画像ファイルのアップロード
(ブログ記事の一覧は「こちら」)
サーバーに画像ファイルを送信(アップロード)する方法を学びましょう。
PHPで用意されている move_uploaded_file 関数を用いると、サーバーにテンポラリファイルをアップロードしてから、指定の場所のファイル名にコピーする、という処理を行っています。
ここで学ぶこと
- move_uploaded_file 関数
- $_FILES(スーパーグローバル)
参考:
move_uploaded_file 関数(PHPマニュアル)
exif_imagetype 関数(PHPマニュアル)
pathinfo 関数(PHPマニュアル)
date 関数(PHPマニュアル)
$_FILES について
PHPでは、$_FILES というスーパーグローバル変数が用意されており、POSTでアップロードされたファイルの情報を得ることができます。
以下のフォームでファイルを送信する場合を考えます。
<form action="" method="post" enctype="multipart/form-data"> <input type="file" name="upload_image"> <input type="submit" value="送信"> </form>
$_FILES のデータの種類と内容は以下のものがあります。(ファイル入力のinputで指定したnameは「upload_image」)
キー名 | 記述例 | 内容 |
---|---|---|
name | $_FILES['upload_image']['name'] | ファイル名 |
type | $_FILES['upload_image']['type'] | ファイルのMIMEタイプ |
tmp_name | $_FILES['upload_image']['tmp_name'] | 一時的に保存されるファイルの名前 |
error | $_FILES['upload_image']['error'] | アップロード時のエラーコード |
size | $_FILES['upload_image']['size'] | ファイルサイズ(単位はバイト) |
例題1
$_FILES を利用して、画像ファイルのアップロードのプログラムを確認しましょう。
作成するもの
送信ページで画像ファイルを指定して、送信するだけのシンプルなサンプルプログラムです。
プログラム
「htdocs / sample」フォルダに以下のPHPプログラムファイルを用意します。
また、画像ファイルの保存先の「htdocs / sample / image」フォルダも用意します。
以下は送信ページのPHPプログラム「sample_upload_image_send_simple.php」です。
<html> <head> <meta charset="UTF-8"> </head> <body> <h1>シンプルな画像ファイルのアップロード</h1> <form action="sample_upload_image_receive_simple.php" method="post" enctype="multipart/form-data"> <p><input type="file" name="upload_image"></p> <p><input type="submit" value="送信"></p> </form> </body> </html>
続いて、受信ページのPHPプログラム「sample_upload_image_receive_simple.php」です。
<?php // 保存するディレクトリ $upload_dir = './image/'; var_dump($_FILES['upload_image']); // ファイルの情報 $name = $_FILES['upload_image']['name']; $tmp_name = $_FILES['upload_image']['tmp_name']; // ファイルパスからファイル名だけを取得(basename関数) $new_name = basename($name); // ファイルのアップロード(move_uploaded_file関数) move_uploaded_file($tmp_name, $upload_dir . $new_name); ?> <html> <head> <meta charset="UTF-8"> </head> <body> <h1>受信ページ</h1> <div><img src="http://localhost/sample/image/<?php echo $new_name;?>"></div> </body> </html>
実行、確認
「sample_upload_image_send_simple.php」を実行して、画像ファイルがサーバーの指定した場所にアップロードされていることを確認してください。
例題2
例題1は、シンプルな画像ファイルのアップロードのプログラムの例でした。しかし、安全に動作させるには十分ではありません。こちらでは以下の対応を追加したプログラムを作成します。
- ファイルの種類を制限する
- アップロードするファイル名を変更する
プログラム
送信ページのPHPプログラム「sample_upload_image_send.php」です。受信ファイル名以外は同じです。
<html> <head> <meta charset="UTF-8"> </head> <body> <h1>画像ファイルのアップロード</h1> <form action="sample_upload_image_receive.php" method="post" enctype="multipart/form-data"> <p><input type="file" name="upload_image"></p> <p><input type="submit" value="送信"></p> </form> </body> </html>
アップロードするファイル名は、現在の日付/時刻にすることで、同じファイル名が存在しないようにできます。以下のdate関数を使用します。
<?php echo date('Ymd_His');
受信ページのPHPプログラム「sample_upload_image_receive.php」です。コメントを参考に、内容を確認してみてください。
<?php $err = ''; // 保存するディレクトリ $upload_dir = './image/'; var_dump($_FILES['upload_image']); // ファイルの情報 $name = $_FILES['upload_image']['name']; $tmp_name = $_FILES['upload_image']['tmp_name']; // 画像ファイルかどうかを判別(exif_imagetype関数) $type = exif_imagetype($tmp_name); if ($type == IMAGETYPE_JPEG || $type == IMAGETYPE_PNG) { // 拡張子を取得(pathinfo関数) $extension = pathinfo($name, PATHINFO_EXTENSION); // ファイル名を「年月日_時分秒」にする(date関数) $new_name = date('_Ymd_His') . '.' . $extension; // ファイルのアップロード(move_uploaded_file関数) move_uploaded_file($tmp_name, $upload_dir . $new_name); } else { $err = '対象ファイルはPNGまたはJPGのみです。'; } ?> <html> <head> <meta charset="UTF-8"> </head> <body> <h1>受信ページ</h1> <?php if ($err !== '') { echo '<p>' . $err . '</p>'; echo '<a href="./sample_upload_image_send.php">戻る</a>'; } else { ?> <div><img src="http://localhost/sample/image/<?php echo $new_img;?>"></div> <?php } ?> </body> </html>
実行、確認
「sample_upload_image_send.php」を実行して、画像ファイルがサーバーの指定した場所にアップロードされていることを確認してください。また、PNGまたはJPEGフォーマット以外の画像ファイルを指定すると、ファイルがアップロードされないことも確認してください。
課題1
例題2を参考に、アップロードできるファイルサイズを1MB(1024 * 1024 byte)までに制限するプログラムを作成してください。
課題2
move_uploaded_file 関数(PHPマニュアル) を参考に、複数の画像ファイルをアップロードできるように、送信側/受信側のPHPプログラムを修正してください。