PHPによるファイルのアップロード
今度はWebフォームの「INPUT TYPE=FILE」タグによるファイルのアップロードリクエストを、 PHPで受け取るサンプルを作ってみます。 ここではアップロードされたファイルを保管するのではなく、 内容をCSVファイルとして読み取る処理を行っています。

<!DOCTYPE HTML>
<html lang="ja">
<body>
<?php
error_reporting(E_ALL);

function showData($data){
    $rows = explode("\n", $data);
    print "------<br>";
    $rn = 1;
    foreach($rows as $rowdata){
        $rowdata = trim($rowdata); // 行頭・行末の空白文字を削除
        if(empty($rowdata)){ continue; } // 空行を読み飛ばす

        $data = explode(",", $rowdata);
        if(count($data) < 4) {
            print $rn . "行目は無効です。(フィールド数不足)<br>";
        } else {
            // 今はデータを表示しているだけ(日本語文字コード考慮なし)
            // 本当は、ここでDB更新処理などを行う
            print $data[0] . "|" . $data[1] . "|" . $data[2] . "|" . $data[3] . "<br>";
        }
        $rn++;
    }
    print "------<br>";
}

if(empty($_FILES["datafilename"]["tmp_name"])){
?>
  <h1>ファイルのアップロード</h1>

<p>
1行に4個以上のフィールドを持つCSVファイルを選択してください。
</p>

  <form action="<?= $_SERVER['PHP_SELF'] ?>" enctype="multipart/form-data" method="POST">
  ファイル:<br/><input type="file" name="datafilename"><br/>
  <input type="submit" value="送信">
  </form>
<?php
} else {
    $tmpfilename = $_FILES["datafilename"]["tmp_name"];

    if(is_uploaded_file($tmpfilename)){
        $name  = $_FILES["datafilename"]["name"];
        $type  = $_FILES["datafilename"]["type"];
        $error = $_FILES["datafilename"]["error"];
        if(! preg_match('/\\.csv$/i', $name)){
            print "エラー:CSVファイルを選択してください。<br>";
        }

        $size = $_FILES["datafilename"]["size"];
        $data = file_get_contents($tmpfilename);
?>
  <h1>アップロードされたファイルの内容:</h1>
    クライアントPC上のファイル名:<?= $name ?><br>
    ファイルタイプ(mime):<?= $type ?><br>
    ファイルサイズ:<?= $size ?><br>
    エラーコード:<?= $error ?><br>
    <font color="#600000"><pre><?= showData($data) ?></pre></font><br>
    <a href="<?= $_SERVER['PHP_SELF'] ?>">戻る</a><br>
<?php
    } else {
        print "エラー:アップロードされたファイルではありません。<br>";
    }
}
?>
</body></html>

アップロードされたファイルは、まずサーバ機上の /tmp などの位置に一時ファイルとして保存された状態で、 PHPによる応答処理が開始されます。このとき作られた一時ファイル名は、

$_FILES["datafilename"]["tmp_name"]

で参照できます。ここで「datafilename」 の部分は「INPUT TYPE=FILE」タグでNAME=属性に指定した値に適当に置き換えてください。 「tmp_name」は固定です。 同様に、

$_FILES["datafilename"]["size"]

はこの一時ファイルのバイト数が、

$_FILES["datafilename"]["name"]

はアップロードされたファイルの 「クライアント機上でのファイル名」が格納されています。 一時ファイルのバイト数が極端に大きかったり小さかったりしたら処理の対象外にする、 などの安全策が充分考えられますね。 また、

$_FILES["datafilename"]["error"]

はPHP 4.2.2から追加された変数で、アップロードが正常に行われた場合には0、 そうでなければそれを示すエラーコードが格納されています。

それで、安全上の理由から、 一時ファイル名が確かにブラウザからアップロードされた一時ファイルのものであるかどうかを確認するために、 組み込み関数 is_uploaded_file が用意されているので、これが真を返した場合のみ処理を行うようにとのことで、 ここではこれに従ってみました。

Open Source Web Architecture Top

(first uploaded 2002/01/02 last updated 2018/10/27, URANO398 - KQ TAURA)