web-dev-qa-db-ja.com

PHP mysql_real_escape_string()-> stripslashes()複数のスラッシュを残す

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が壊れ、テキストには下線が引かれていません。


  1. なぜmysql_real_escape_string()は3つのスラッシュを追加し、stripslashes()は2つのスラッシュを削除するのですか?私はそれらの両方が1つのスラッシュを追加/削除することを期待します。
  2. これを防ぐにはどうすればよいですか?
  3. 私はこれに正しい方法で近づいていますか?
18
teaforchris

最良のソリューション

Php.iniファイルでは、 magic_quotes_gpc ディレクティブがオンに設定されている可能性があります。これはセキュリティ上の理由から無効にする必要があります。 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);
81
tj111

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

3
troelskn

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']);を使用できることです。

1
sujay mondal