Oracle PDO OCI字符集失败


Oracle PDO OCI charset failing

我使用的是即时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中设置环境变量也不起作用!

你必须:

  1. 将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
    
  2. 将其添加到/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_LANGLD_LIBRARY_PATHC_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