Jag har också kämpat ett tag för att hitta en lösning på "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"
fel på Mac OS X. Efter mycket forskning hittade jag en lösning som på ett hållbart sätt fixar detta fel och ville dela den här för att hjälpa andra.
Som en liten bakgrund använder jag den Apple-levererade installationen av PHP på OS X 10.8.4 (PHP 5.3.15 med Suhosin-Patch), och använde PECL-förvaret för att installera OCI8-tillägget efter att jag hade laddat ner Oracle Instant Client nedladdningar från Oracle.com.
Jag har också testat alla lösningar för detta fel som jag har kunnat hitta online, inklusive inställning av DYLD_LIBRARY_PATH
, ORACLE_HOME
och LD_LIBRARY_PATH
systemmiljövariabler i min ~/.bash_profile
och ~/.bashrc
filer; försöker konfigurera miljövariablerna via Apaches mod_env
modul och SetEnv
i httpd.conf
; ställa in miljövariablerna via putenv("DYLD_LIBRARY_PATH=/...")
i PHP-kod; samt andra förslag, men alla misslyckades med att lösa felet.
Den enda fungerande lösning jag hade hittat tidigare, som jag använde på min tidigare OS X 10.7.8-installation, var att kopiera innehållet i Oracle Instant Client-biblioteken till de alltid sökta, men ändå dolda systemmapparna:/usr/include
, /usr/bin
och /usr/lib
. Jag kände dock att den här lösningen inte var idealisk och skulle potentiellt göra det svårt att underhålla och uppgradera biblioteken på lång sikt, och jag kände att en hållbar lösning på detta problem måste finnas någonstans.
Slutligen, efter mycket ytterligare forskning, snubblade jag över ett inlägg på OpenSUSE-forumen som beskrev hur en grupp användare där hade löst samma OCI-fel under Apache/PHP på OpenSUSE. Foruminlägget utökade också kommentarer jag hade sett i andra foruminlägg som talade om att det finns flera typer av 'miljövariabler' i en typisk Apache/PHP-inställning:
- Det finns Apache-miljövariabler, som vanligtvis konfigureras via
mod_env
- dessa visas iApache Environment
avsnittet iphp_info()
sida. - Det finns PHP-miljövariabler, vanligtvis inställda via
php.ini
ellerputenv()
, och bli tillgänglig i dina skript viagetenv()
och liknande metoder. - Slutligen, det som jag refererar till här som 'processspecifika miljövariabler' - dessa är miljövariabler som måste konfigureras innan Apache-processen startas och som en del av själva Apache-startprocessen. Det räcker inte att specificera dessa miljövariabler i ens
~/.bash_profile
till exempel. Dessa speciella miljövariabler ärvs av Apache-processen när den startar, och avgörande , av alla dess underordnade processer inklusive andra spawn av Apache-processen och av PHP självt - och det är dessa mycket "processspecifika miljövariabler" som vi måste konfigurera för att permanent och hållbart lösa vårt problem med OCI8-biblioteket. När de är korrekt konfigurerade kommer dessa miljövariabler att visas iEnvironment Variables
avsnittet iphp_info()
sida.
Ledtråden som ledde mig till lösningen på Mac OS X kom från inlägget på OpenSUSE-forumet som innehöll en kommentar från forummedlemmen, key_nap , som märkte att när Apache-processen lanserades på OpenSUSE, laddades en speciell konfigurationsfil också. Den här filen, /usr/share/apache2/load_configuration
visade sig vara ett bash-skript, och det kom upp för dem att de kunde inkludera den relevanta export DYLD_LIBRARY_PATH=...
uttalanden i detta bash-skript, och att genom att konfigurera miljövariablerna där, att de skulle ärvas av Apache-processen och dess barn vid lanseringen.
Detta fick mig att undra var på Mac OS X vi skulle kunna korrekt konfigurera samma "processspecifika miljövariabler". Som launchd
används nästan uteslutande på OS X för att hantera laddningen av systemprocesser, jag undrade om vi skulle kunna konfigurera nödvändiga miljövariabler i Apaches launchd
konfigurationsfil? På OS X 10.8 bör du hitta Apaches launchd
konfiguration .plist
fil på /System/Library/LaunchDaemons/org.apache.httpd.plist
. När jag öppnade filen på mitt system märkte jag omedelbart ett avsnitt för att specificera miljövariabler!
Vår lösning (testad för att fungera på Mac OS X 10.8.4) var därför att redigera org.apache.httpd.plist
fil som visas nedan (märk inkluderingen av ORACLE_HOME
, DYLD_LIBRARY_PATH
och LD_LIBRARY_PATH
till avsnittet EnvironmentVariables i filen), och för att sedan starta om Apache genom att köra sudo apachectl restart
från terminalen.
<?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>
Genom att lägga till dessa "processspecifika miljövariabler" definitioner till Apache launchd
konfigurationsfil, säkerställer vi att dessa miljövariabler ärvs korrekt av Apache och alla dess underordnade processer, som inkluderar PHP och alla moduler som PHP laddar som OCI8! Du bör självklart ersätta sökvägen /Users/workstation/Oracle/...
visas i exemplet ovan med de korrekta sökvägarna till din egen installation av Oracle Client Libraries – använd samma värden som när du anger dessa miljövariabler i din ~/.bash_profile
.
Se också till att du har rätt version av Oracle Instant Client Libraries installerad för ditt system - det vill säga antingen 32-bitars eller 64-bitars varianter beroende på vilken version av OS X du kör och om Apache och PHP körs i eller inte 32- eller 64-bitarsläge. På OS X 10.8 och senare bör Apache/PHP köras som 64-bitarsprocesser. Om du är osäker kan du göra som jag gjorde på min tidigare Mac och kombinera 32- och 64-bitarsversionerna av Oracle Instant Client-bibliotekets binärfiler till enstaka fettbinärfiler med flera arkitekturer med lipo
verktyg från XCode som skapar binärfiler som laddas på båda plattformarna.
Slutligen, lösningen som beskrivs ovan för att konfigurera miljövariabler i Apaches launchd
konfigurationsfilen bör också fungera för att lösa liknande fel i andra PHP-moduler som körs via Apache som förlitar sig på miljövariabler för att hitta sina länkade bibliotek. Om du kör PHP från kommandoraden bör du kunna specificera alla miljövariabler du behöver i din ~/.bash_profile
och/eller ~/.bashrc
filer.