Uploader PHPでファイルをアップロード

2012.12.31 (月)

PHPすごいです。以前よりPerlばっかり使っていたのでこの度PHPではじめてアップローダーを作ってみたのだけど15分ぐらいでできてしまいました。
Webに特化したPHPなのでかなり簡単に作れるみたいです。
むしろアップロード専用の関数をすでに用意しているといった感じでそれらを組み合わせるといった感覚でしょうか。ちなみにPerlはアップローダーの関数を自分で作って自分で組み立てる…といった感覚です。

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta name="generator" content="omnioo" />
        <title>Uploader</title>
    </head>
    <body>
        <form action="upload.php" method="post" enctype="multipart/form-data">
            <input type="file" name="upload_file" size="30"><br>
            <input type="submit" value="UPLOAD">
        </form>
    </body>
</html>

かなり簡単です。びっくりしたのがPOST送信なんですね。勿論これだけじゃダメでエンコードのタイプでenctype=”multipart/form-data”を指定します。後はinputのtype指定でtype=”file”を設定してあげることです。それ以外は殆ど通常のテキスト送信と変わらないです。

<?php
    //アップロードファイルの保存(upload.php)
    if (is_uploaded_file($_FILES["upload_file"]["tmp_name"])) { # (*1)
    if (move_uploaded_file($_FILES["upload_file"]["tmp_name"], "files/" . $_FILES["upload_file"]["name"])) { # (*2)
        echo $_FILES["upload_file"]["name"] . " Success Upload.";
    } else {
        echo "can not upload !";
    }
} else {
    echo "failure !";
}
?>

POST送信されたファイルはname=”upload_file”の場合は、$_FILES(複数形なので注意)という配列に格納されます。($_POSTや$_GETと同じです。)しかし$_FILES[‘upload_file’]では取り出すことができなくて$_FILES[“upload_file”][“tmp_name”]で取り出します。これはテキストデータと違ってファイルオブジェクトは一時的に/tmpディレクトリ内に保存されるためです。(*1)これらのファイルデータをis_upload_fileであるかないかを確認します。ない場合はアップロードエラーとなります。
次にその一時保存したファイルデータを指定のディレクトリに移動します。その際に、

$_FILES["upload_file"]["tmp_name"] → $_FILES["upload_file"]["name"]
(/tmp/phpsrrxxxxx) → (<ファイル名>)

という風に移動と同時に元のファイル名に戻してあげます。これもどうやら定形らしい。(*2)
移動先はfilesというディレクトリをあらかじめ作っておき書き込み権限を与えておきます。filesディレクトリに保存(移動)されたファイルデータは自動的にパーミッション644になりますので大丈夫です。で、PHPの実行が終わった時点で/tmpファイル内のデータは消去されます。move_uploaded_file関数はシェルのmvです。しかしmove_uploaded_file関数はアップロードに最適化された関数なので、ここでは意味を考えないでそのまま使うのがよいです。
後は適当にifでもって制御すればよいです。根幹としてはファイルの保存ディレクトリを作成してあげてから、

move_uploaded_file ($_FILES["upload_file"]["tmp_name"], "files/" . $_FILES["upload_file"]["name"]);

だけでOKです。ああ、簡単。
アップロードした画像ファイルなどは、パーミッションが600で保存されていることがあります。サーバーの設定によってまちまちですので、表示したり何なりという必要がある場合はchmod(“<アップロードしたファイルパス>”, 0644);とかでもってパーミッション変更しておく必要があります。その目的によってパーミッションを確認及び調整してください。