緊急PHP2Shell(CVE-2026-109618 / 109619)公表から1日/PHP 8.1 以前は修正版なし今すぐ診断
  1. ホーム
  2. ブログ
  3. PHP のセキュリティ

PHP の PDO の使い方|プリペアドステートメントで SQL インジェクションを防ぐ

公開
著者
編集部

PHP でデータベースを使うときの基本。PDO のつなぎ方、プリペアドステートメントで SQL インジェクションを防ぐ方法、間違えやすい所をまとめた。

SQL インジェクションは、入力された文字で SQL を書き換えられ、データを抜き取られたり消されたりする弱点。PHP では PDO のプリペアドステートメントを使えば防げる。

この記事の要点
  • 入力された値を、SQL の文字列に直接つなげない
  • PDO の prepare() と、値の受け渡し(execute() の引数)を使う
  • PDO::ATTR_EMULATE_PREPARES を false にすると、より安全
  • 古い mysql_* 関数は PHP 7.0 で削除されている

危ない書き方と安全な書き方

書き方
危ないSQL の文字列に $_GET['id'] などを直接つなげる
安全prepare('SELECT * FROM users WHERE id = ?') のあと execute([$id])
安全名前で渡す:WHERE email = :email と execute(['email' => $email])

つなぐときの設定

  • エラーのときに例外を投げる:PDO::ATTR_ERRMODE を PDO::ERRMODE_EXCEPTION(PHP 8.0 から既定)
  • 本物のプリペアドステートメントを使う:PDO::ATTR_EMULATE_PREPARES を false
  • 文字コードは接続の文字列で charset=utf8mb4 を指定する

間違えやすい所

  • 並べ替えの列名(ORDER BY)やテーブル名は、値として渡せない。許す名前の一覧から選ぶ
  • IN (...) は、値の数だけ ? を並べる
  • 検索の LIKE も、値として渡す(% は値の側に付ける)
古いプログラムの移行と一緒に

mysql_* 関数を使った古いプログラムは、PHP 7.0 以降で動かない。PHP を上げるときに、PDO へ書き換えるのがちょうどよい。

よくある質問

エスケープの関数を使えば、プリペアドステートメントは要りませんか?

プリペアドステートメントを使ってください。
エスケープは使い方を間違えやすく、漏れが出やすいです。

mysqli でもプリペアドステートメントは使えますか?

使えます。
考え方は PDO と同じで、値を SQL の文字列につなげずに渡します。

無料ツールPHP2Shell 脆弱性チェッカーPHP のバージョンとサーバー会社を選ぶだけで、危険度と今やることが分かります。

参考にした情報

この記事の情報

2026年10月22日時点の公開情報にもとづく。画面や手順は変わることがあるので、最新は各社の公式のマニュアルを確認すること。

URL を入れるだけで、PHP2Shell の危険度と今やることが分かる。移行の相談もできる。

無料で診断する

この記事の著者

編集部