兩者都能設定 character_set_client、character_set_connection、character_set_results,但 **mysqli_set_charset 額外更新客戶端結構體 charset 指標,影響 mysql_real_escape_string 安全性**。
SET NAMES utf8;
-- 等價於:
SET character_set_client = utf8;
SET character_set_connection = utf8;
SET character_set_results = utf8;
⚠️ **缺陷**:僅修改 Session 變數,**不更新 PHP mysqli 客戶端結構體**,導致 mysqli_real_escape_string() 仍使用舊字元集判斷多位元組字元,造成 **SQL 注入風險**(特別是 GBK/Big5 等多位元組編碼)。
int mysql_set_character_set(MYSQL *mysql, const char *cs_name) {
// 1. 執行 SET NAMES
sprintf(buff, "SET NAMES %s", cs_name);
mysql_real_query(mysql, buff, strlen(buff));
// 2. 關鍵:更新客戶端結構體 charset 指標
mysql->charset = cs; // 指向 charset_info_st 結構
}
| 特性 | SET NAMES | mysqli_set_charset |
|---|---|---|
| 設定 Session 字元集 | ✅ | ✅ |
| 更新客戶端 charset 結構體 | ❌ | ✅ |
| 影響 mysqli_real_escape_string | ❌ (危險) | ✅ (安全) |
| PDO 等效方法 | SET NAMES | PDO::MYSQL_ATTR_INIT_COMMAND 或 DSN charset=utf8 |
| 持久連線行為 | 每次查詢需重設 | 連線池內自動保持 |
$mysqli->set_charset('utf8mb4')charset=utf8mb4 (PHP 5.3.6+)SET NAMES 作為唯一設定手段my.cnf 設定 character-set-server=utf8mb4、collation-server=utf8mb4_unicode_ci核心結論:
mysqli_set_charset是**唯一正確**的 PHP 客戶端字元集設定方式,它同步更新 Session 變數與客戶端內部狀態,保障real_escape_string正確處理多位元組字元,防禦 SQL 注入。