Tôi cũng đã vật lộn trong một thời gian để tìm giải pháp cho "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"
lỗi trên Mac OS X. Cuối cùng sau nhiều nghiên cứu, tôi đã tìm ra giải pháp có thể khắc phục lỗi này một cách bền vững và mong muốn chia sẻ nó ở đây để giúp những người khác.
Về thông tin cơ bản, tôi đang sử dụng bản cài đặt PHP do Apple cung cấp trên OS X 10.8.4 (PHP 5.3.15 với Suhosin-Patch) và sử dụng kho lưu trữ PECL để cài đặt tiện ích mở rộng OCI8 sau khi tôi đã tải xuống Oracle Instant Client tải xuống từ Oracle.com.
Tôi cũng đã thử nghiệm tất cả các giải pháp cho lỗi này mà tôi có thể tìm thấy trực tuyến, bao gồm cả việc đặt DYLD_LIBRARY_PATH
, ORACLE_HOME
và LD_LIBRARY_PATH
biến môi trường hệ thống trong ~/.bash_profile
của tôi và ~/.bashrc
các tập tin; cố gắng định cấu hình các biến môi trường thông qua mod_env
của Apache mô-đun và SetEnv
trong httpd.conf
; thiết lập các biến môi trường thông qua putenv("DYLD_LIBRARY_PATH=/...")
trong mã PHP; cũng như các đề xuất khác, nhưng tất cả đều không giải quyết được lỗi.
Giải pháp hoạt động duy nhất mà tôi đã tìm thấy trước đây, mà tôi đã sử dụng trên bản cài đặt OS X 10.7.8 trước đó của mình liên quan đến việc sao chép nội dung của các thư viện Oracle Instant Client vào các thư mục hệ thống luôn được tìm kiếm nhưng ẩn:/usr/include
, /usr/bin
và /usr/lib
. Tuy nhiên, tôi cảm thấy rằng giải pháp này không lý tưởng và có khả năng gây khó khăn cho việc duy trì và nâng cấp thư viện về lâu dài và tôi cảm thấy rằng một giải pháp bền vững cho vấn đề này phải tồn tại ở đâu đó.
Cuối cùng sau nhiều nghiên cứu bổ sung, tôi tình cờ thấy một bài đăng trên diễn đàn OpenSUSE trình bày chi tiết cách một nhóm người dùng ở đó đã giải quyết cùng một lỗi OCI trong Apache / PHP trên OpenSUSE. Bài đăng trên diễn đàn cũng mở rộng về các nhận xét mà tôi đã thấy trong các bài đăng khác trên diễn đàn nói về việc có nhiều loại 'biến môi trường' trong thiết lập Apache / PHP điển hình:
- Có các Biến Môi trường Apache, thường được định cấu hình qua
mod_env
- những thứ này xuất hiện trongApache Environment
phần củaphp_info()
trang. - Có các biến môi trường PHP, thường được đặt qua
php.ini
hoặcputenv()
và có thể truy cập được trong các tập lệnh của bạn quagetenv()
và các phương pháp tương tự. - Cuối cùng, những gì tôi đang đề cập ở đây là 'các biến môi trường cụ thể của quy trình' - đây là các biến môi trường phải được định cấu hình trước khi quy trình Apache được khởi chạy và là một phần của chính quy trình khởi chạy Apache. Không đủ để chỉ định các biến môi trường này trong
~/.bash_profile
của một người Ví dụ. Các biến môi trường đặc biệt này được kế thừa bởi quy trình Apache khi nó khởi chạy, và quan trọng là , bởi tất cả các quy trình con của nó bao gồm các quy trình sinh sản khác của quy trình Apache và bởi chính PHP - và chính 'các biến môi trường cụ thể của quy trình' này mà chúng ta cần phải định cấu hình để giải quyết vấn đề của chúng ta với thư viện OCI8 một cách lâu dài và bền vững. Khi được định cấu hình đúng, các biến môi trường này sẽ xuất hiện trongEnvironment Variables
phần củaphp_info()
trang.
Manh mối dẫn tôi đến giải pháp trên Mac OS X là từ bài đăng trên diễn đàn OpenSUSE có nhận xét của thành viên diễn đàn, key_nap , người đã nhận thấy rằng khi quy trình Apache được khởi chạy trên OpenSUSE, một tệp cấu hình đặc biệt cũng đang được tải. Tệp này, /usr/share/apache2/load_configuration
hóa ra là một tập lệnh bash và họ nhận ra rằng chúng có thể bao gồm export DYLD_LIBRARY_PATH=...
có liên quan các câu lệnh bên trong tập lệnh bash này và bằng cách định cấu hình các biến môi trường ở đó, chúng sẽ được kế thừa bởi quá trình Apache và các phần tử con của nó khi khởi chạy.
Điều này khiến tôi tự hỏi nơi nào trên Mac OS X, chúng ta có thể định cấu hình chính xác các 'biến môi trường cụ thể của quá trình' này. Dưới dạng launchd
hầu như chỉ được sử dụng trên OS X để xử lý việc tải các quy trình hệ thống, tôi tự hỏi liệu chúng tôi có thể định cấu hình các biến môi trường cần thiết trong launchd
của Apache không tập tin cấu hình? Trên OS X 10.8, bạn sẽ tìm thấy launchd
của Apache cấu hình .plist
gửi tại /System/Library/LaunchDaemons/org.apache.httpd.plist
. Khi tôi mở tệp trên hệ thống của mình, tôi ngay lập tức nhận thấy một phần để chỉ định Biến môi trường!
Do đó, giải pháp của chúng tôi (được thử nghiệm hoạt động trên Mac OS X 10.8.4) là chỉnh sửa org.apache.httpd.plist
tệp như hình bên dưới (lưu ý bao gồm ORACLE_HOME
, DYLD_LIBRARY_PATH
và LD_LIBRARY_PATH
vào phần EnvironmentVariables của tệp), và sau đó khởi động lại Apache bằng cách chạy sudo apachectl restart
từ nhà ga.
<?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>
Bằng cách thêm các định nghĩa 'biến môi trường cụ thể của quy trình' này vào launchd
của Apache tệp cấu hình, chúng tôi đảm bảo các biến môi trường này được Apache và tất cả các quy trình con của nó kế thừa chính xác, bao gồm PHP và bất kỳ mô-đun nào mà PHP tải như OCI8! Rõ ràng là bạn nên thay thế đường dẫn /Users/workstation/Oracle/...
được hiển thị trong ví dụ ở trên với các đường dẫn chính xác để cài đặt Thư viện máy khách Oracle của riêng bạn - sử dụng các giá trị giống như khi chỉ định các biến môi trường này trong ~/.bash_profile
của bạn .
Đồng thời đảm bảo rằng bạn đã cài đặt đúng phiên bản Thư viện ứng dụng khách tức thì Oracle cho hệ thống của mình - tức là các biến thể 32 bit hoặc 64 bit tùy thuộc vào phiên bản OS X bạn đang chạy và Apache và PHP có đang chạy trong đó hay không Chế độ 32 hoặc 64 bit. Trên OS X 10.8 trở lên, Apache / PHP phải chạy dưới dạng quy trình 64-bit. Nếu bạn không chắc chắn, bạn có thể thực hiện những gì tôi đã làm trên máy Mac trước đó của mình và kết hợp các phiên bản 32 và 64-bit của thư viện Oracle Instant Client thành các tệp nhị phân thư viện đa kiến trúc duy nhất bằng cách sử dụng lipo
công cụ từ XCode sẽ tạo các tệp nhị phân tải trên một trong hai nền tảng.
Cuối cùng, giải pháp chi tiết ở trên để định cấu hình các biến môi trường trong launchd
của Apache tệp cấu hình cũng sẽ hoạt động để giải quyết các lỗi tương tự trong các mô-đun PHP khác chạy qua Apache dựa trên các biến môi trường để tìm các thư viện được liên kết của chúng. Nếu chạy PHP từ dòng lệnh, bạn sẽ có thể chỉ định tất cả các biến môi trường bạn cần trong ~/.bash_profile
của mình và / hoặc ~/.bashrc
tệp.