首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

解決 PHP PDO 連接 Oracle 中文亂碼問題的完整指南

     編輯:PHP 綜合知識

問題背景

在使用 PHP PDO 連接 Oracle 數據庫時,中文數據讀寫經常出現亂碼。根本原因通常是客戶端字符集(NLS_LANG)與數據庫字符集不匹配,或 PHP 運行環境未正確設置區域設置。本文提供一套在 Linux(CentOS/RHEL)環境下經驗證的完整解決方案。

核心解決思路

通過設置環境變量 NLS_LANG 為 FRENCH_FRANCE.UTF8(或 AMERICAN_AMERICA.AL32UTF8),強制 Oracle Instant Client 以 UTF-8 編碼與數據庫通信,並將該環境變量注入 PHP-FPM 進程。

步驟一:創建 Oracle 環境腳本

在 /etc/profile.d/oracle.sh 中定義 Oracle 客戶端路徑與字符集:

ORACLE_HOME=/usr/lib/oracle/12.1/client64
C_INCLUDE_PATH=/usr/include/oracle/12.1/client64
LD_LIBRARY_PATH=$ORACLE_HOME/lib
# 關鍵:設置客戶端字符集為 UTF-8
NLS_LANG=FRENCH_FRANCE.UTF8
export ORACLE_HOME LD_LIBRARY_PATH NLS_LANG

說明:NLS_LANG 格式為 語言_地區.字符集。此處使用 FRENCH_FRANCE.UTF8 是因為某些 Oracle 版本對 AMERICAN_AMERICA.AL32UTF8 支持不佳;實際部署時請根據 SELECT * FROM NLS_DATABASE_PARAMETERS 查詢的數據庫字符集調整。

步驟二:修改 PHP-FPM 啟動腳本注入環境變量

編輯 /etc/init.d/php-fpm,在文件頭部(#!/bin/bash 之後)引入上述腳本:

. /etc/profile.d/oracle.sh
. /etc/init.d/functions
. /etc/profile.d/oracle.sh
# Check that networking is up.
. /etc/sysconfig/network
# Additional environment file
if [ -f /etc/sysconfig/php-fpm ]; then
    . /etc/sysconfig/php-fpm
fi
if [ "$NETWORKING" = "no" ]; then
    exit 0
fi
RETVAL=0
prog="php-fpm"
pidfile=${PIDFILE-/var/run/php-fpm/php-fpm.pid}
lockfile=${LOCKFILE-/var/lock/subsys/php-fpm}

關鍵點:必須在 php-fpm 進程啟動前 source 環境腳本,確保子進程繼承 NLS_LANG。

步驟三:重啟 PHP-FPM 生效

systemctl restart php-fpm
# 或
service php-fpm restart

驗證方法

創建測試腳本:

<?php
$pdo = new PDO('oci:dbname=//host:1521/sid', 'user', 'pass');
$stmt = $pdo->query("SELECT '測試中文' AS txt FROM dual");
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo $row['txt']; // 應正常輸出「測試中文」
?>

常見坑點補充

  • 字符集不匹配:若數據庫為 AL32UTF8,客戶端 NLS_LANG 建議用 .AL32UTF8 或 .UTF8;若數據庫為 ZHS16GBK,則需設置為 SIMPLIFIED CHINESE_CHINA.ZHS16GBK。
  • 多 PHP-FPM 池:若使用多池配置,需在各池的 env[NLS_LANG] 中顯式設置。
  • CLI 模式:命令行執行 PHP 腳本時,需在 ~/.bashrc 或腳本開頭 putenv('NLS_LANG=...') 設置。

總結

Oracle 中文亂碼 90% 由客戶端字符集設置不當導致。通過在系統級環境腳本統一設置 NLS_LANG 並注入 PHP-FPM,可徹底解決 PDO、OCI8 等擴展的中文編碼問題,避免在業務代碼中反覆 iconv 轉碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved