PHP Conference Japan 2024

mysqli::set_charset

mysqli_set_charset

(PHP 5 >= 5.0.5, PHP 7, PHP 8)

mysqli::set_charset -- mysqli_set_charset設定用戶端字元集

說明

物件導向風格

public mysqli::set_charset(字串 $charset): 布林值

程序風格

mysqli_set_charset(mysqli $mysql, string $charset): bool

設定在與資料庫伺服器傳送資料時所使用的字元集。

參數

mysql

僅限程序式風格:由 mysqli_connect()mysqli_init() 返回的 mysqli 物件。

charset

所需的字元集。

回傳值

成功時返回 true,失敗時返回 false

錯誤/例外

如果啟用了 mysqli 錯誤回報 (MYSQLI_REPORT_ERROR) 且請求的操作失敗,則會產生警告。此外,如果模式設定為 MYSQLI_REPORT_STRICT,則會改為拋出 mysqli_sql_exception

範例

範例 #1 mysqli::set_charset() 範例

物件導向風格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "test");

printf("初始字元集:%s\n", $mysqli->character_set_name());

/* 將字元集更改為 utf8mb4 */
$mysqli->set_charset("utf8mb4");

printf("目前字元集:%s\n", $mysqli->character_set_name());

程序風格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'test');

printf("初始字元集:%s\n", mysqli_character_set_name($link));

/* 將字元集更改為 utf8mb4 */
mysqli_set_charset($link, "utf8mb4");

printf("目前字元集:%s\n", mysqli_character_set_name($link));

以上範例的輸出結果會類似於

Initial character set: latin1
Current character set: utf8mb4

注意事項

備註:

這是更改字元集的首選方法。不建議使用 mysqli_query() 來設定它(例如 SET NAMES utf8)。詳情請參閱MySQL 字元集概念章節。

另請參閱

新增備註

使用者貢獻的備註 5 則備註

