Аз също се боря от известно време да намеря решение на "PHP Warning: oci_new_connect(): OCIEnvNlsCreate() failed. There is something wrong with your system - please check that DYLD_LIBRARY_PATH includes the directory with Oracle Instant Client libraries"
грешка в Mac OS X. Най-накрая след дълго проучване намерих решение, което трайно коригира тази грешка, и пожелах да го споделя тук, за да помогна на други.
Като малко предистория, използвам предоставената от Apple инсталация на PHP на OS X 10.8.4 (PHP 5.3.15 с Suhosin-Patch) и използвах хранилището PECL, за да инсталирам разширението OCI8, след като изтеглих Oracle Instant Client изтегляния от Oracle.com.
Тествах също всички решения за тази грешка, които успях да намеря онлайн, включително задаване на DYLD_LIBRARY_PATH
, ORACLE_HOME
и LD_LIBRARY_PATH
променливи на системната среда в моя ~/.bash_profile
и ~/.bashrc
файлове; опитвайки се да конфигурирате променливите на средата чрез mod_env
на Apache модул и SetEnv
в httpd.conf
; задаване на променливите на средата чрез putenv("DYLD_LIBRARY_PATH=/...")
в PHP код; както и други предложения, но всички не успяха да отстранят грешката.
Единственото работещо решение, което намерих в миналото, което използвах при предишната си инсталация на OS X 10.7.8, включваше копиране на съдържанието на библиотеките Oracle Instant Client във винаги търсените, но скрити системни папки:/usr/include
, /usr/bin
и /usr/lib
. Въпреки това усетих, че това решение не е идеално и потенциално би затруднило поддържането и надграждането на библиотеките в дългосрочен план и почувствах, че някъде трябва да съществува устойчиво решение на този проблем.
Накрая след много допълнителни проучвания попаднах на публикация във форумите на OpenSUSE, която подробно описва как група потребители там е решила същата грешка в OCI под Apache/PHP на OpenSUSE. Публикацията във форума също разшири коментарите, които бях виждал в други публикации във форума, които говореха за съществуването на няколко типа „променлива на средата“ в типична настройка на Apache/PHP:
- Има променливи на средата на Apache, които обикновено се конфигурират чрез
mod_env
- те се появяват вApache Environment
раздел наphp_info()
страница. - Има PHP променливи на средата, обикновено задавани чрез
php.ini
илиputenv()
, и станете достъпни във вашите скриптове чрезgetenv()
и подобни методи. - Накрая, това, което наричам тук „специфични за процеса променливи на средата“ – това са променливи на средата, които трябва да бъдат конфигурирани преди стартирането на процеса на Apache и като част от самия процес на стартиране на Apache. Не е достатъчно да посочите тези променливи на средата в своя
~/.bash_profile
например. Тези специални променливи на средата се наследяват от процеса на Apache, когато се стартира, и от решаващо значение , от всички негови дъщерни процеси, включително други раждания на процеса Apache и от самия PHP - и точно тези „специфични за процеса променливи на средата“ трябва да конфигурираме, за да разрешим трайно и устойчиво нашия проблем с библиотеката OCI8. Когато са конфигурирани правилно, тези променливи на средата ще се появят вEnvironment Variables
раздел наphp_info()
страница.
Уликата, която ме доведе до решението на Mac OS X, беше от публикацията във форума на OpenSUSE, която включваше коментар от член на форума, key_nap , който забеляза, че когато процесът Apache е стартиран на OpenSUSE, се зарежда и специален конфигурационен файл. Този файл, /usr/share/apache2/load_configuration
се оказа bash скрипт и им хрумна, че могат да включат съответния export DYLD_LIBRARY_PATH=...
изрази в този bash скрипт и че чрез конфигуриране на променливите на средата там, те ще бъдат наследени от процеса Apache и неговите деца при стартиране.
Това ме накара да се чудя къде в Mac OS X бихме могли да конфигурираме правилно същите тези „специфични за процеса променливи на средата“. Като launchd
се използва почти изключително в OS X за обработка на зареждането на системни процеси, чудех се дали ще можем да конфигурираме необходимите променливи на средата в launchd
на Apache конфигурационен файл? В OS X 10.8 трябва да намерите launchd
на Apache конфигурация .plist
файл в /System/Library/LaunchDaemons/org.apache.httpd.plist
. Когато отворих файла в моята система, веднага забелязах раздел за определяне на променливи на средата!
Следователно нашето решение (тествано за работа на Mac OS X 10.8.4) беше да редактираме org.apache.httpd.plist
файл, както е показано по-долу (забележете включването на ORACLE_HOME
, DYLD_LIBRARY_PATH
и LD_LIBRARY_PATH
към секцията EnvironmentVariables на файла) и след това да рестартирате Apache, като изпълните sudo apachectl restart
от терминала.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<true/>
<key>Label</key>
<string>org.apache.httpd</string>
<key>EnvironmentVariables</key>
<dict>
<key>XPC_SERVICES_UNAVAILABLE</key>
<string>1</string>
<key>ORACLE_HOME</key>
<string>/Users/workstation/Oracle</string>
<key>DYLD_LIBRARY_PATH</key>
<string>/Users/workstation/Oracle/lib</string>
<key>LD_LIBRARY_PATH</key>
<string>/Users/workstation/Oracle/lib</string>
</dict>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/httpd-wrapper</string>
<string>-D</string>
<string>FOREGROUND</string>
</array>
<key>OnDemand</key>
<false/>
<key>SHAuthorizationRight</key>
<string>system.preferences</string>
</dict>
</plist>
Чрез добавяне на тези дефиниции на „специфична за процеса променлива на средата“ към Apache launchd
конфигурационен файл, ние гарантираме, че тези променливи на средата са правилно наследени от Apache и всички негови дъщерни процеси, които включват PHP и всички модули, които PHP зарежда, като OCI8! Очевидно трябва да замените пътя /Users/workstation/Oracle/...
показано в примера по-горе с правилните пътища до вашата собствена инсталация на клиентските библиотеки на Oracle – използвайте същите стойности, както бихте направили, когато задавате тези променливи на средата във вашия ~/.bash_profile
.
Също така се уверете, че имате правилната версия на Oracle Instant Client Libraries за вашата система - т.е. 32-битови или 64-битови варианти в зависимост от това коя версия на OS X използвате и дали Apache и PHP се изпълняват или не 32- или 64-битов режим. На OS X 10.8 и по-нова версия Apache/PHP трябва да работи като 64-битови процеси. Ако не сте сигурни, можете да направите това, което направих на предишния си Mac, и да комбинирате 32- и 64-битовите версии на двоичните файлове на библиотеката Oracle Instant Client в единични мултиархитектурни fat-binary с помощта на lipo
инструмент от XCode, който ще създаде двоични файлове, които се зареждат на всяка платформа.
И накрая, подробно описаното по-горе решение за конфигуриране на променливи на средата в launchd
на Apache конфигурационен файл също трябва да работи за разрешаване на подобни грешки в други PHP модули, изпълнявани чрез Apache, които разчитат на променливи на средата, за да намерят своите свързани библиотеки. Ако изпълнявате PHP от командния ред, трябва да можете да посочите всички променливи на средата, от които се нуждаете във вашия ~/.bash_profile
и/или ~/.bashrc
файлове.