PHP ファイルのアップロード
PHP は、ブラウザからファイルのアップロードを 受けることができる。ファイルのアップロードはブラウザの機能なので、できないものも当然あるので注意。普通のものならたいていは大丈夫。
php.iniの編集
- 作業を始める前にphp.iniを編集してファイルの受信ができるようにしておく。Vineの場合、/usr/local/lib/php.ini。File Uploadの部分を書き換える。
;;;;;;;;;;;;;;;; ; File Uploads ; ;;;;;;;;;;;;;;;; ; Whether to allow HTTP file uploads. file_uploads = On <Onにする> ; Temporary directory for HTTP uploaded files (will use system default if not ; specified). upload_tmp_dir = /var/tmp/ <希望の場所を指定する、指定が無い場合はデフォルトが適用される> ; Maximum allowed size for uploaded files. upload_max_filesize = 2M <最大ファイルサイズを指定>
送信部分を作る(HTML)
<html> <head> <meta http-equiv="Content-Language" content="ja"><HTML> <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP"> <title>ファイル送信</title> </head> <body> <form method="POST" enctype="multipart/form-data" action="upload.php"> <p> 送信ファイル:<input type="file" name="userfile" size="40"> <input type="submit" value="送信" name="up"> </p> </form> </body> </html>
- 送信部分は基本的にこれだけ。apple社製のブラウザは、日本語を含むファイルは送信してくれないので注意。IEでもあまり古いバージョンはダメらしい。
受信部分を作る(PHP)
- 受信部分と言っても、以下のスクリプトが受信するわけではない。送られてきたファイルは、php.iniで指定された場所にphp***と勝手に名前を付けて一時的に保存される。この一時ファイルはセッションの終了とともに削除される。だからその前に拾い上げるプログラムを作ればよい。upload.php まずはこれだけ。
<?php print_r($_FILES); ?>
- 送られてきたファイルに関する情報は$_FILESの中に連想配列として格納されている。以上のスクリプトを実行すると
Array ( [userfile] => Array ( [name] => beer.jpg [type] => image/jpeg [tmp_name] => /var/tmp/php1mAL0z [error] => 0 [size] => 7171) )
と、$_FILESの中身を見ることができる。(実際は一行で表示される)もうすこしまともな表示にしてみる。名前、サイズ、MIMEタイプを表示。ファイルのアップロードとは直接関係がないが。。
<html> <head> <meta http-equiv="Content-Language" content="ja"> <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP"> <title>アップロードファイルの保存</title> </head> <body> <table border="1" width="270"> <tr> <td width="120" align="right">ファイル名:</td> <td width="150"><? echo $_FILES['userfile']['name']; ?></td> </tr> <tr> <td width="120" align="right">ファイルサイズ:</td> <td width="150"><? echo $_FILES['userfile']['size']; ?></td> </tr> <tr> <td width="120" align="right">MIMEタイプ:</td> <td width="150"><? echo $_FILES['userfile']['type']; ?></td> </tr> </table> </body> </html>
- upload.phpにもどる。ここで、/var/tmp/php1mAL0zは、PHPが作った一時ファイルの名前なので、これを消える前に助け出す。以下のようなプログラムを実行。
<?php //$uploadfileにアップロードしたファイルの場所と名前を記す $uploaddir = '/var/tmp/'; $uploadfile = $uploaddir. $_FILES['userfile']['name']; //アップロードしたファイルが存在する場合処理をする if(!is_uploaded_file($_FILES['userfile']['tmp_name'])) { echo "ファイルを保存できませんでした!"; exit; } else { //PHPが作ったテンポラリファイルを$uploadfileにコピーする copy($_FILES['userfile']['tmp_name'],$uploadfile); //ファイルの内容を$contentsに書き出す $UPLOAD = fopen($uploadfile,"r"); $contents = fread($UPLOAD,$_FILES['userfile']['size']); fclose($UPLOAD); echo $contents; } ?>
- ここで、is_uploaded_fileは、アップロードされたファイルが存在するかどうかを判断する関数。存在する場合のみ実行する。その後、copy()で/var/tmpに新たにファイル名を付与してコピーしている。最後は、そのファイルを開き、変数$contentsに読み込んだ後表示している。
- 画像ファイルの場合、表示以前に何かテキストなどを出力していると画像はでてこない。header()の問題か。
Base64でのエンコードとデコード
-
//echo $contents; //base64でエンコードする $contents2 = chunk_split(base64_encode($contents)); //echo $contents2; //base64でデコードする $contents3 = base64_decode($contents2); echo $contents3;
- これで、表示させてみても見た目は変わらないが、実際にはいったんbase64でエンコードされ、再びデコードされた$contents3が表示されている。ちなみに、echo $contents2の//コメントをはずせば、エンコードされた内容を見ることができる(意味はないが)。