PHP/MySQLで文字列をエスケープ/ストリッピングする際に問題が発生します-常に余分なスラッシュがあるようです。
例として次の文字列を考えてみましょう:
_<span style="text-decoration:underline;">underline</span>
_
データベースに文字列を追加するときは、mysql_real_escape_string()
を使用してエスケープしています。次のものがデータベースに保存されます([〜#〜] edit [〜#〜]:mysql appで直接データベースにクエリを実行してこれを確認しました):
_<span style=\\\"text-decoration:underline;\\\">underline</span>
_
データベースから読み戻すときに、stripslashes()
を介して文字列を渡しています。次のコードが返されます。
_<span style=\"text-decoration:underline;\">underline</span>
_
引用符は依然としてエスケープされているため、htmlが壊れ、テキストには下線が引かれていません。
mysql_real_escape_string()
は3つのスラッシュを追加し、stripslashes()
は2つのスラッシュを削除するのですか?私はそれらの両方が1つのスラッシュを追加/削除することを期待します。Php.iniファイルでは、 magic_quotes_gpc
ディレクティブがオンに設定されている可能性があります。これはセキュリティ上の理由から無効にする必要があります。 php.iniファイルにアクセスできない場合(共有ホスト上など)は、.htaccessディレクティブを使用して同じことをいつでも実行できます(これはApacheサーバーであると想定しています)。
あなたのphp.iniで
magic_quotes_gpc Off
.htaccessファイル:
php_flag magic_quotes_gpc Off
これが発生している理由は、次の一連のロジックによるものです。
This is my string. It's awesome.
This is my string. It\'s awesome
mysql_real_escape_string
には、エスケープする文字が2つあります。バックスラッシュ\\
とアポストロフィ\'
。です。This is my string. It\\\'s awesome
stripslashes
に渡されます。これにより、手順3で追加された2つのエスケープが削除されますが、バックスラッシュの1つがエスケープされているため、stripslashes
はそれが属していると考えます。This is my string. It\'s awesome
バックスラッシュの数が増えるたびに、これらの文字列をデータベースに再送信すると、この問題は本当に手に負えなくなります。
すばやく簡単な代替策は、magic_quotes
に文字列を渡す前に、mysql_real_escape_string
によって追加されたスラッシュを削除することです。
$str = stripslashes($_POST['str']);
$str = mysql_real_escape_string($str);
文字列をデータベースに追加するときは、
mysql_real_escape_string()
を使用してエスケープしています。次のものがデータベースに保存されます。
<span style=\\\"text-decoration:underline;\\\">underline</span>
いいえ、ちがいます。 SQLクエリで文字列をエスケープする場合、クエリでデータを転送するだけです。データベースはクエリを解析し、余分なスラッシュなしでデータベースにデータを保存します。したがって、データベースからデータを取得するときは、エスケープを解除しない必要があります。それはよくある誤解です。
出力に余分なスラッシュが含まれている場合は、マジッククオートがオンになっている可能性があります。 オフにする 。
mysql> create table foo (bar text) ;
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO foo (bar) VALUES ("<span style=\\\"text-decoration:underline;\\\">underline</span>");
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM foo;
+-------------------------------------------------------------+
| bar |
+-------------------------------------------------------------+
| <span style=\"text-decoration:underline;\">underline</span> |
+-------------------------------------------------------------+
1 row in set (0.00 sec)
ご覧のように、クエリには、データベース内に表示されるデータよりも1レベル多くのエスケープがあり、その結果、クエリを実行するとどのようにエスケープされますか。あなたの場合、おそらくが起こっているのは、マジッククオートがオンになっていて、クエリに埋め込む前に文字列をエスケープすることです。これにより、データが二重にエスケープされ、改ざんされます。適切な解決策は、文字列をエスケープし続けることですが、マジッククオートをオフにすることです。そして、データベースから出てくるデータに対しては何もしない。すでにシステムにあるデータを最初にクリーンアップする必要があることに注意してください。
get_magic_quotes_gpc()
がSERVERでオフの場合、使用できるのは私たちだけです
_$data= mysql_real_escape_string($_POST['data']);
_
get_magic_quotes_gpc()
がSERVERでオンの場合、使用する必要があります
_$data= mysql_real_escape_string(stripslashes($_POST['data']));
_
それ以外の場合は、データに2つの円記号を追加します。
また、別の解決策は、stripslashes($data)
のみを使用する場合、datadaseからフェッチしながらmysql_real_escape_string($_POST['data']);
を使用できることです。