18

PHP/MySQL で文字列をエスケープ/削除する際に問題が発生しています - 冗長なスラッシュが常にあるようです。


例として、次の文字列を見てみましょう。

<span style="text-decoration:underline;">underline</span>


データベースに文字列を追加するとき、私はそれをエスケープしてmysql_real_escape_string()おり、以下がデータベースに保存されます( EDIT : mysql アプリでデータベースに直接クエリを実行してこれを確認しました):

<span style=\\\"text-decoration:underline;\\\">underline</span>


データベースから読み戻すときに、文字列を渡すstripslashes()と、次のものが返されます。

<span style=\"text-decoration:underline;\">underline</span>


引用符はまだエスケープされているため、html が壊れ、テキストに下線が引かれません。


  1. なぜmysql_real_escape_string()3 つのスラッシュを追加し、stripslashes()2 つのスラッシュを削除するのですか? 両方とも1つのスラッシュを追加/削除することを期待しています.
  2. どうすればこれを防ぐことができますか?
  3. 私はこれに正しい方法でアプローチしていますか?
4

3 に答える 3

83

最良の解決策

php.ini ファイルで、magic_quotes_gpcディレクティブが on に設定されている可能性があります。これは、セキュリティ上の理由から無効にする必要があります。php.ini ファイルにアクセスできない場合 (共有ホストなど) は、.htaccess ディレクティブを使用していつでも同じことができます (これが apache サーバーであると仮定します)。

あなたのphp.iniで

magic_quotes_gpc Off

.htaccess ファイル内:

php_flag magic_quotes_gpc Off

なぜこうなった?

これが発生する理由は、次の一連のロジックによるものです。

  1. エスケープが必要な文字列がサーバーに送信されます。
    • This is my string. It's awesome.
  2. Magic Quotes は、コードに到達する前にアポストロフィをエスケープします。
    • This is my string. It\'s awesome
  3. mysql_real_escape_string\\バックスラッシュとアポストロフィの 2 文字をエスケープするようになりました\'
    • This is my string. It\\\'s awesome
  4. この新しいスーパーエスケープされた文字列はデータベースに保存されます。
  5. 文字列がデータベースから取得されると、 に渡され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);
于 2009-10-05T20:54:19.163 に答える
3

データベースに文字列を追加するとき、私はそれをエスケープして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 つ多くのエスケープ レベルがあり、その結果、クエリを実行したときにデータがどのように出力されるかが分かります。あなたの場合、おそらく起こっていることは、魔法の引用符をオンにしてから、クエリに埋め込む前に文字列をエスケープすることです。これにより、二重エスケープが発生し、データが改ざんされます。適切な解決策は、文字列をエスケープし続け、魔法の引用符をオフにすることです。また、データベースから出てくるデータに対して何もしないでください。システムに既に存在するデータを最初にクリーンアップする必要があることに注意してください。

于 2009-10-05T21:11:44.350 に答える
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']);

于 2013-02-06T07:05:58.093 に答える