0Pricing
PHP Academy · レッスン

ファイルアップロードの処理

_FILESスーパーグローバルを使ってアップロードされたファイルを安全に処理します

「ファイルアップロードの処理」はCoddyKit上の無料PHP Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPHP Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 PHP Academyコースには全4レッスンが含まれています。

PHPファイルアップロードの概要

PHP は $_FILES スーパーグローバルを通じてファイルアップロードを処理します。フォームでは method="POST" と enctype="multipart/form-data" を使用する必要があります。

HTMLアップロードフォーム

単一および複数のファイルをアップロードするための HTML フォームの設定です。

<!-- Single file -->
<form method="POST" action="upload.php"
      enctype="multipart/form-data">
    <input type="file" name="document">
    <button>Upload</button>
</form>

<!-- Multiple files -->
<form method="POST" enctype="multipart/form-data">
    <input type="file" name="photos[]" multiple>
    <button>Upload All</button>
</form>

$_FILESの構造

アップロードされた各ファイルには、$_FILES 内に 5 つのエントリがあります。

<?php
$file = $_FILES['document'];

echo $file['name'];      // original name: report.pdf
echo $file['type'];      // browser-reported MIME: application/pdf
echo $file['tmp_name'];  // server temp path: /tmp/phpXXXXXX
echo $file['error'];     // error code: 0 = UPLOAD_ERR_OK
echo $file['size'];      // file size in bytes

アップロードエラーコード

処理する前に、必ず $file['error'] を確認します。

<?php
$errorMessages = [
    UPLOAD_ERR_INI_SIZE   => 'Exceeds upload_max_filesize in php.ini',
    UPLOAD_ERR_FORM_SIZE  => 'Exceeds MAX_FILE_SIZE in form',
    UPLOAD_ERR_PARTIAL    => 'Only partially uploaded',
    UPLOAD_ERR_NO_FILE    => 'No file uploaded',
    UPLOAD_ERR_NO_TMP_DIR => 'Missing temp folder',
    UPLOAD_ERR_CANT_WRITE => 'Failed to write to disk',
    UPLOAD_ERR_EXTENSION  => 'PHP extension stopped upload',
];

$err = $_FILES['doc']['error'];
if ($err !== UPLOAD_ERR_OK) {
    die($errorMessages[$err] ?? 'Unknown error');
}

ファイルの種類を安全に検証する

ブラウザーから提供された MIME タイプを決して信用せず、実際のファイル内容で検証します。

<?php
$tmp  = $_FILES['image']['tmp_name'];
$allowed = ['image/jpeg', 'image/png', 'image/webp'];

// Check real MIME type from file content
$realMime = mime_content_type($tmp);

if (!in_array($realMime, $allowed)) {
    die('Invalid file type: ' . $realMime);
}

ファイルサイズの検証

HTML フォームに MAX_FILE_SIZE の hidden フィールドがある場合でも、サーバー側でサイズ制限を適用します。

<?php
$maxBytes = 5 * 1024 * 1024;  // 5MB
$size     = $_FILES['video']['size'];

if ($size > $maxBytes) {
    $mb = round($size / 1024 / 1024, 2);
    die("File too large: {$mb}MB (max 5MB)");
}

is_uploaded_file と move_uploaded_file

ファイルが HTTP アップロードによって送信されたことを確認し、安全に移動するために、必ずこの 2 つの関数を使用します。

<?php
$tmp  = $_FILES['photo']['tmp_name'];
$dest = '/var/www/uploads/' . basename($_FILES['photo']['name']);

if (!is_uploaded_file($tmp)) {
    die('Not an uploaded file — possible attack');
}

if (!move_uploaded_file($tmp, $dest)) {
    die('Failed to move uploaded file');
}

echo 'Upload saved to: ' . $dest;

安全なファイル名の生成

ディレクトリトラバーサル攻撃や上書き攻撃を防ぐため、ランダムなファイル名を生成します。

<?php
$originalName = $_FILES['doc']['name'];
$ext          = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));

$allowedExts = ['jpg', 'jpeg', 'png', 'pdf'];
if (!in_array($ext, $allowedExts)) {
    die('File type not allowed');
}

$safeName = bin2hex(random_bytes(16)) . '.' . $ext;
$dest     = '/var/www/uploads/' . $safeName;

move_uploaded_file($_FILES['doc']['tmp_name'], $dest);

複数ファイルのアップロード処理

name="photos[]" を使用すると、$_FILES には配列が格納されます。これらを反復処理します。

<?php
$files = $_FILES['photos'];
$count = count($files['name']);

for ($i = 0; $i < $count; $i++) {
    if ($files['error'][$i] !== UPLOAD_ERR_OK) continue;
    
    $tmp  = $files['tmp_name'][$i];
    $ext  = pathinfo($files['name'][$i], PATHINFO_EXTENSION);
    $dest = '/uploads/' . uniqid() . '.' . strtolower($ext);
    
    move_uploaded_file($tmp, $dest);
    echo "Saved: $dest" . PHP_EOL;
}

php.ini のアップロード設定

ファイルアップロードに影響する主な php.ini ディレクティブ:

  • file_uploads = On — アップロードを有効にする
  • upload_max_filesize = 8M — 1 ファイルあたりの最大サイズ
  • post_max_size = 32M — POST 本体の最大サイズ(upload_max_filesize より大きくする必要がある)
  • max_file_uploads = 20 — 1 リクエストあたりの最大ファイル数

アップロード後の画像サイズ変更

GD ライブラリを使って、アップロード後に画像のサイズを変更します。

<?php
function resizeImage(string $src, string $dst, int $maxW): void {
    [$w, $h, $type] = getimagesize($src);
    $ratio   = $maxW / $w;
    $newH    = (int) ($h * $ratio);
    $srcImg  = imagecreatefromjpeg($src);
    $dstImg  = imagecreatetruecolor($maxW, $newH);
    imagecopyresampled($dstImg, $srcImg, 0,0,0,0, $maxW, $newH, $w, $h);
    imagejpeg($dstImg, $dst, 90);
    imagedestroy($srcImg);
    imagedestroy($dstImg);
}

確認問題

アップロードされたファイルを最終的な保存先へ安全に移動するために必要な PHP 関数はどれですか。

まとめ: ファイルアップロード

アップロード処理のチェックリスト:

  • フォームでは method=POST enctype=multipart/form-data を使用する必要がある
  • $_FILES['field']['error'] === UPLOAD_ERR_OK を確認する
  • mime_content_type() で実際の MIME タイプを検証する
  • サーバー側でファイルサイズを検証する
  • move_uploaded_file() を使用し、rename/copy は使用しない
  • 競合を防ぐため、ランダムなファイル名を生成する

よくある質問

「ファイルアップロードの処理」レッスンは無料ですか?

はい。「ファイルアップロードの処理」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、PHP Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 PHP Academyコースには全4レッスンが含まれています。

「ファイルアップロードの処理」で何を学びますか?

_FILESスーパーグローバルを使ってアップロードされたファイルを安全に処理します ブラウザで直接実行するハンズオンコードでPHP Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

PHP Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPHP Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「ファイルアップロードの処理」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPHP Academyレッスンでコードを書いて実行できますか?

はい。すべてのPHP Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

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

  1. PHPでファイルを読み込む
  2. ファイルへの書き込みと追記
  3. ディレクトリを操作する
  4. ファイルアップロードの処理
← PHP Academyに戻る