ユーザー入力のサニタイズ
htmlspecialcharsとfilter_inputを使って危険な文字を取り除きます
「ユーザー入力のサニタイズ」はCoddyKit上の無料PHP Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPHP Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 PHP Academyコースには全4レッスンが含まれています。
サニタイズとバリデーション
バリデーションは、データが要件を満たしているかを確認し、満たしていなければ拒否します。
サニタイズは、危険な文字を削除またはエンコードしてデータを安全に使用できるようにします。
どちらも必要です。まずバリデーションを行い、その後、出力用にサニタイズします。
HTML出力のための htmlspecialchars()
XSS を防ぐため、HTML に挿入する前に必ず出力をエスケープします。
<?php
$name = '<script>alert(1)</script>';
// Dangerous — executes script:
// echo $name;
// Safe:
echo htmlspecialchars($name, ENT_QUOTES | ENT_HTML5, 'UTF-8');
// <script>alert(1)</script>htmlentities() と htmlspecialchars() の違い
どちらも HTML をエスケープしますが、htmlentities は該当するすべての文字を変換するのに対し、htmlspecialchars は最も危険な 5 つの文字だけを変換します。
<?php
$str = '<b>café</b> & "bar"';
// htmlspecialchars: only & < > ' "
echo htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
// htmlentities: also converts é → é
echo htmlentities($str, ENT_QUOTES, 'UTF-8');
// Prefer htmlspecialchars — htmlentities can break UTF-8filter_var の FILTER_SANITIZE_*
filter_var のサニタイズモードは危険なコンテンツを除去します。
<?php
$rawEmail = 'user(bad)@exam<ple.com';
$clean = filter_var($rawEmail, FILTER_SANITIZE_EMAIL);
echo $clean; // user@example.com
$rawUrl = 'http://exa mple.com/pa th?q=foo bar';
$cleanUrl = filter_var($rawUrl, FILTER_SANITIZE_URL);
echo $cleanUrl;strip_tags()
文字列から HTML タグを削除します。必要に応じて、許可するタグを残すこともできます。
<?php
$input = '<p>Hello <b>World</b> <script>alert(1)</script></p>';
// Remove all tags:
echo strip_tags($input);
// Hello World alert(1)
// Keep only <b> and <i>:
echo strip_tags($input, '<b><i>');
// Hello <b>World</b>SQL向けのサニタイズ
文字列関数で SQL をサニタイズしてはいけません。必ずプリペアドステートメントを使用してください。正しい方法は次のとおりです。
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
// WRONG — even with addslashes this is dangerous:
// $sql = "SELECT * FROM users WHERE email = '" . addslashes($email) . "'";
// CORRECT — prepared statement:
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute([':email' => $email]);
$user = $stmt->fetch();addslashes() とプリペアドステートメントの違い
addslashes() はバックスラッシュと引用符をエスケープしますが、SQL に対して安全な方法ではありません。代わりに PDO のプリペアドステートメントを使用してください。addslashes() は、JavaScript 文字列の生成など、SQL 以外の用途では役立つ場合があります。
<?php
// For embedding PHP string into JavaScript (still escape via json_encode):
$jsData = json_encode(['name' => $userInput], JSON_HEX_QUOT);
echo "<script>var data = $jsData;</script>";ファイル名のサニタイズ
アップロードされたファイル名から危険な文字を除去します。
<?php
function sanitizeFilename(string $name): string {
// Remove path traversal chars and other dangerous ones
$name = basename($name); // strip any path
$name = preg_replace('/[^a-zA-Z0-9._-]/', '_', $name); // only safe chars
$name = preg_replace('/_{2,}/', '_', $name); // collapse underscores
return strtolower($name);
}
echo sanitizeFilename('../../../etc/passwd'); // etc_passwd
echo sanitizeFilename('My Photo (1).JPG'); // my_photo_1_.jpgIDの整数キャスト
数値 ID に対する最も簡単なサニタイズ方法です。int にキャストすると、数値以外のコンテンツが破棄されます。
<?php
// Never do this:
$id = $_GET['id'];
$sql = "SELECT * FROM posts WHERE id = $id";
// Safe approach 1: cast to int
$id = (int) ($_GET['id'] ?? 0);
if ($id <= 0) die('Invalid ID');
// Safe approach 2: validate
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if (!$id) die('Invalid ID');出力コンテキストが重要
出力するコンテキストごとに、適切なエスケープ方法が異なります。
- HTML 本文 →
htmlspecialchars() - HTML 属性 →
htmlspecialchars(ENT_QUOTES) - JSON/JavaScript →
json_encode() - URL パラメーター →
urlencode() - SQL → プリペアドステートメント
urlencode と rawurlencode
URL で使用する値をエンコードします。
<?php
$search = 'hello world & PHP';
echo urlencode($search);
// hello+world+%26+PHP (+ for spaces)
echo rawurlencode($search);
// hello%20world%20%26%20PHP (RFC 3986 — use in paths)
$url = 'https://example.com/search?q=' . urlencode($search);
echo $url;確認問題
データベースクエリでユーザー入力を使用するとき、SQL インジェクションを防ぐ正しい方法はどの関数ですか。
まとめ: 入力値のサニタイズ
サニタイズのルール:
- HTML 出力 →
htmlspecialchars(ENT_QUOTES, 'UTF-8') - SQL → プリペアドステートメントを使用し、文字列のエスケープは決して使わない
- URL →
urlencode()またはrawurlencode() - ファイル名 → 正規表現で除去し、
basename()を使用する - 整数 ID →
(int)でキャストする - タグ → 許可するタグのフィルタリングには
strip_tags()を使用する
よくある質問
「ユーザー入力のサニタイズ」レッスンは無料ですか?
はい。「ユーザー入力のサニタイズ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、PHP Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 PHP Academyコースには全4レッスンが含まれています。
「ユーザー入力のサニタイズ」で何を学びますか?
htmlspecialcharsとfilter_inputを使って危険な文字を取り除きます ブラウザで直接実行するハンズオンコードでPHP Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
PHP Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのPHP Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「ユーザー入力のサニタイズ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このPHP Academyレッスンでコードを書いて実行できますか?
はい。すべてのPHP Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- GETとPOST:使い分け
- スーパーグローバルでフォームデータを読み取る
- 入力値のバリデーション手法
- ユーザー入力のサニタイズ