PHPでファイル・アップローダを作る

(1/1)
今回は、Web経由で任意のファイルを指定ディレクトリに登録するファイル・アップローダを作ってみることにする。

サンプル・プログラム

サンプル・プログラムの解説:準備

アップロード用パス名は固定で、変数 $path_up に代入しておく。これは、各自の環境に合わせて変更してほしい。

0010: $path_up = "./upload/";        //アップロード用パス

プログラムは、アップロードするファイルを指定する部分と、アップロード処理の実施と結果を表示する部分の 2 つに分かれる。$_FILES 変数に渡された内容によって、2 つのプログラムを切り替えることができるようにしてある。

0046: if (isset($_FILES["upload"]) == FALSE) {

サンプル・プログラムの解説:アップロード・ファイル指定

まず、アップロードするファイルの指定だが、これは HTML の <input type="file"> タグを利用する。ここで注意しなければならないのは、バイナリ・ファイルを扱うこともあるので、<form> タグで enctype="multipart/form-data" としてやらなければならない。
あとは、POST メソッドでファイルがアップロードされる。

0049: <form name="add" enctype="multipart/form-data" method="post" action="$myself">
0050: ファイル:
0051: <input name="upload" type="file" size="50" />
0052: <input value="登録" type="submit" />
0053: </form>

この画面では、登録されているファイル一覧も表示するようにした。

0058: $filenames = array();
0059: $n = get_filenames($path_up$filenames);
0060: if ($n == 0) {
0061:     echo "<<ファイルは登録されていません>>";
0062: else {
0063:     echo "<table border=\"0\">\n";
0064:     echo "<caption>登録ファイル一覧</caption>\n";
0065:     foreach($filenames as $key=>$val) {
0066:         echo "<tr>\n";
0067:         echo "<td><a href=\"" . $path_up . $val . "\" target=\"_blank\">$val</a></td>\n";
0068:         echo "</tr>\n";
0069:     }
0070:     echo "</table>\n";
0071: }

この画面では、登録されているファイル一覧も表示するようにした。
変数 $path_up にあるファイル名一覧を取得するユーザー関数 get_filenames を用意した。
取得したファイル名は、配列変数 $filenames に代入する。引き数に & を付けると、参照による代入を行うことを意味する。
PHP では、ディレクトリを扱うための  opendir  関数が用意されている。これを  fopen  関数のように使い、個々のファイル名を  readdir  関数で読み出していくことができる。
isdir 関数を使い、取得したファイル名がディレクトリか判断する。ファイル名がディレクトリであれば、配列には格納しない。

0014: /**
0015:  * 指定パスのファイル名一覧を取得する
0016:  * @param string $path ターゲット・パス
0017:  * @param array  $filenames ファイル名を格納する配列
0018:  * @return int 取得したファイル数
0019: */
0020: function get_filenames($path, &$filenames) {
0021:     $n = 0;
0022:     if ($dir = opendir($path)) {
0023:         while ($fname = readdir($dir)) {
0024:             if (is_dir($path . $fname))      continue;
0025:             $filenames[$n] = $fname;
0026:             $n++;
0027:         }
0028:     }
0029:     return $n;
0030: }

サンプル・プログラムの解説:ファイル登録実行

次に、ファイルの登録実行である。
アップロードした元ファイル名が $_FILES["upload"]["name"] に代入されているので(元のパス名は含まれない)、これが空でないかどうかをチェックする。空でなければ、登録先のフルネームを変数 $file_name に代入する。
もし $file_name が存在していたら、登録処理は中止する。
アップロードされたファイルそのものは、一時ファイル $_FILES["upload"]["tmp_name"] に格納されている。これを $file_name へコピーしてやる。

0079: if (! empty($_FILES["upload"]["name"])) {
0080:     $file_name = $path_up . $_FILES["upload"]["name"];
0081:     if (! file_exists($file_name)) {
0082:         $ret = copy($_FILES["upload"]["tmp_name"]$file_name);
0083:         echo "" . $_FILES["upload"]["name"];
0084:         if ($ret)   echo " の登録に成功<br />\n";
0085:         else        echo " の登録に失敗<br />\n";
0086:     } else {
0087:         echo "> 同名ファイルが存在するため登録中止<br />\n";
0088:     }
0089: }

登録ページへ「戻る」ボタンを用意しておいた。

0092: <form method="post" action="$myself">
0093: <input type="submit" value="戻る" />
0094: </form>

さらに、アップロード時にパスワードを登録させ、パスワードが合致する場合には削除できるようにする機能や、アップロードするファイル拡張子を限定するような機能を追加すれば、画像掲示板に発展させることもできるだろう。
なお、今回のファイル・アップローダは、日本語ファイル名を扱うことを想定して、 mb_internal_encoding  関数で文字コードを指定している。
この部分は OS のファイルシステムに依存することがあるようだ。一般的には Shift JIS 指定でよいだろう。
Windows では、UTF-16UTF-32 でも正常に動作するが、UTF-8 では動作しなかった。

0012: mb_internal_encoding('SJIS');

(この項おわり)
header