Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
552 views
in Technique[技术] by (71.8m points)

php - Oracle instantclient DYLD_LIBRARY_PATH error

I am using Xamppp for macos on OSX 10.9 with Php 5.4.19 I've installed oracle instantclient and i can see oci8 is enabled in phpinfo (below):

OCI8 Support enabled Version 1.4.9 Revision $Id: 44bfa713983a99b3e59477f6532e5fb51b6dee94 $ Active Persistent Connections 0 Active Connections 0

I can see DYLD_LIBRARY_PATH is set in my phpinfo also.

DYLD_LIBRARY_PATH /usr/local/instantclient/11.2.0.3

But when i try to connect with php i got the same error for two days now :(

Warning: oci_connect(): OCIEnvNlsCreate() failed. There is something wrong with your system - please check that DYLD_LIBRARY_PATH includes the directory with Oracle Instant Client libraries in info.php on line 6 Warning: oci_connect(): Error while trying to retrieve text for error ORA-01804 in info.php on line 6

Any help would be great. Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I too have been struggling for some time to find a solution to the "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" error on Mac OS X. Finally after much research, I found a solution that sustainably fixes this error, and wished to share it here to help others.

As a little background, I am using the Apple-provided installation of PHP on OS X 10.8.4 (PHP 5.3.15 with Suhosin-Patch), and used the PECL repository to install the OCI8 extension after I had downloaded the Oracle Instant Client downloads from Oracle.com.

I have also tested all the solutions for this error that I have been able to find online, including setting the DYLD_LIBRARY_PATH, ORACLE_HOME, and LD_LIBRARY_PATH system environment variables in my ~/.bash_profile and ~/.bashrc files; attempting to configure the environment variables via Apache's mod_env module and SetEnv in httpd.conf; setting the environment variables via putenv("DYLD_LIBRARY_PATH=/...") in PHP code; as well as other suggestions, but all failed to solve the error.

The only working solution I had found in the past, which I used on my previous OS X 10.7.8 installation involved copying the contents of the Oracle Instant Client libraries to the always-searched, yet hidden system folders: /usr/include, /usr/bin, and /usr/lib. However, I felt that this solution wasn't ideal and would potentially make it difficult to maintain and upgrade the libraries in the long-term, and I felt that a sustainable solution to this problem had to exist somewhere.

Finally after much additional research, I stumbled upon a post on the OpenSUSE forums which detailed how a group of users there had solved the same OCI error under Apache/PHP on OpenSUSE. The forum post also expanded on comments I had seen in other forum posts that talked about there being multiple types of 'environment variable' in a typical Apache/PHP setup:

  • There are Apache Environment Variables, which are usually configured via mod_env - these appear in the Apache Environment section of the php_info() page.
  • There are PHP environment variables, usually set via php.ini or putenv(), and become accessible in your scripts via getenv() and similar methods.
  • Finally, there what I am referring to here as 'process specific environment variables' - these are environment variables that must be configured before the Apache process is launched, and as part of the Apache launch process itself. It does not suffice to specify these environment variables in one's ~/.bash_profile for example. These special environment variables are inherited by the Apache process when it launches, and crucially, by all its child processes including other spawns of the Apache process and by PHP itself - and it is these very 'process specific environment variables' that we need to configure to in order to permanently and sustainably solve our problem with the OCI8 library. When configured correctly, these environment variables will appear in the Environment Variables section of the php_info() page.

The clue that led me to the solution on Mac OS X was from the post on the OpenSUSE forum that included a comment by forum member, key_nap, who noticed that when the Apache process was launched on OpenSUSE, a special configuration file was being loaded also. This file, /usr/share/apache2/load_configuration turned out to be a bash script, and it occurred to them that they could include the relevant export DYLD_LIBRARY_PATH=... statements within this bash script, and that by configuring the environment variables there, that they would be inherited by the Apache process and its children upon launch.

This lead me to wondering where on Mac OS X we would be able to correctly configure these same 'process specific environment variables'. As launchd is used almost exclusively on OS X to handle the loading of system processes, I wondered if we would be able to configure the necessary environment variables in Apache's launchd configuration file? On OS X 10.8, you should find Apache's launchd configuration .plist file at /System/Library/LaunchDaemons/org.apache.httpd.plist. When I opened the file on my system, I immediately noticed a section for specifying Environment Variables!

Our solution therefore (tested to work on Mac OS X 10.8.4), was to edit the org.apache.httpd.plist file as show below (notice the inclusion of ORACLE_HOME, DYLD_LIBRARY_PATH, and LD_LIBRARY_PATH to the EnvironmentVariables section of the file), and to then restart Apache by running sudo apachectl restart from the 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>

By adding these 'process specific environment variable' definitions to the Apache launchd configuration file, we ensure these environment variables are correctly inherited by Apache and all of its child processes, which include PHP and any modules PHP loads such as OCI8! You should obviously replace the path /Users/workstation/Oracle/... shown in the example above with the correct paths to your own installation of the Oracle Client Libraries – use the same values as you would when specifying these environment variables in your ~/.bash_profile.

Also ensure that you have the correct version of the Oracle Instant Client Libraries installed for your system - i.e. either the 32-bit or 64-bit variants depending on which version of OS X you are running and whether or not Apache and PHP are running in 32- or 64-bit mode. On OS X 10.8 and above, Apache/PHP should be running as 64-bit processes. If you are unsure, you can do what I did on my previous Mac and combine the 32- and 64-bit versions of the Oracle Instant Client library binaries into single multi-architecture fat-binaries using the lipo tool from XCode which will create binaries that load on either platform.

Lastly, the solution detailed above to configure environment variables in Apache's launchd configuration file should also work to solve similar errors in other PHP modules run via Apache that rely on environment variables to find their linked libraries. If running PHP from the command line you should be able to specify all the environment variables you need in your ~/.bash_profile and/or ~/.bashrc files.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...