Auch ich habe einige Zeit damit gekämpft, eine Lösung für die "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"
Fehler unter Mac OS X. Nach langer Recherche habe ich endlich eine Lösung gefunden, die diesen Fehler nachhaltig behebt, und möchte sie hier teilen, um anderen zu helfen.
Als kleinen Hintergrund verwende ich die von Apple bereitgestellte Installation von PHP unter OS X 10.8.4 (PHP 5.3.15 mit Suhosin-Patch) und habe das PECL-Repository verwendet, um die OCI8-Erweiterung zu installieren, nachdem ich den Oracle Instant Client heruntergeladen hatte Downloads von Oracle.com.
Ich habe auch alle Lösungen für diesen Fehler getestet, die ich online finden konnte, einschließlich der Einstellung des DYLD_LIBRARY_PATH
, ORACLE_HOME
und LD_LIBRARY_PATH
Systemumgebungsvariablen in meinem ~/.bash_profile
und ~/.bashrc
Dateien; versuchen, die Umgebungsvariablen über Apaches mod_env
zu konfigurieren Modul und SetEnv
in httpd.conf
; Setzen der Umgebungsvariablen über putenv("DYLD_LIBRARY_PATH=/...")
im PHP-Code; sowie andere Vorschläge, aber alle konnten den Fehler nicht beheben.
Die einzige funktionierende Lösung, die ich in der Vergangenheit gefunden hatte und die ich bei meiner vorherigen OS X 10.7.8-Installation verwendete, bestand darin, den Inhalt der Oracle Instant Client-Bibliotheken in die immer durchsuchten, aber versteckten Systemordner zu kopieren:/usr/include
, /usr/bin
, und /usr/lib
. Ich war jedoch der Meinung, dass diese Lösung nicht ideal war und es möglicherweise langfristig schwierig machen würde, die Bibliotheken zu warten und zu aktualisieren, und ich war der Meinung, dass es irgendwo eine nachhaltige Lösung für dieses Problem geben musste.
Nach vielen zusätzlichen Recherchen stolperte ich schließlich über einen Beitrag in den OpenSUSE-Foren, in dem ausführlich beschrieben wurde, wie eine Gruppe von Benutzern dort denselben OCI-Fehler unter Apache/PHP auf OpenSUSE gelöst hatte. Der Forumsbeitrag erweiterte auch Kommentare, die ich in anderen Forenbeiträgen gesehen hatte, die davon sprachen, dass es mehrere Arten von „Umgebungsvariablen“ in einem typischen Apache/PHP-Setup gibt:
- Es gibt Apache-Umgebungsvariablen, die normalerweise über
mod_env
konfiguriert werden - diese erscheinen in derApache Environment
Abschnitt vonphp_info()
Seite. - Es gibt PHP-Umgebungsvariablen, die normalerweise über
php.ini
gesetzt werden oderputenv()
, und werden in Ihren Skripten übergetenv()
zugänglich und ähnliche Methoden. - Schließlich das, was ich hier als „prozessspezifische Umgebungsvariablen“ bezeichne – das sind Umgebungsvariablen, die konfiguriert werden müssen, bevor der Apache-Prozess gestartet wird, und als Teil des Apache-Startprozesses selbst. Es reicht nicht aus, diese Umgebungsvariablen in seinem eigenen
~/.bash_profile
anzugeben zum Beispiel. Diese speziellen Umgebungsvariablen werden vom Apache-Prozess geerbt, wenn er gestartet wird, und entscheidend , von all seinen untergeordneten Prozessen einschließlich anderer Spawns des Apache-Prozesses und von PHP selbst - und es sind genau diese "prozessspezifischen Umgebungsvariablen", auf die wir konfigurieren müssen, um unser Problem mit der OCI8-Bibliothek dauerhaft und nachhaltig zu lösen. Bei richtiger Konfiguration erscheinen diese Umgebungsvariablen in denEnvironment Variables
Abschnitt vonphp_info()
Seite.
Der Hinweis, der mich zu der Lösung unter Mac OS X führte, war der Beitrag im OpenSUSE-Forum, der einen Kommentar des Forumsmitglieds key_nap enthielt , der bemerkte, dass beim Start des Apache-Prozesses auf OpenSUSE auch eine spezielle Konfigurationsdatei geladen wurde. Diese Datei, /usr/share/apache2/load_configuration
stellte sich als Bash-Skript heraus, und ihnen kam der Gedanke, dass sie den relevanten export DYLD_LIBRARY_PATH=...
einfügen könnten Anweisungen innerhalb dieses Bash-Skripts, und dass durch Konfigurieren der Umgebungsvariablen dort, dass sie vom Apache-Prozess und seinen untergeordneten Elementen beim Start geerbt würden.
Dies führte mich zu der Frage, wo wir unter Mac OS X in der Lage wären, dieselben "prozessspezifischen Umgebungsvariablen" korrekt zu konfigurieren. Als launchd
fast ausschließlich unter OS X verwendet wird, um das Laden von Systemprozessen zu handhaben, fragte ich mich, ob wir in der Lage wären, die notwendigen Umgebungsvariablen in Apaches launchd
zu konfigurieren Konfigurationsdatei? Unter OS X 10.8 sollten Sie Apaches launchd
finden Konfiguration .plist
Datei unter /System/Library/LaunchDaemons/org.apache.httpd.plist
. Als ich die Datei auf meinem System öffnete, bemerkte ich sofort einen Abschnitt zum Angeben von Umgebungsvariablen!
Unsere Lösung (auf Mac OS X 10.8.4 getestet) bestand daher darin, die org.apache.httpd.plist
zu bearbeiten Datei wie unten gezeigt (beachten Sie die Aufnahme von ORACLE_HOME
, DYLD_LIBRARY_PATH
und LD_LIBRARY_PATH
in den EnvironmentVariables-Abschnitt der Datei) und dann Apache neu starten, indem Sie sudo apachectl restart
ausführen vom 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>
Durch Hinzufügen dieser Definitionen der „prozessspezifischen Umgebungsvariablen“ zum Apache launchd
Konfigurationsdatei stellen wir sicher, dass diese Umgebungsvariablen korrekt von Apache und allen seinen untergeordneten Prozessen geerbt werden, die PHP und alle von PHP geladenen Module wie OCI8 enthalten! Sie sollten natürlich den Pfad /Users/workstation/Oracle/...
ersetzen wie im obigen Beispiel mit den korrekten Pfaden zu Ihrer eigenen Installation der Oracle-Client-Bibliotheken gezeigt – verwenden Sie die gleichen Werte wie bei der Angabe dieser Umgebungsvariablen in Ihrem ~/.bash_profile
.
Stellen Sie außerdem sicher, dass Sie die richtige Version der Oracle Instant Client Libraries für Ihr System installiert haben – d. h. entweder die 32-Bit- oder die 64-Bit-Variante, je nachdem, welche Version von OS X Sie ausführen und ob Apache und PHP ausgeführt werden oder nicht 32- oder 64-Bit-Modus. Unter OS X 10.8 und höher sollte Apache/PHP als 64-Bit-Prozess ausgeführt werden. Wenn Sie sich nicht sicher sind, können Sie das tun, was ich auf meinem vorherigen Mac getan habe, und die 32- und 64-Bit-Versionen der Binärdateien der Oracle Instant Client-Bibliothek mithilfe von lipo
zu einzelnen Multi-Architektur-Fat-Binärdateien kombinieren Tool von XCode, das Binärdateien erstellt, die auf beiden Plattformen geladen werden.
Zuletzt die oben beschriebene Lösung zum Konfigurieren von Umgebungsvariablen in Apaches launchd
Konfigurationsdatei sollte auch funktionieren, um ähnliche Fehler in anderen PHP-Modulen zu beheben, die über Apache ausgeführt werden und auf Umgebungsvariablen angewiesen sind, um ihre verknüpften Bibliotheken zu finden. Wenn Sie PHP über die Befehlszeile ausführen, sollten Sie in der Lage sein, alle benötigten Umgebungsvariablen in Ihrem ~/.bash_profile
anzugeben und/oder ~/.bashrc
Dateien.