Konstantin Rozinov
7 年前
Claude 的評論(https://php.dev.org.tw/manual/en/mysqli.set-charset.php#121067)是正確的。

在建立連線後像這樣設定字元集(實際上是編碼)
$connection->set_charset("utf8mb4")

無法為連線設定正確的校對規則

client 字元集:utf8mb4
connection 字元集:utf8mb4
database 字元集:utf8mb4
filesystem 字元集:binary
results 字元集:utf8mb4
server 字元集:utf8mb4
system 字元集:utf8
connection 校對規則:utf8mb4_general_ci <---- 仍然顯示 general
database 校對規則:utf8mb4_unicode_ci
server 校對規則:utf8mb4_unicode_ci

如果使用 SET NAMES,則可以正常運作
$connection->query("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci");

client 字元集:utf8mb4
connection 字元集:utf8mb4
database 字元集:utf8mb4
filesystem 字元集:binary
results 字元集:utf8mb4
server 字元集:utf8mb4
system 字元集:utf8
connection 校對規則:utf8mb4_unicode_ci <-- 現在顯示 unicode
database 校對規則:utf8mb4_unicode_ci
server 校對規則:utf8mb4_unicode_ci

請注意,我在伺服器上設定了以下變數

將以下設定為:utf8mb4_unicode_ci

character_set_client
character_set_connection
character_set_database
character_set_results
character_set_server

collation_connection
collation_server

設定

character-set-client-handshake = FALSE 或 0
skip-character-set-client-handshake = TRUE 或 1
Emmanuel Appiah
8 年前
就我的情況而言,我曾嘗試將 mysql 的校對規則從 utf8mb4_unicode_ci 更改為 uft8_general_ci。

然後貼上

mysqli_set_charset( $con, 'utf8');

就在我執行 SELECT 命令之前。

這是我的資料庫讀取程式碼

/*

$DB_SERVER="資料庫伺服器名稱";
$DB_USER_READER="root";
$DB_PASS_READER="密碼";
$DB_NAME="資料庫名稱";
$DB_PORT="連接埠號碼";

$SELECT_WHAT="`表格中的欄位名稱`";
$WHICH_TBL="`表格名稱`";
$ON_WHAT_CONDITION="`id`='7'";

*/

$con = mysqli_connect($DB_SERVER, $DB_USER_READER, $DB_PASS_READER, $DB_NAME, $DB_PORT);//這是用於選取的唯一連線

mysqli_set_charset( $con, 'utf8');


$slct_stmnt = "SELECT ".$SELECT_WHAT." FROM ".$WHICH_TBL." WHERE ".$ON_WHAT_CONDITION;

$slct_query = mysqli_query($con, $slct_stmnt);

if ($slct_query==true) {
//在此處執行您的操作 . . .
}

它就像有魔力一樣運作。一切順利。以上程式碼可以用於從儲存此類資料的資料庫表格欄位中讀取中文、俄文、阿拉伯文或任何國際語言。
claude dot pache at gmail dot com
7 年前
雖然文件說明使用該函數比使用 SET NAMES 更佳,但在使用非預設排序規則的情況下,它並不夠用。

<?php
// 這會將 collation_connection 重設為 latin1_swedish_ci
// (latin1 的預設排序規則):
$mysqli->set_charset('latin1');

// 您必須在 mysqli::set_charset() *之後* 執行以下語句
// 才能獲得 collation_connection 的所需值:
$mysqli->query("SET NAMES latin1 COLLATE latin1_german1_ci");
ASchmidt at Anamera dot net
6 年前
要將字元集(例如 utf8mb4)和排序規則與 schema(資料庫)設定對齊

<?php
$mysqli
= new mysqli( DB_HOST, DB_USER, DB_PASSWORD, DB_SCHEMA, DB_PORT );
if (
0 !== $mysqli->connect_errno )
throw new
\Exception( $mysqli->connect_error, $mysqli->connect_errno );

if (
TRUE !== $mysqli->set_charset( 'utf8mb4' ) )
throw new
\Exception( $mysql->error, $mysqli->errno );

if (
TRUE !== $mysqli->query( 'SET collation_connection = @@collation_database;' ) )
throw new
\Exception( $mysql->error, $mysqli->errno );
?>

確認方法

<?php
echo 'character_set_name: ', $mysqli->character_set_name(), '<br />', PHP_EOL;
foreach(
$mysqli->query( "SHOW VARIABLES LIKE '%_connection';" )->fetch_all() as $setting )
echo
$setting[0], ': ', $setting[1], '<br />', PHP_EOL;
?>

將會輸出類似以下的內容
字元集名稱:utf8mb4
connection 字元集:utf8mb4
校對連線:utf8mb4_unicode_520_ci
chris at ocproducts dot com
6 年前
請注意,使用 utf8mb4 搭配此函式時,可能會導致此函式傳回 false,具體取決於編譯到 PHP 中的 MySQL 用戶端程式庫。如果用戶端程式庫的版本早於 utf8mb4 的引入,那麼 PHP 呼叫程式庫的 'mysql_set_character_set' 將會傳回錯誤,因為它無法辨識該字元集。

您唯一能知道發生錯誤的方法是檢查傳回值,因為此函式不會發出 PHP 警告。
mysqli_error 將會傳回類似以下的訊息:
「無法初始化字元集 utf8mb4 (路徑:/usr/share/mysql/charsets/)」
(我認為目錄与此無關;我認為 utf8mb4 與 utf8 的區別是在內部處理的)

解決方法是使用 utf8 重新呼叫,然後使用 utf8mb4 執行 'SET NAMES' 查詢。

如果您的 MySQL 伺服器預設配置為使用 utf8,那麼您可能不會注意到任何問題,直到出現奇怪的錯誤。就位元組而言,它似乎仍然可以正確地儲存到資料庫中。但是,如果您截斷字串以符合欄位,則可能會出現「資料過長」錯誤,因為在長度檢查期間,從 MySQL 的角度來看,每個 4 位元組字元實際上是多個單獨的字元。這讓我花了好幾個小時除錯。
To Top