8

フォームからデータベースにデータを挿入しています。私はテキストをエスケープするために使用しています(同じ結果でaddslashes試しました)。mysql_real_escape_string

通常の引用符はエスケープされますが、他の引用符はエスケープされません。たとえば、文字列:

ホーマーの血は、モーの新しいビールの秘密の成分になります。

に変換されます:

ホーマーの血は、モーの新しいビールの秘密の成分になります。

中途半端な引用がエスケープされていないことが重要だとは思いませんでしたが、データベースに挿入されるのはこのテキストだけです。

ホーマーの血が萌えの秘伝となる

したがって、PHPは中引用符は問題ないと考えていますが、MySQLは文字列を失っています。ただし、MySQLはエラーを出していません。

4

2 に答える 2

7

Webインターフェイスで使用されている文字エンコードとデータベースレベルで使用されている文字エンコードの不一致を探します。たとえば、WebインターフェイスがUTF-8を使用していて、データベースがデフォルトのMySQLエンコーディングであるを使用している場合はlatin1、テーブルをで設定する必要がありますDEFAULT CHARSET=utf8

mysql_real_escape_string()ちなみに、またはmysqli を使用してください。SQLインジェクションに対する適切な保護でaddslashes()はありません。

于 2009-08-23T16:10:44.370 に答える
7

Moeの'は、その文字列がlatin1でエンコードされているが、mysqlサーバーがutf8を想定している場合に有効にならない、サンプル文字列内の唯一の文字です。

簡単なデモンストレーション:

<?php
function foo($s) {
    echo 'len=', strlen($s), ' ';
  for($i=0; $i<strlen($s); $i++) {
    printf('%02X ', ord($s[$i]));
  }
  echo "\n";
}

 // my file is latin1 encoded and so is the string literal
foo('Moe’s');
// now try it with an utf8 encoded string
foo( utf8_encode('Moe’s') );

プリント

len = 5 4D 6F 65 92 73
len = 6 4D 6F 65 C2 92 73

したがって、問題は次のとおりです。mysqlサーバーに「間違った」エンコーディングで何かをフィードしますか?
各接続には接続文字セットがあり、mysqlサーバーはクライアント(phpスクリプト)がその文字セットでエンコードされたデータを送信することを期待しています。接続文字セットが何であるかを知ることができます

SHOW VARIABLES LIKE '%character%'

のように

$mysql = mysql_connect('..', '..', '..') or die(mysql_error());
mysql_select_db('..', $mysql) or die(mysql_error());

$query = "SHOW VARIABLES like '%character%'";
$result = mysql_query($query, $mysql) or die(__LINE__.mysql_error());
while( false!==($row=mysql_fetch_array($result, MYSQL_ASSOC)) ) {
  echo join(', ', $row), "\n";
}

これは次のようなものを印刷する必要があります

character_set_client, utf8
character_set_connection, utf8
character_set_database, latin1
character_set_filesystem, binary
character_set_results, utf8
character_set_server, utf8
character_set_system, utf8

「my」接続文字セットがutf8であることをcharacter_set_connection, utf8示します。つまり、mysqlサーバーはクライアント(php)からutf8でエンコードされた文字を予期します。「あなたの」接続文字セットとは何ですか?

次に、パラメータ文字列の実際のエンコーディングを確認します。

$foo = mysql_real_escape_string($_POST['foo'], $mysql);

に置き換えます

echo '<div>Debug hex($_POST[foo])=';
for($i=0; $i<strlen($s); $i++) {
    printf('%02X ', ord($_POST['foo'][$i]));
}
echo "</div>\n";
$foo = mysql_real_escape_string($_POST['foo'], $mysql);

入力文字列の実際のエンコーディングが何であるかを確認します。92またはC292を印刷しますか?

于 2009-08-23T16:37:42.740 に答える