PHP入門 リクエスト情報 アップロードの実装($_FILES)
$_FILESは、アップロードしたファイルに関する情報を取得するためのスーパーグローバル変数です。$_FILESを利用することで、ファイルのアップロード機能も直感的に作成できます。
画像ファイルのアップロード
例:画像ファイルをサーバーにアップロードする
sample1.php
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>ファイルアップロード</title>
</head>
<body>
<!--アップロード時はenctype属性に注意-->
<form method="POST" action="sample2.php" enctype="multipart/form-data"> //➊
<label for="upfile">ファイルのパス: </label>
<input type="hidden" name="max_file_size" value="1000000" />
<input id="upfile" type="file" name="upfile" size="40" />
<input type="submit" value="アップロード" />
</form>
</body>
</html>
sample2.php
<?php
// アップロード処理そのものの成否をチェック
if ($_FILES['upfile']['error'] !== UPLOAD_ERR_OK) {
$msg = [
UPLOAD_ERR_INI_SIZE => 'php.iniのupload_max_filesize制限を越えています。 ',
UPLOAD_ERR_FORM_SIZE => 'HTMLのMAX_FILE_SIZE 制限を越えています。',
UPLOAD_ERR_NO_FILE => 'ファイルはアップロードされませんでした',
UPLOAD_ERR_NO_TMP_DIR => '一時保存フォルダーが存在しません。',
UPLOAD_ERR_CANT_WRITE => 'ディスクへの書き込みに失敗しました。',
UPLOAD_ERR_EXTENSION => '拡張モジュールによってアップロードが中断されました。'
];
$err_msg = $msg[$_FILES['upfile']['error']];
// 拡張子が許可されたものであるかを判定
} elseif (!in_array(
strtolower(
pathinfo($_FILES['upfile']['name'])['extension']),['gif', 'jpg', 'jpeg', 'png'])) {
$err_msg = '画像以外のファイルはアップロードできません。 ';
// ファイルの内容が画像であるかをチェック
} elseif (!in_array(
finfo_file(finfo_open(FILEINFO_MIME_TYPE), $_FILES['upfile']['tmp_name']),['image/gif', 'image/jpg', 'image/jpeg', 'image/png'])) {
$err_msg='ファイルの内容が画像ではありません。';
//エラーチェックを終えたら、アップロード処理
} else {
$src = $_FILES['upfile']['tmp_name'];
$dest = $_FILES['upfile']['name'];
if (!move_uploaded_file($src, 'doc/'.$dest)) {
$err_msg = 'アップロード処理に失敗しました。 ';
}
}
//エラー発生時はエラーメッセージを表示
if (isset($err_msg)) {
die('<div style="color: Red;">'.$err_msg. '</div>');
}
// 処理成功時はフォームにリダイレクト (8.4.4項)
header('Location: http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/file1.php');
ファイルを選択ボタンをクリックして、画像ファイルを選択します。アップロードボタンをクリックしてエラーが発生しなければ、ファイルがサーバーにアップロードされます。
入力フォームの注意点
1、enctype属性を指定する
<form>タグにenctype=”multipart/form-data”を指定する必要があります。enctypeオプションは、フォームデータのエンコード形式を指定するもので、通常はあまり意識する必要がありません。しかし、アップロードに際しては明示的に指定しておかないと、サーバー側で正しくデータを受け取ることができません。
2、ファイル入力ボックスを配置
アップロードファイルの指定には、ファイル入力ボックスとして<input type=”file”>タグを利用します。複数のファイルを同時にアップロードさせたい場合には、複数選択可能なチェックボックスやリストボックスの場合と同様に、要素名にブラケット([])を指定してからmultiple属性を付与します。
<input id="upfile" type="file" name="upfile[]" size="40" multiple />
3、アップロードファイルの上限を設定
name=”max_file_size”の隠しフィールドでは、アップロード可能なファイルサイズの上限を指定できます。
アップロード実処理の解説
アップロードファイルの情報を取得するのは、$_FILESの役割です。$_FILESは2次元配列の構造を持っています。
構文:$_FILES
$_FILES['要素名']['情報名']
要素名は、<input type=”file”>タグのname属性で指定された値です。情報名には次の値を指定できます。
スーパーグローバル変数$_FILESで取得可能な情報
情報名 | 概要 | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
name | オリジナルのファイル名 | |||||||||||||||||||||||||||
type | アップロードファイルのコンテンツタイプ | |||||||||||||||||||||||||||
size | アップロードファイルのデータサイズ(バイト) | |||||||||||||||||||||||||||
tmp_name | サーバー上に仮保存されたときの一時ファイル名 | |||||||||||||||||||||||||||
error | アップロード時に発生したエラーのコード
|
➊では、name、tmp_nameキーから、それぞれオリジナルのファイル名と一時的なファイルの保存先を取得しています。(PHPでは、クライアントからファイルを受け取ると暫定的に仮のフォルダーに保存しています)あとは、move_uploaded_file関数で一時フォルダーから本来の保存先にファイルを移動するだけです。
構文:move_uploaded_file関数
move_uploaded_file(string $from, string $to) : bool
$from | 一時ファイルのパス |
$to | 保存先のパス |
move_uploaded_file関数は、引数$fromがアップロードされたファイルではなかったり、引数$toに書き込めなかったりした場合などにfalseを返します。この例では、move_uploaded_file関数の戻り値falseであった場合に、変数err_msgにエラーメッセージを設定しています。
複数ファイルのアップロードした場合
複数ファイルのアップロードを有効にした<input type=”file”>要素にmultiple属性を付与した場合、スーパーグローバル変数$_FILESには、以下のような情報がセットされます。
Aarry(
[upfile]=> Array (
[name] => Array (
[0] => test.jpg
[1] => test.gif
)
[type] => Array (
[0] => image/jpeg
[1] => image/gif
)
・
・
)
)
アップロードのエラー処理
1、アップロード処理そのものの成否を確認
最初に、$_FILESのerrorキーを確認します。$_FILESにはアップロード時に発生したエラー情報が格納されます
2、アップロードファイルの種類を確認
画像ファイルのみアップロードを許可したい場合は、pathinfo関数を利用してファイルの拡張子を取得します。
構文:pathinfo関数
pathinfo(string $path) : array
$path | 任意のパス |
pathinfo関数は、指定されたパスに関する情報をdirname(親フォルダ)mbasename(ベース名)、extension(拡張子)、filename(ファイル名)などのキーを持った連想配列として返します。
3、画像ファイルであることの確認
finfo_file関数は、与えられたファイル内容を解析してコンテンツタイプを取り出します。
構文:finfo_file関数
finfo_file(resource $finfo,string $filename) : string|false
$finfo | FileInfoリソース |
$filename | 対象となるファイル名 |
FileInfoリソースはfinfo_open関数から生成できます。finfo_file関数から得られたコンテンツタイプを、あらかじめ用意しておいた許可リストと比較し、妥当なファイルかどうかを判定します。
アップロード関連の設定パラメーター
PHPでは、アップロードの挙動を制御するために、php.iniで設定できるさまざまなパラメーターを用意しています。
アップロード関連の設定パラメーター
パラメーター名 | 概要 | 既定値 |
---|---|---|
file_uploads | アップロードを有効にするか | 1 |
max_file_uploads | 同時にアップロードできるファイルの最大数 | 20 |
upload_max_filesizes | アップロード可能な最大サイズ | 2M |
upload_tmp_dir | アップロードファイルを一時的に保存するためのフォルダー | – |
post_max_size | ポストデータとして送信可能な最大サイズ | 8M |
memory_limit | 利用可能なメモリサイズ | 128M |
max_execution_time | スクリプトの最大実行時間(秒) | 30 |
max_input_time | スクリプトが入力処理に利用できる最大時間(秒) | -1(max_execution_time) |