我使用的是即时oracle客户端11.2,php 5.5.16,它是从具有以下配置参数的源代码编译而来的:
'./configure' '--enable-fpm' '--enable-bcmath' '--with-bz2' '--enable-calendar' '--with-curl' '--enable-dba' '--enable-exif' '--enable-ftp' '--with-gd' '--with-gettext' '--with-kerberos' '--enable-mbstring' '--with-mcrypt' '--with-openssl' '--enable-shmop' '--enable-soap' '--enable-sockets' '--enable-sysvmsg' '--enable-wddx' '--enable-zip' '--with-zlib' '--with-xsl' '--with-mysql' '--with-mysqli' '--with-pgsql' '--with-pdo-mysql' '--with-pdo-pgsql' '--with-oci8' '--with-pdo-oci'
在我之前的配置中,我使用了apache2(--with-apxs2=/usr/bin/apxs2
而不是--enable-fpm
)和oracle和oci8。我的数据源名称是:"oci:dbname=//IP:1521/SID;charset=UTF8"
。它运行得很好。
今天我想把这个服务器配置从apache转移到nginx和fpm。一切都很好,除了在连接时,PDO抛出:
OCIEnvNlsCreate: Check the character set is valid and that PHP has access to Oracle libraries and NLS data
除了php-fpm处理php而不是apxs之外,我得到了完全相同的配置。
如果我删除charset=UTF8
部分,它可以工作,但显然我有字符集错误。我在php_fpm.conf
中添加了env[NLS_LANG]=FRENCH_FRANCE.UTF8
环境变量,但没有成功。
我该怎么做才能使nginx/php-fpm配置正常工作?
再次阅读oci8安装php页面上的注释,我已经解决了这个问题。
事实是,即使oraclephp文档中提到了这一点,在php_fpm.conf
中设置环境变量也不起作用!
你必须:
-
将oracle特定配置文件写入
vim /etc/profile.d/oracle.sh
#!/bin/bash ORACLE_HOME=/usr/lib/oracle/11.2/client64 C_INCLUDE_PATH=/usr/include/oracle/11.2/client64 LD_LIBRARY_PATH=$ORACLE_HOME/lib #remember this is the client NLS_LANG not the server one NLS_LANG=FRENCH_FRANCE.UTF8 export ORACLE_HOME LD_LIBRARY_PATH NLS_LANG
-
将其添加到
/etc/init.d/php-fpm
. /etc/profile.d/oracle.sh
今天解决了这个问题。在我的案例中,问题只出现在一个环境变量中:ORACLE_HOME
。
如果我使用php-cli运行脚本,那么ORACLE_HOME被设置为/usr/lib,一切都很好,所以dsn中的charset=UTF8是可以的。
但是,如果我用php-fpm运行相同的脚本,那么就没有设置ORACLE_HOME,这就是dsn中charset=UTF8破坏运行时的原因。
所以我的解决方案是添加这个:
putenv('ORACLE_HOME=/usr/lib');
到我的php脚本。不需要设置任何其他变量。因此设置NLS_LANG
、LD_LIBRARY_PATH
或C_INCLUDE_PATH
是冗余。
解决了将环境变量添加到php-fpm.conf中的问题,如下所示:
; ORACLE
env[ORACLE_HOME] = /usr/lib/oracle/12.2/client64
env[C_INCLUDE_PATH] = /usr/lib/oracle/12.2/client64
env[LD_LIBRARY_PATH] = /usr/lib/oracle/12.2/client64/lib
env[NLS_LANG] = AMERICAN_AMERICA.AL32UTF8