Ook ik worstel al een tijdje om een oplossing te vinden voor de "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"
fout op Mac OS X. Eindelijk, na veel onderzoek, vond ik een oplossing die deze fout duurzaam verhelpt, en wilde deze hier delen om anderen te helpen.
Als een beetje achtergrond gebruik ik de door Apple geleverde installatie van PHP op OS X 10.8.4 (PHP 5.3.15 met Suhosin-Patch), en gebruikte ik de PECL-repository om de OCI8-extensie te installeren nadat ik de Oracle Instant Client had gedownload downloads van Oracle.com.
Ik heb ook alle oplossingen voor deze fout getest die ik online heb kunnen vinden, inclusief het instellen van de DYLD_LIBRARY_PATH
, ORACLE_HOME
, en LD_LIBRARY_PATH
systeemomgevingsvariabelen in mijn ~/.bash_profile
en ~/.bashrc
bestanden; proberen de omgevingsvariabelen te configureren via Apache's mod_env
module en SetEnv
in httpd.conf
; de omgevingsvariabelen instellen via putenv("DYLD_LIBRARY_PATH=/...")
in PHP-code; evenals andere suggesties, maar het is allemaal niet gelukt om de fout op te lossen.
De enige werkende oplossing die ik in het verleden had gevonden, die ik gebruikte op mijn vorige OS X 10.7.8-installatie, was het kopiëren van de inhoud van de Oracle Instant Client-bibliotheken naar de altijd gezochte, maar verborgen systeemmappen:/usr/include
, /usr/bin
, en /usr/lib
. Ik vond echter dat deze oplossing niet ideaal was en het op lange termijn mogelijk moeilijk zou maken om de bibliotheken te onderhouden en te upgraden, en ik vond dat er ergens een duurzame oplossing voor dit probleem moest bestaan.
Eindelijk, na veel aanvullend onderzoek, stuitte ik op een bericht op de OpenSUSE-forums waarin werd beschreven hoe een groep gebruikers daar dezelfde OCI-fout had opgelost onder Apache/PHP op OpenSUSE. Het forumbericht ging ook dieper in op opmerkingen die ik had gezien in andere forumberichten waarin werd gesproken over meerdere soorten 'omgevingsvariabele' in een typische Apache/PHP-configuratie:
- Er zijn Apache-omgevingsvariabelen, die meestal worden geconfigureerd via
mod_env
- deze verschijnen in deApache Environment
sectie van dephp_info()
pagina. - Er zijn PHP-omgevingsvariabelen, meestal ingesteld via
php.ini
ofputenv()
, en wordt toegankelijk in uw scripts viagetenv()
en vergelijkbare methoden. - Ten slotte is er wat ik hier verwijs als 'processpecifieke omgevingsvariabelen' - dit zijn omgevingsvariabelen die moeten worden geconfigureerd voordat het Apache-proces wordt gestart, en als onderdeel van het Apache-startproces zelf. Het is niet voldoende om deze omgevingsvariabelen te specificeren in iemands
~/.bash_profile
bijvoorbeeld. Deze speciale omgevingsvariabelen worden overgenomen door het Apache-proces wanneer het opstart, en cruciaal , door al zijn onderliggende processen, inclusief andere spawns van het Apache-proces en door PHP zelf - en het zijn deze zeer 'processpecifieke omgevingsvariabelen' die we moeten configureren om ons probleem met de OCI8-bibliotheek permanent en duurzaam op te lossen. Indien correct geconfigureerd, zullen deze omgevingsvariabelen verschijnen in deEnvironment Variables
sectie van dephp_info()
pagina.
De aanwijzing die me naar de oplossing op Mac OS X leidde, kwam uit de post op het OpenSUSE-forum met een opmerking van een forumlid, key_nap , die opmerkte dat toen het Apache-proces op OpenSUSE werd gestart, er ook een speciaal configuratiebestand werd geladen. Dit bestand, /usr/share/apache2/load_configuration
bleek een bash-script te zijn, en het kwam bij hen op dat ze de relevante export DYLD_LIBRARY_PATH=...
konden opnemen statements binnen dit bash-script, en dat door de omgevingsvariabelen daar te configureren, ze bij het opstarten zouden worden overgenomen door het Apache-proces en zijn onderliggende.
Dit bracht me tot de vraag waar we in Mac OS X in staat zouden zijn om dezelfde 'processpecifieke omgevingsvariabelen' correct te configureren. Als launchd
bijna uitsluitend op OS X wordt gebruikt om het laden van systeemprocessen af te handelen, ik vroeg me af of we de nodige omgevingsvariabelen zouden kunnen configureren in Apache's launchd
configuratiebestand? Op OS X 10.8 zou je Apache's launchd
. moeten vinden configuratie .plist
bestand op /System/Library/LaunchDaemons/org.apache.httpd.plist
. Toen ik het bestand op mijn systeem opende, zag ik meteen een sectie voor het specificeren van Omgevingsvariabelen!
Onze oplossing (getest om te werken op Mac OS X 10.8.4) was daarom het bewerken van de org.apache.httpd.plist
bestand zoals hieronder getoond (let op de opname van ORACLE_HOME
, DYLD_LIBRARY_PATH
, en LD_LIBRARY_PATH
naar de sectie EnvironmentVariables van het bestand), en om vervolgens Apache opnieuw te starten door sudo apachectl restart
uit te voeren. vanaf de terminal.
<?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>
Door deze 'processpecifieke omgevingsvariabele'-definities toe te voegen aan de Apache launchd
configuratiebestand, zorgen we ervoor dat deze omgevingsvariabelen correct worden overgenomen door Apache en al zijn onderliggende processen, waaronder PHP en alle modules die PHP laadt zoals OCI8! Je moet uiteraard het pad /Users/workstation/Oracle/...
. vervangen weergegeven in het bovenstaande voorbeeld met de juiste paden naar uw eigen installatie van de Oracle Client Libraries - gebruik dezelfde waarden als wanneer u deze omgevingsvariabelen opgeeft in uw ~/.bash_profile
.
Zorg er ook voor dat u de juiste versie van de Oracle Instant Client Libraries voor uw systeem hebt geïnstalleerd - d.w.z. de 32-bits of 64-bits varianten, afhankelijk van de versie van OS X die u gebruikt en of Apache en PHP al dan niet worden uitgevoerd 32- of 64-bits modus. Op OS X 10.8 en hoger zou Apache/PHP moeten draaien als 64-bits processen. Als je het niet zeker weet, kun je doen wat ik deed op mijn vorige Mac en de 32- en 64-bits versies van de Oracle Instant Client-bibliotheekbinaire bestanden combineren tot enkele multi-architectuur fat-binaries met behulp van de lipo
tool van XCode die binaire bestanden maakt die op beide platforms worden geladen.
Ten slotte, de hierboven beschreven oplossing om omgevingsvariabelen te configureren in Apache's launchd
configuratiebestand zou ook moeten werken om soortgelijke fouten op te lossen in andere PHP-modules die via Apache worden uitgevoerd en die afhankelijk zijn van omgevingsvariabelen om hun gekoppelde bibliotheken te vinden. Als je PHP vanaf de opdrachtregel uitvoert, zou je alle omgevingsvariabelen moeten kunnen specificeren die je nodig hebt in je ~/.bash_profile
en/of ~/.bashrc
bestanden.