mysql,php mysql addslashes_PHP函數 mysql_real_escape_string 與 addslashes 的區別

 2023-10-20 阅读 28 评论 0

摘要:addslashes?和?mysql_real_escape_string?都是為了使數據安全的插入到數據庫中而進行的過濾,那么這兩個函數到底是有什么區別呢?mysql?首先,我們還是從PHP手冊入手:手冊上addslashes轉義的字符是單引號(')、雙引號(")、反斜線(\)與NUL(N

addslashes?和?mysql_real_escape_string?都是為了使數據安全的插入到數據庫中而進行的過濾,那么這兩個函數到底是有什么區別呢?

mysql?首先,我們還是從PHP手冊入手:

手冊上addslashes轉義的字符是單引號(')、雙引號(")、反斜線(\)與NUL(NULL 字符)。

mysql_real_escape_string轉義的字符并沒有被提到,只是說了一句:

注意:mysql_real_escape_string() 并不轉義% 和_。

為什么PHP手冊沒有說呢?因為其實這是個MySql的C的API,所以我們需要查下MySql手冊,上面是這么說的:

編碼的字符為NUL (ASCII 0)、'\n'、'\r'、'\'、'''、'"'、以及Control-Z(請參見9.1節,“文字值”)。(嚴格地講,MySQL僅需要反斜杠和引號字符,用于引用轉義查詢中的字符串。該函數能引用其他字符,從而使得它們在日志文件中具有更好的可讀性)。

MySql手冊上面的話總是令人費解的。

我們為了更深層次的探究這兩個函數的不同,還是去看一看PHP的源碼吧。

這是PHP的addslashes函數:

PHP_FUNCTION(addslashes)

{

zval **str;

if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {

WRONG_PARAM_COUNT;

}

convert_to_string_ex(str);

if (Z_STRLEN_PP(str) == 0) {

RETURN_EMPTY_STRING();

}

RETURN_STRING(php_addslashes(Z_STRVAL_PP(str),

Z_STRLEN_PP(str),

&Z_STRLEN_P(return_value), 0

TSRMLS_CC), 0);

}

很顯然,它調用了 php_addslashes,我們繼續看這個函數,

PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_free TSRMLS_DC)

{

return php_addslashes_ex(str, length, new_length, should_free, 0 TSRMLS_CC);

}

結果又是在調用 php_addslashes_ex,我們就像在剝洋蔥一樣,一步一步的接近真理。

PHPAPI char *php_addslashes_ex(char *str, int length, int *new_length, int should_free, int ignore_sybase TSRMLS_DC)

{

/* maximum string length, worst case situation */

char *new_str;

char *source, *target;

char *end;

int local_new_length;

if (!new_length) {

new_length = &local_new_length;

}

if (!str) {

*new_length = 0;

return str;

}

new_str = (char *) safe_emalloc(2, (length ? length : (length = strlen(str))), 1);

source = str;

end = source + length;

target = new_str;

if (!ignore_sybase && PG(magic_quotes_sybase)) {

while (source < end) {

switch (*source) {

case '\0':

*target++ = '\\';

*target++ = '0';

break;

case '\'':

*target++ = '\'';

*target++ = '\'';

break;

default:

*target++ = *source;

break;

}

source++;

}

} else {

while (source < end) {

switch (*source) {

case '\0':

*target++ = '\\';

*target++ = '0';

break;

case '\'':

case '\"':

case '\\':

*target++ = '\\';

/* break is missing *intentionally* */

default:

*target++ = *source;

break;

}

source++;

}

}

*target = 0;

*new_length = target - new_str;

if (should_free) {

STR_FREE(str);

}

new_str = (char *) erealloc(new_str, *new_length + 1);

return new_str;

}

上面的函數已經非常清楚的描述出都要轉義哪些字符了,現在我們去看一看 mysql_real_escape_string

這個不在string.c里了,是在mysql擴展中。

PHP_FUNCTION(mysql_real_escape_string)

{

zval *mysql_link = NULL;

char *str;

char *new_str;

int id = -1, str_len, new_str_len;

php_mysql_conn *mysql;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &str, &str_len, &mysql_link) == FAILURE) {

return;

}

if (ZEND_NUM_ARGS() == 1) {

id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);

CHECK_LINK(id);

}

ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);

new_str = safe_emalloc(str_len, 2, 1);

new_str_len = mysql_real_escape_string(&mysql->conn, new_str, str, str_len);

new_str = erealloc(new_str, new_str_len + 1);

RETURN_STRINGL(new_str, new_str_len, 0);

}

這個函數并沒有像上面的那樣剝洋蔥,而是直接調用了MySql的C的API,mysql_real_escape_string()。

需要注意的是,這個函數在調用mysql_real_escape_string這個API之前,先是判斷了是否連接上了數據庫,

CHECK_LINK(id); // 就是這句

所以,這就意味著mysql_real_escape_string必須是連接數據庫之后才能使用。為了證實這一點,我們來簡單的實驗下:

echo mysql_real_escape_string("fdsafda'fdsa");

結果:

Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied for user 'ODBC'@'localhost' (using password: NO) in PHPDocument1 on line 2

Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: A link to the server could not be established in PHPDocument1 on line 2

果然報錯了,顯示沒有鏈接上數據庫。

好了,總結就先告一段落。

終于明白為什么那么多開源的程序比如Discuz用addslashes而不用mysql_real_escape_string了。

所以呢,以后也就用addslashes好了,暫時可以忘記掉mysql_real_escape_string了!

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/152097.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息