0Pricing
PHP Academy · レッスン

ユーザー入力のサニタイズ

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');
// &lt;script&gt;alert(1)&lt;/script&gt;

htmlentities() と htmlspecialchars() の違い

どちらも HTML をエスケープしますが、htmlentities は該当するすべての文字を変換するのに対し、htmlspecialchars は最も危険な 5 つの文字だけを変換します。

<?php
$str = '<b>caf&eacute;</b> & "bar"';

// htmlspecialchars: only & < > ' "
echo htmlspecialchars($str, ENT_QUOTES, 'UTF-8');

// htmlentities: also converts é → &eacute;
echo htmlentities($str, ENT_QUOTES, 'UTF-8');
// Prefer htmlspecialchars — htmlentities can break UTF-8

filter_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_.jpg

IDの整数キャスト

数値 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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. GETとPOST:使い分け
  2. スーパーグローバルでフォームデータを読み取る
  3. 入力値のバリデーション手法
  4. ユーザー入力のサニタイズ
← PHP Academyに戻る