mysql_real_escape_string()
SQL Serverの代替を探しています。あるaddslashes()
私の最良の選択肢を用いることができる別の代替機能はありますか?
の代替mysql_error()
も役立ちます。
mysql_real_escape_string()
SQL Serverの代替を探しています。あるaddslashes()
私の最良の選択肢を用いることができる別の代替機能はありますか?
の代替mysql_error()
も役立ちます。
回答:
addslashes()
十分ではありませんが、PHPのmssqlパッケージは適切な代替手段を提供していません。醜いが完全に一般的なソリューションは、データを16進バイト文字列としてエンコードすることです。
$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/en/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'])
)
これは、値パラメーターがそうであるかどうかに関係なく、選択、削除、更新で正しく機能します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' ) ";
等...
何時間もこれに苦労した後、私はほとんど最高に感じられる解決策を思いつきました。
値を16進文字列に変換するというカオスの答えは、すべてのデータ型、特に日時列では機能しません。
PHPを使用していますPDO::quote()
が、PHPに付属してPDO::quote()
いるため、MS SQL Serverではサポートされておらず、が返されますFALSE
。それが機能するための解決策は、いくつかのMicrosoftバンドルをダウンロードすることでした。
その後、次の例のようなDSNを使用してPDOでPHPに接続できます。
sqlsrv:Server=192.168.0.25; Database=My_Database;
DSNでパラメータUID
とPWD
パラメータを使用しても機能しなかったため、接続の作成時にPDOコンストラクタの2番目と3番目のパラメータとしてユーザー名とパスワードが渡されました。これで、PHPを使用できますPDO::quote()
。楽しい。
ユーザーchaosによる2009-02-22T121000からの回答は、すべてのクエリに適合しません。
たとえば、「CREATE LOGIN [0x6f6c6f6c6f] FROM WINDOWS」とすると、例外が発生します。
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/en/function.mssql-query.php
これらのmssql_ *関数をまだ使用している人は、v7.0.0からPHPから削除されていることに注意してください。つまり、PDOライブラリー、sqlsrv_ *などを使用するようにモデルコードを最終的に書き換える必要があることを意味します。「引用/エスケープ」メソッドで何かを探している場合は、PDOをお勧めします。
この関数の代替には、PDO :: query()、sqlsrv_query()、odbc_exec()などがあります。
PDOを使用している場合は、このPDO::quote
メソッドを使用できます。
SQLの16進値をASCIIに戻す変換の場合、これは私がこれで得た解決策です(ユーザーカオスからの関数を使用して16進にエンコードします)。
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);
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;
}