我正在寻找mysql_real_escape_string()
SQL Server 的替代方案。是addslashes()
我最好的选择,还是可以使用另一种替代功能?
的替代方法mysql_error()
也将很有用。
我正在寻找mysql_real_escape_string()
SQL Server 的替代方案。是addslashes()
我最好的选择,还是可以使用另一种替代功能?
的替代方法mysql_error()
也将很有用。
Answers:
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数据类型都可以使用此方法,它才是正确的。
mssql_escape()
返回的函数的内容不是为我做的。选择后的文本显示看起来像这样,0x4a2761696d65206269656e206c652063686f636f6c6174
因此不可读。
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/zh/pdo.prepared-statements.php
preg_replace
?还str_replace
不够吗?
empty($value)
将返回true
不仅''
,而且对null
,0
和'0'
!在所有这些情况下,您都将返回一个空字符串。
在查询中可以使用参数时,为什么还要转义任何内容?
sqlsrv_query(
$connection,
'UPDATE some_table SET some_field = ? WHERE other_field = ?',
array($_REQUEST['some_field'], $_REQUEST['id'])
)
无论您的value参数是否正确,它都可以正确地进行选择,删除,更新null
。原则上的问题-不要串联SQL,这样一来,您始终会很安全,并且查询效果会更好。
您可以查看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' ) ";
等等...
经过数小时的努力,我想出了一种感觉最好的解决方案。
Chaos将值转换为十六进制字符串的答案不适用于每种数据类型,特别是对于日期时间列。
我使用的是PHP PDO::quote()
,但是由于PHP附带了它,PDO::quote()
因此MS SQL Server不支持它并返回FALSE
。解决该问题的方法是下载一些Microsoft捆绑软件:
之后,您可以使用DSN将PHP与PDO连接起来,如下例所示:
sqlsrv:Server=192.168.0.25; Database=My_Database;
在DSN中使用UID
和PWD
参数无效,因此在创建连接时,用户名和密码作为PDO构造函数中的第二个和第三个参数传递。现在您可以使用PHP了PDO::quote()
。请享用。
用户混乱在2009-02-22T121000中给出的答案并不适合所有查询。
例如,“从WINDOWS创建登录[0x6f6c6f6c6f]”将为您提供一个例外。
PS:看一下用于PHP的SQL Server驱动程序,http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx和sqlsrv_prepare函数,该函数可以绑定参数。
PSS:上面的查询也无济于事;)
警告:此功能已在PHP 7.0.0中删除。
http://php.net/manual/zh/function.mssql-query.php
对于仍在使用这些mssql_ *函数的任何人,请记住,从v7.0.0起它们已从PHP中删除。因此,这意味着您最终必须重写模型代码以使用PDO库,sqlsrv_ *等。如果您正在寻找带有“引用/转义”方法的内容,我建议您使用PDO。
此功能的替代方法包括:PDO :: query(),sqlsrv_query()和odbc_exec()
如果使用的是PDO,则可以使用该PDO::quote
方法。
最好也转义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;
}
为了将SQL中的十六进制值转换回ASCII,这是我得到的解决方案(使用用户混乱中的函数编码为十六进制)
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);