首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > Mysql >

(转)addslashes与mysql_real_escape_string的差别

2012-12-23 
(转)addslashes与mysql_real_escape_string的区别我们为了更深层次的探究这两个函数的不同..还是去看一看P

(转)addslashes与mysql_real_escape_string的区别
我们为了更深层次的探究这两个函数的不同..还是去看一看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必须是连接数据库之后才能使用.为了证实这一点.

我们来简单的实验下.


<?php 
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了:)

热点排行