如何使用PHP在SQL Server中转义字符串?

时间:2009-02-22 11:54:43

标签: php sql-server escaping input-sanitization

我正在为SQL Server寻找mysql_real_escape_string()的替代方案。 addslashes()是我最好的选择还是可以使用另一种替代功能?

修改mysql_error()的替代方案也很有用。

14 个答案:

答案 0 :(得分:70)

addslashes()并不完全足够,但PHP的mssql包没有提供任何合适的替代方案。丑陋但完全通用的解决方案是将数据编码为十六进制字节串,即

$unpacked = unpack('H*hex', $data);
mssql_query('
    INSERT INTO sometable (somecolumn)
    VALUES (0x' . $unpacked['hex'] . ')
');

抽象,那将是:

function mssql_escape($data) {
    if(is_numeric($data))
        return $data;
    $unpacked = unpack('H*hex', $data);
    return '0x' . $unpacked['hex'];
}

mssql_query('
    INSERT INTO sometable (somecolumn)
    VALUES (' . mssql_escape($somevalue) . ')
');

mysql_error()等效于mssql_get_last_message()

答案 1 :(得分:40)

function ms_escape_string($data) {
        if ( !isset($data) or empty($data) ) return '';
        if ( is_numeric($data) ) return $data;

        $non_displayables = array(
            '/%0[0-8bcef]/',            // url encoded 00-08, 11, 12, 14, 15
            '/%1[0-9a-f]/',             // url encoded 16-31
            '/[\x00-\x08]/',            // 00-08
            '/\x0b/',                   // 11
            '/\x0c/',                   // 12
            '/[\x0e-\x1f]/'             // 14-31
        );
        foreach ( $non_displayables as $regex )
            $data = preg_replace( $regex, '', $data );
        $data = str_replace("'", "''", $data );
        return $data;
    }

这里的一些代码是从CodeIgniter中删除的。效果很好,是一个干净的解决方案。

编辑: 上面的代码片段存在很多问题。请不要在没有阅读评论的情况下使用它,以了解它们是什么。更好的是,请不要使用它。参数化查询是您的朋友:http://php.net/manual/en/pdo.prepared-statements.php

答案 2 :(得分:14)

如果您可以在查询中使用参数,为什么还要烦扰任何事情?!

sqlsrv_query(
    $connection, 
    'UPDATE some_table SET some_field = ? WHERE other_field = ?', 
    array($_REQUEST['some_field'], $_REQUEST['id'])
)

无论您的值参数是否为null,它都可以在选择,删除,更新中正常工作。 原则问题 - 不要连接SQL,你总是安全的,你的查询读得更好。

http://php.net/manual/en/function.sqlsrv-query.php

答案 3 :(得分:10)

您可以查看PDO Library。您可以将预准备语句与PDO一起使用,如果您正确执行预准备语句,它将自动转义字符串中的任何错误字符。这只适用于PHP 5。

答案 4 :(得分:4)

处理单引号和双引号的另一种方法是

function mssql_escape($str)
{
   if(get_magic_quotes_gpc())
   {
    $str= stripslashes($str);
   }
   return str_replace("'", "''", $str);
}

答案 5 :(得分:2)

经过几个小时的挣扎,我想出了一个几乎感觉最好的解决方案。

Chaos将值转换为hexstring的答案不适用于每种数据类型,特别是日期时间列。

我使用PHP的PDO::quote(),但由于它附带PHP,MS SQL Server不支持PDO::quote()并返回FALSE。它的工作解决方案是下载一些Microsoft捆绑包:

之后,您可以使用DSN将PHP与PDO连接,如下例所示:

sqlsrv:Server=192.168.0.25; Database=My_Database;

使用DSN中的UIDPWD参数不起作用,因此在创建连接时,用户名和密码将作为PDO构造函数的第二个和第三个参数传递。 现在您可以使用PHP的PDO::quote()。享受。

答案 6 :(得分:2)

为了逃避单引号和双引号,你必须加倍:

$value = 'This is a quote, "I said, 'Hi'"';

$value = str_replace( "'", "''", $value ); 

$value = str_replace( '"', '""', $value );

$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";

等...

和归因:Escape Character In Microsoft SQL Server 2000

答案 7 :(得分:1)

我知道,有点迟到,但是从'2009年2月22日12:10'回答混乱并不适合所有问题。例如: “从WINDOWS创建登录[0x6f6c6f6c6f]”会给你异常

P.S。查看用于php,http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx和sqlsrv_prepare函数的mssql驱动程序,它可以绑定params。

p.s.s。这对上面的查询也没有帮助;)

答案 8 :(得分:0)

  

警告:此功能已在PHP 7.0.0中删除。

http://php.net/manual/en/function.mssql-query.php

对于仍在使用这些mssql_ *函数的人,请记住,自v7.0.0起,它们已从PHP中删除。所以,这意味着你最终必须重写模型代码以使用PDO库sqlsrv_ *等。如果你正在寻找带有“引用/转义”方法的东西,我会推荐PDO。

  

此函数的替代方法包括:PDO :: query(),sqlsrv_query()和odbc_exec()

答案 9 :(得分:0)

如果您使用的是PDO,则可以使用PDO::quote方法。

答案 10 :(得分:0)

还是逃避SQL保留字是不是更好?例如:

function ms_escape_string($data) {
    if ( !isset($data) or empty($data) ) return '';
    if ( is_numeric($data) ) return $data;

    $non_displayables = array(
        '/%0[0-8bcef]/',            // url encoded 00-08, 11, 12, 14, 15
        '/%1[0-9a-f]/',             // url encoded 16-31
        '/[\x00-\x08]/',            // 00-08
        '/\x0b/',                   // 11
        '/\x0c/',                   // 12
        '/[\x0e-\x1f]/',             // 14-31
        '/\27/'
    );
    foreach ( $non_displayables as $regex )
        $data = preg_replace( $regex, '', $data );
    $reemplazar = array('"',"'",'=');
    $data = str_replace($reemplazar, "*", $data );
    return $data;
}

答案 11 :(得分:-1)

对于将SQL中的HEX转换回ASCII的转换,这是我得到的解决方案(使用Chaos中的函数编码为Hex)

function hexEncode($data) {
    if(is_numeric($data))
        return $data;
    $unpacked = unpack('H*hex', $data);
    return '0x' . $unpacked['hex'];
}
function hexDecode($hex) {
    $str = '';
    for($i=0;$i<strlen($hex);$i+=2) $str .= chr(hexdec(substr($hex,$i,2)));
    return $str;
}
$stringHex = hexEncode('Test String');
var_dump($stringHex);
$stringAscii = hexDecode($stringHex);
var_dump($stringAscii);

答案 12 :(得分:-1)

我一直在使用它来替代mysql_real_escape_string()

function htmlsan($htmlsanitize){
    return $htmlsanitize = htmlspecialchars($htmlsanitize, ENT_QUOTES, 'UTF-8');
}
$data = "Whatever the value's is";
$data = stripslashes(htmlsan($data));

答案 13 :(得分:-2)

您可以使用以下正则表达式滚动自己的mysql_real_escape_string版本(并对其进行改进):[\000\010\011\012\015\032\042\047\134\140]。它负责以下字符:null,退格,水平制表符,换行符,回车符,替换号,双引号,单引号,反斜杠,重音符号。 mysql_real_escape_string不支持退格和水平制表符。