unsigned long
mysql_real_escape_string(MYSQL *mysql,
char *to,
const char *from,
unsigned long length)
此函數會建立一個合法的 SQL 字串,以便在 SQL 陳述式中使用。請參閱字串常值。
mysql_real_escape_string()
如果啟用了 NO_BACKSLASH_ESCAPES
SQL 模式,則會失敗並產生 CR_INSECURE_API_ERR
錯誤。在這種情況下,該函數無法跳脫引號字元,除非將它們加倍,並且為了正確執行此操作,它必須比可用的資訊知道更多關於引號上下文的資訊。請改用 mysql_real_escape_string_quote()
,它會採用額外的引數來指定引號上下文。
mysql
引數必須是有效、開啟的連線,因為字元跳脫取決於伺服器使用的字元集。
from
引數中的字串會經過編碼,以產生跳脫的 SQL 字串,並考量到連線的目前字元集。結果會放置在 to
引數中,接著是終止的空位元組。
編碼的字元為 \
、'
、"
、NUL
(ASCII 0)、\n
、\r
和 Control+Z。嚴格來說,MySQL 僅要求反斜線和用來在查詢中引號字串的引號字元被跳脫。mysql_real_escape_string()
會引號其他字元,讓它們在日誌檔案中更容易讀取。作為比較,請參閱字串常值中的常值字串引號規則和 QUOTE()
SQL 函數,以及字串函數與運算符號。
from
指向的字串必須為 length
個位元組長。您必須將 to
緩衝區配置為至少 length*2+1
個位元組長。(在最糟的情況下,每個字元可能需要使用兩個位元組進行編碼,並且必須有空間容納終止的空位元組。)當 mysql_real_escape_string()
返回時,to
的內容會是空終止字串。傳回值是編碼字串的長度,不包含終止的空位元組。
如果您必須變更連線的字元集,請使用 mysql_set_character_set()
函數,而不是執行 SET NAMES
(或 SET CHARACTER SET
)陳述式。mysql_set_character_set()
的運作方式與 SET NAMES
類似,但也會影響 mysql_real_escape_string()
使用的字元集,而 SET NAMES
則不會。
下列範例會將兩個跳脫字串插入 INSERT
陳述式中,每個字串都在單引號字元內
char query[1000],*end;
end = my_stpcpy(query,"INSERT INTO test_table VALUES('");
end += mysql_real_escape_string(&mysql,end,"What is this",12);
end = my_stpcpy(end,"','");
end += mysql_real_escape_string(&mysql,end,"binary data: \0\r\n",16);
end = my_stpcpy(end,"')");
if (mysql_real_query(&mysql,query,(unsigned int) (end - query)))
{
fprintf(stderr, "Failed to insert row, Error: %s\n",
mysql_error(&mysql));
}
範例中使用的 my_stpcpy()
函數包含在 libmysqlclient
程式庫中,其運作方式與 strcpy()
類似,但會傳回指向第一個參數的終止空值。
放入 to
引數中之編碼字串的長度,不包含終止的空位元組,如果發生錯誤則為 -1。
由於 mysql_real_escape_string()
會傳回無符號值,因此您可以將傳回值與 (unsigned long)-1
(或與等效的 (unsigned long)~0
) 進行比較,以檢查是否為 -1。
-
如果啟用了
NO_BACKSLASH_ESCAPES
SQL 模式,則會發生此錯誤,因為在這種情況下,無法保證mysql_real_escape_string()
會產生正確編碼的結果。若要避免此錯誤,請改用mysql_real_escape_string_quote()
。