mysql_real_escape_string()
的替代方法。除了使用addslashes()
之外,是否还有其他可用的替代函数?另外,如果能提供
mysql_error()
的替代方法也会很有帮助。mysql_real_escape_string()
的替代方法。除了使用addslashes()
之外,是否还有其他可用的替代函数?mysql_error()
的替代方法也会很有帮助。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()
。
SQLSTATE[22007]: Invalid datetime format: 210 [Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting datetime from binary/varbinary string.
我认为只有当这种方法适用于每种 MSSQL 数据类型时,它才能正确。 - Alejandro García Iglesiasmssql_escape()
函数返回的内容对我来说不起作用。在执行选择操作后,文本显示为 0x4a2761696d65206269656e206c652063686f636f6c6174
,因此无法阅读。 - Jeff Noelfunction 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
preg_replace
?str_replace
不足吗? - Gabeempty($value)
不仅会返回 ''
,还会返回 null
、0
和 '0'
!因此,在所有这些情况下,您都会返回一个空字符串。请修改代码。 - Nux当你可以在查询中使用参数时,为什么还要费心去转义任何东西?!
sqlsrv_query(
$connection,
'UPDATE some_table SET some_field = ? WHERE other_field = ?',
array($_REQUEST['some_field'], $_REQUEST['id'])
)
无论您的值参数是否为null
,在选择、删除、更新中都可以正常工作。
坚持原则——不要连接SQL,这样您就始终安全,并且查询的可读性更好。
您可以研究一下PDO库。您可以使用PDO的预处理语句,如果正确使用预处理语句,PDO会自动转义字符串中的任何错误字符。我认为这仅适用于PHP 5。
处理单引号和双引号的另一种方式是:
function mssql_escape($str)
{
if(get_magic_quotes_gpc())
{
$str = stripslashes($str);
}
return str_replace("'", "''", $str);
}
$value = 'This is a quote, "I said, 'Hi'"';
$value = str_replace( "'", "''", $value );
$value = str_replace( '"', '""', $value );
$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";
在苦苦挣扎几个小时后,我想出了一个几乎最佳的解决方案。
将值转换为十六进制字符串的混沌答案并不能适用于每种数据类型,特别是日期时间列。
我使用 PHP 的 PDO::quote()
,但由于它随 PHP 一起发布,PDO::quote()
不支持 MS SQL Server 并返回 FALSE
。让它工作的解决方案是下载一些微软捆绑包:
之后,您可以使用像以下示例一样的 DSN 在 PHP 中连接 PDO:
sqlsrv:Server=192.168.0.25; Database=My_Database;
UID
和PWD
参数无效,因此在创建连接时,在PDO构造函数的第二个和第三个参数中传递用户名和密码。现在您可以使用PHP的PDO::quote()
。享受吧。http://php.net/manual/en/function.mssql-query.php
如果您仍在使用这些mssql_*函数,请记住它们已从PHP v7.0.0中删除。因此,这意味着您最终必须重写您的模型代码,以使用PDO库、sqlsrv_*等。如果您正在寻找带有“引用/转义”方法的东西,我建议使用PDO。2009-02-22T121000用户chaos的回答并不适用于所有查询。
例如,"CREATE LOGIN [0x6f6c6f6c6f] FROM WINDOWS"会导致异常。
PS:查看PHP的SQL Server驱动程序http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx和sqlsrv_prepare函数,它可以绑定参数。
PSS:这也无法帮助您解决上述查询问题;)
最好也转义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;
}