web-dev-qa-db-ja.com

MySQLに挿入するときにPHPで一重引用符をエスケープする

私は理解できないように思える厄介な問題があります...私はここの誰かが私を正しい方向に向けることができるかもしれないと思っています...

2つのSQLステートメントがあります。-最初のステートメントは、フォームからデータベースに情報を入力します。 -2番目は、上記で入力したデータベースからデータを取得し、電子メールを送信してから、トランザクションの詳細を記録します

問題は、単一引用符が2番目のエントリでのみMySQLエラーをトリガーしているように見えることです!!!最初のインスタンスは問題なく機能しますが、2番目のインスタンスはmysql_error()をトリガーします。

フォームのデータは、フォームにキャプチャされたデータとは異なる方法で処理されますか?

クエリ#1-これは問題なく機能します(一重引用符をエスケープすることなく)

$result = mysql_query("INSERT INTO job_log 
(order_id, supplier_id, category_id, service_id, qty_ordered, customer_id, user_id, salesperson_ref, booking_ref, booking_name, address, suburb, postcode, state_id, region_id, email, phone, phone2, mobile, delivery_date, stock_taken, special_instructions, cost_price, cost_price_gst, sell_price, sell_price_gst, ext_sell_price, retail_customer, created, modified, log_status_id) 
VALUES 
('$order_id', '$supplier_id', '$category_id', '{$value['id']}', '{$value['qty']}', '$customer_id', '$user_id', '$salesperson_ref', '$booking_ref', '$booking_name', '$address', '$suburb', '$postcode', '$state_id', '$region_id', '$email', '$phone', '$phone2', '$mobile', STR_TO_DATE('$delivery_date', '%d/%m/%Y'), '$stock_taken', '$special_instructions', '$cost_price', '$cost_price_gst', '$sell_price', '$sell_price_gst', '$ext_sell_price', '$retail_customer', '".date('Y-m-d H:i:s', time())."', '".date('Y-m-d H:i:s', time())."', '1')");

Query#2-一重引用符で名前を入力すると失敗します(つまり、O'Brien)

$query = mysql_query("INSERT INTO message_log 
(order_id, timestamp, message_type, email_from, supplier_id, primary_contact, secondary_contact, subject, message_content, status) 
VALUES 
('$order_id', '".date('Y-m-d H:i:s', time())."', '$email', '$from', '$row->supplier_id', '$row->primary_email' ,'$row->secondary_email', '$subject', '$message_content', '1')");
171
sjw

これらの各文字列(両方のスニペットで)をmysql_real_escape_string()でエスケープする必要があります。

http://us3.php.net/mysql-real-escape-string

2つのクエリの動作が異なる理由は、magic_quotes_gpcがオンになっているためです(これは悪い考えです)。これは、$ _ GET、$ _ POST、および$ _COOKIESから収集された文字列がエスケープされることを意味します(つまり、"O'Brien" -> "O\'Brien")。

データを保存してから再度取得すると、データベースから返される文字列はnot自動的にエスケープされます。 "O'Brien"が返されます。したがって、mysql_real_escape_string()を介して渡す必要があります。

125
awgy

2015年にこのソリューションを見つけて前進する人のために...

mysql_real_escape_string()関数は、PHP 5.5.0で非推奨になりました。

参照: php.net

警告

この拡張機能はPHP 5.5.0で非推奨になり、将来削除される予定です。代わりに、MySQLiまたはPDO_MySQL拡張機能を使用する必要があります。 MySQL:APIガイドと関連するFAQの選択も参照してください。この機能の代替手段は次のとおりです。

mysqli_real_escape_string()

PDO::quote()

50
Amy McCrobie

弦の中で戦うものがいくつかあります。

  • 適切なMySQLクォートの欠如(mysql_real_escape_string()
  • 潜在的な自動「マジッククォート」-gpc_magic_quotes設定を確認してください
  • 埋め込み文字列変数。つまり、PHPが変数を正しく検出する方法を知る必要があります。

単一引用符で囲まれた値が、最初のクエリのパラメーターに存在しない可能性もあります。あなたの例は結局のところ適切な名前であり、2番目のクエリだけが名前を扱っているようです。

14
staticsan

PHPとMySQLの両方をエスケープする以下を実行できます。

<?
$text = '<a href="javascript:window.open(\\\'http://www.google.com\\\');"></a>';
?> 

これはMySQLを次のように反映します

<a href="javascript:window.open('http://www.google.com');"></a>

それはどのように機能しますか?

PHPとMySQLアポストロフィの両方がバックスラッシュとアポストロフィでエスケープできることを知っています。

\'

PHPを使用してMySQLに挿入しているため、PHPを使用してバックスラッシュをMySQLに書き込み、それもエスケープできるようにします。そのため、バックスラッシュとバックスラッシュのPHPエスケープ文字とバックスラッシュとアポストロフィを使用して、これを実現します。

\\\'
14
Error404

デバッグを支援するには、このようなことをする必要があります

$sql = "insert into blah blah....";
echo $sql;

おそらく、作業中のクエリで一重引用符がバックスラッシュでエスケープされていることに気付くでしょう。これは、phpによってmagic_quotes_gpc設定を介して自動的に行われたか、コードの他の部分で自分で行った可能性があります(addslashesとstripslashesは検索する関数です)。

http://php.net/manual/en/security.magicquotes.php を参照してください

14
goat

"mysql_real_escape_string(trim($ val))"内の変数ORデータを渡すだけです

ここで、$ val =困っているデータ。

10
user3272729