質問: 質問失礼します。 現在PHPを勉強しておりPDOというものを知りました。 いろいろと調べましたが内容が難しく私の解釈があっているのか、 コードの書き方はあっているのか教えていただきたく質問させていただきました。 下記はデータベースに商品を登録するシンプルなものです。 インジェクション対策を行ったほうが良い、PDOがあるとお聞きしてPDOを使用してコードを書いてみました。 動作としては意図する動きをするのですがこれではインジェクション対策になっていないでしょうか? PDO::PARAM_STRを使用していれば htmlspecialchars~ENT_QUOTES UTF-8は必要ないのでしょうか? htmlspecialchars~ENT_QUOTES UTF-8はユーザーの入力した値を画面に表示する際にだけ使用しておけばよかったかな? いろいろと突っ込みどころが多いと思いますがよろしくお願いします。 下記がコードになります。 dbconnect.php ``` false)); } catch (PDOException $e) { exit('データベース接続失敗。'.$e->getMessage()); } ?> ``` ``` prepare("INSERT INTO menu (id,kind,name,price,remarks) VALUES (:id, :kind, :name, :price, :remarks)"); $stmt -> bindValue(':id', $id, PDO::PARAM_STR); $stmt -> bindValue(':kind', $kind, PDO::PARAM_STR); $stmt -> bindValue(':name', $name, PDO::PARAM_STR); $stmt -> bindValue(':price', $price, PDO::PARAM_STR); $stmt -> bindValue(':remarks', $remarks, PDO::PARAM_STR); $stmt -> execute(); ?> ```
回答: > > htmlspecialchars~ENT_QUOTES UTF-8はユーザーの入力した値を画面に表示する際にだけ使用しておけばよかったかな? > > > はい、そのとおりです。`htmlspecialchars`は、**HTMLとして**特殊な意味を持つ文字をエスケープする関数ですので、HTML出力以外のところで使うと余計なエスケープになるだけです。エスケープ前のデータとエスケープ後のデータが混在すると混乱しか産まないので、エスケープは**出力の直前に**行いましょう。 そして、MySQLには名前付きのプレースホルダ機能がありませんので、`(PDO::ATTR_EMULATE_PREPARES => false`としても、実は**PDOレベルで変換が入っています**。 あと、`$_POST`を直接使うと、値が来ていない時に`E_NOTICE`となります。`filter_input`などを活用しましょう。