プログラミング勉強中の者です。 分からないコードがあったため質問します。 phpにてSQLクエリを作成していたのですが、理解できない部分があります。
プログラミング勉強中の者です。 分からないコードがあったため質問します。 phpにてSQLクエリを作成していたのですが、理解できない部分があります。 ウェブサイトのログイン機能を作成しているところなのですが、//SQLクエリを作成のコードの 'SELECT * FROM users WHERE email = "' . $email .'"';のクォーテーションやドットの意味が分かりません。クエリ文自体の意味は分かるのですが、なぜ$emailの両端に「.」、その外側に「’」、更にその外側に「”」が付いているのかが分からないです。 'SELECTの「'」と "' . $email .'"'の一番右の「’」は$queryのテキストを囲む「’」と考えて良いのでしょうか? また、コメントアウトの「外部からのリクエストは何が入ってくるか分からないので、必ず、エスケープしたものをクオートで囲む」というのは、なぜですか?real_escape_string関数でエスケープ処理したのならSQLインジェクション対策はできているのでは?と考えてしまいます。 ------------------------------------------- // 入力値をエスケープ $email = $mysqli->real_escape_string($email); // SQLクエリを作成 // 外部からのリクエストは何が入ってくるか分からないので、必ず、エスケープしたものをクオートで囲む $query = 'SELECT * FROM users WHERE email = "' . $email . '"'; // クエリ実行 --------------------------------------------- 長々と分かりにくい文章でしたが、どなたかご教授お願いします。
ベストアンサー
.(ドット)は文字列の結合演算子です(文字列を繋ぎます)。 https://www.php.net/manual/ja/language.operators.string.php 提示されている $query = 'SELECT * FROM users WHERE email = "' . $email .'"'; は、$email が(たとえば)account@example.com という文字列だったときに、$query に SELECT * FROM users WHERE email = "account@example.com" という文字列を作りたいのでしょうね。 MySQLの場合は単引用符で括る方が確実なので(ANSI_QUOTES SQLモードの設定に左右されない) $query = sprintf("SELECT * FROM users WHERE email = '%s', $email); とした方がいいでしょう。 https://dev.mysql.com/doc/refman/8.0/ja/string-literals.html なお、mysqliを使うよりもPDOを推奨します。また個別にエスケープするよりも、パラメータマーカを含んだSQL文を prepare に渡して、execute する方が楽だと思います。 (PDOの例) // $email をエスケープしなくてもいい $stmt = $pdo->prepare('SELECT * FROM users WHERE email=?'); $stmt->execute([$email]); mysqliでも prepare/execute でエスケープをシステムに任せることもできますが、PDOに比べて多少面倒な記述になります(汗
おっと、失礼 × $query = sprintf("SELECT * FROM users WHERE email = '%s', $email); 〇 $query = sprintf("SELECT * FROM users WHERE email = '%s'", $email); ですね(汗 再度書きますが、prepare で(パラメータマーカを)渡すなら文字列部分を単引用符で括らなくていいので、それだけでもSQL文を組み立てやすいです(なので基本的に prepare/execute を推奨)。
質問者からのお礼コメント
分かりやすくて、とても勉強になりました。 ベストアンサーに選ばせて頂きます。
お礼日時:7/5 21:34