Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

PHP辞典

  1. トップページ
  2. PHP辞典
  3. move_uploaded_file() / is_uploaded_file()

move_uploaded_file() / is_uploaded_file()対応: PHP 4(2000)

HTTPでアップロードされたファイルを安全に処理します。アップロードの正当性を検証し、指定したディレクトリにファイルを移動させます。

構文
// アップロードされたファイルを指定先に移動します。
move_uploaded_file($from, $to);

// ファイルがHTTPアップロードされたものかを検証します。
is_uploaded_file($filename);

// アップロードファイルの情報はスーパーグローバル変数で取得します。
$_FILES["フィールド名"]["name"];     // 元のファイル名
$_FILES["フィールド名"]["type"];     // MIMEタイプ
$_FILES["フィールド名"]["tmp_name"]; // サーバー上の一時ファイルパス
$_FILES["フィールド名"]["error"];    // エラーコード
$_FILES["フィールド名"]["size"];     // ファイルサイズ(バイト)
関数一覧
関数概要
move_uploaded_file($from, $to)アップロードされた一時ファイルを移動先に移します。内部で『is_uploaded_file()』の検証も行われるため、直接 『rename()』や『copy()』を使うより安全です。
is_uploaded_file($filename)指定されたファイルがHTTPのPOSTでアップロードされたものかを検証します。偽装されたファイルパスを検出するセキュリティ関数です。
$_FILESアップロードされたファイルの情報を格納するスーパーグローバル変数です。HTMLフォームの input type="file" の name 属性をキーとして、ファイル名・サイズ・一時パスなどにアクセスできます。
$_FILES のエラーコード
定数概要
UPLOAD_ERR_OK0エラーなし。アップロード成功です。
UPLOAD_ERR_INI_SIZE1php.ini の upload_max_filesize を超過しています。
UPLOAD_ERR_FORM_SIZE2HTMLフォームの MAX_FILE_SIZE を超過しています。
UPLOAD_ERR_PARTIAL3ファイルが部分的にしかアップロードされませんでした。
UPLOAD_ERR_NO_FILE4ファイルが選択されていません。
UPLOAD_ERR_NO_TMP_DIR6一時フォルダが見つかりません。
UPLOAD_ERR_CANT_WRITE7ディスクへの書き込みに失敗しました。
サンプルコード
<?php
// 基本的なファイルアップロード処理
if ($_FILES["photo"]["error"] === UPLOAD_ERR_OK) {
    $tmp_name = $_FILES["photo"]["tmp_name"];
    $upload_dir = "/var/www/html/uploads/";
    $filename = basename($_FILES["photo"]["name"]); // ディレクトリトラバーサル対策
    if (move_uploaded_file($tmp_name, $upload_dir . $filename)) {
        echo "アップロードが完了しました。";
    } else {
        echo "ファイルの移動に失敗しました。";
    }
} else {
    echo "アップロードエラーが発生しました。";
}

// is_uploaded_file() でアップロードの正当性を事前検証します。
if (is_uploaded_file($_FILES["document"]["tmp_name"])) {
    echo "正当なアップロードファイルです。";
} else {
    echo "不正なファイルが指定されました。";
}

// セキュリティを考慮したアップロード処理
$allowed_types = ["image/jpeg", "image/png", "image/gif"];
$max_size = 5 * 1024 * 1024; // 5MB

if ($_FILES["avatar"]["error"] !== UPLOAD_ERR_OK) {
    die("アップロードエラーが発生しました。");
}

// MIMEタイプを検証します。$_FILES["type"] はクライアントが送信するため信頼できません。
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $_FILES["avatar"]["tmp_name"]);
finfo_close($finfo);

if (!in_array($mime_type, $allowed_types, true)) {
    die("許可されていないファイル形式です。");
}

// ファイルサイズを検証します。
if ($_FILES["avatar"]["size"] > $max_size) {
    die("ファイルサイズが5MBを超えています。");
}

// ランダムなファイル名を生成して保存します。
$ext = pathinfo($_FILES["avatar"]["name"], PATHINFO_EXTENSION);
$new_name = bin2hex(random_bytes(16)) . "." . $ext;
$dest = "/var/www/html/uploads/" . $new_name;

if (move_uploaded_file($_FILES["avatar"]["tmp_name"], $dest)) {
    echo $new_name . " として保存しました。"; // ランダムなファイル名が出力されます。
}
概要

『move_uploaded_file()』はHTTPでアップロードされたファイルを安全に移動するための関数です。アップロードされたファイルの移動には必ず『move_uploaded_file()』を使用してください。内部でアップロードファイルの正当性を検証するため、『rename()』や『copy()』を直接使うよりも安全です。

ファイルアップロードのセキュリティ対策として、以下の点を必ず実装してください。元のファイル名をそのまま使用せず『basename()』でディレクトリトラバーサルを防ぐこと、『$_FILES["type"]』はクライアントが自由に設定できるため信頼せず『finfo_file()』でサーバー側でMIMEタイプを検証すること、ファイルサイズの上限を設けること、そして可能であればランダムなファイル名に変換して保存することが重要です。

HTMLフォームには enctype="multipart/form-data" の指定が必要です。php.ini の『upload_max_filesize』と『post_max_size』でサーバー側の上限も設定してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。