条件:php5.4.x以上
今回、ブラウザからのファイルアップロード速度を計測したく、PHPを用いたファイルアップロードスクリプトを用意しました。このスクリプトでは、クライアントから任意のファイルを選択しサーバーにアップロードするフォーム、さらにはアップロード後にアップロードされたファイルのサイズはもちろんのことアップロードにかかった時間、アップロード速度(MbpsおよびMB/s)を表示することができます。
スクリプトの記載内容は以下のとおり
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=2.0,user-scalable=1" /> <title>ファイルアップロードテスト</title> </head> <body> <center> <div style='margin: 100 auto;';> <?php // ★条件:$_FILESがある場合 if($_FILES){ if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) { // アップロードされたファイルの削除 if (unlink($_FILES["upfile"]["tmp_name"])) { // アップロード完了時の時刻取得 $upload_time = microtime(TRUE) - $_SERVER['REQUEST_TIME_FLOAT']; // アップロードされたファイルのサイズ取得 $MB = round($_FILES['upfile']['size'] / $upload_time / 1024 / 1024, 2); $mbps = round($MB * 8,2); echo '<p>' . $_FILES['upfile']['name'] . 'をアップロードしました。</p>'; print 'アップロードにかかった時間:<br><h2>' . round($upload_time,2) . ' 秒</h2></p>'; print 'アップロードしたサイズ:<br><h2>' . number_format($_FILES['upfile']['size']) . ' Bytes</h2></p>'; print '速度(Mbps):<br><h2>' . $mbps . ' Mbps</h2></p>'; print '速度(MB/s):<br><h2>' . $MB . ' MB/s</h2></p>'; } else { echo '<p>ファイルをアップロードできません。</p>'; } } else { echo '<p>ファイルが選択されていません。</p>'; } echo "<a href='./'>戻る</a>"; // ★条件:$_FILESがない場合 }else{ ?> <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post" enctype="multipart/form-data"> ファイル:<br /> <input type="file" name="upfile" size="30" /><br /> <br /> <input type="submit" value="アップロード" /> </form> <?php } ?> </div> </center> </body> </html>
注意点
PHPの制限でPOSTできるサイズ・アップロードできるサイズの制限がされている場合があります。その場合は/etc/php.iniもしくは同等のファイルを変更し、制限を解除する必要があります。
これら2箇所の設定です。以下は変更済みです。
# grep max_.*size /etc/php.ini post_max_size = 2G upload_max_filesize = 2G #
上記のようにphp.iniを編集してWebサーバーの再起動をすれば大丈夫なのですが、もし特定のフォルダ配下のみアップロードサイズ制限を緩和したい場合は、以下のとおり希望するディレクトリに.htaccessをおくことで実現可能です。
# cat .htaccess php_value post_max_size 2G php_value upload_max_filesize 2G
引き続き、上記スクリプトの中でためになる部分を少しだけ解説します。
HTMLフォームを使ったファイルのアップロード
ファイルのアップロードを行うフォームを作るには以下の3点がポイント
- フォームのmethod(メゾッド)が POST であること
- enctype(エンクタイプ)が multipart/form-data であること
- input type=’file’ を用いたINPUTを用意する
これらをクリアさせればファイルのアップロードを行うHTMLフォームが完成できます。
上記の例のフォームではaction先が「<?php echo $_SERVER[‘PHP_SELF’];?>」になっていますが、これはPHPファイル自身にPOSTしなさいという記述です。
アップロードにかかった時間の取得
これがphp5.4.x以上である必要がある理由なのですが、「$_SERVER[‘REQUEST_TIME_FLOAT’]」という変数を用いて、アップロード処理にかかった時間を取り出しています。この変数はPHP5.4.x以上で使えるようになりました。
$_SERVER[‘REQUEST_TIME_FLOAT’] が追加され、マイクロ秒単位の精度も取得できるようになりました。
‘REQUEST_TIME_FLOAT‘ リクエストの開始時のタイムスタンプ (マイクロ秒までの精度)。 PHP 5.4.0 以降で利用可能。
301 Moved Permanently
「ファイルのアップロードが完了した時間」から「アップロードリクエストを行った時間」を引くことで、「アップロードにかかった時間」を取り出しています。
$upload_time = microtime(TRUE) - $_SERVER['REQUEST_TIME_FLOAT'];
数値の表示フォーマットの変更
round 小数点以下に表示する文字を指定(以下の例の場合は2文字)して、それ以外は四捨五入する。
round(1.345) は 1.35 となる 。
number_format 与えられた値を3文字ごとに区切って表示する。
number_format(1234567) は 1,234,567 となる。
以上
参考:
Using php_flag or php_value in .htaccess files – .htaccessでPHPの設定を変える方法(英語)
PHP Labo – ファイルのアップロード – PHPでのファイルアップロード方法
[PHP.net] round – 数値の四捨五入、小数点は以下の数制限
[PHP.net] number_format – 数値を千単位で「,」区切りにする
Measure upload time and speed with PHP and Javascript – アップロード時間の取得方法(英語)
コメント