[ PHP ] ファイルアップロードの進捗率を画面に表示する

Pocket

ここでは、 アップロードしているファイルの進捗状況を表示するサンプルを掲載しています。大きなファイルや回線が遅い場合など、処理が継続しているか停止しているのか判断できますので、ユーザビリティも向上します。

スポンサーリンク

ファイルアップロードのフォーム

サンプルで使用するファイルをアップロードする HTML は下記の通りです。ファイルのアップロードは iframe に対して行います。ただし、iframe 自体は画面の外に追い出されているため表示されません。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>ファイルの進捗を表示するサンプル</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
#long-running-process
{
    position: absolute;
    left: -100px;
    top: -100px;

    width: 1px;
    height: 1px;
}
</style>

<script type="text/javascript">
<!-- 
function Show_Progress_Text(text) { 
    document.getElementById('progress').value = text; 
} 
// -->
</script>

  </head>
  <body>
    <form target="target" action="long_time.php" method="post" enctype="multipart/form-data">
        <input type="file" name="upfile" />
        <input type="text" name="progress" />
        <input type="submit" value="アップロード" />
    </form>
    <iframe name="target" src="long_time.php" id="long-running-process"></iframe>
  </body>
</html>

ファイルアップロードの進捗状況を通知

フォームがサブミットされると、以下のスクリプト ( long_time.php ) が実行されます。本スクリプトは Javascript の Show_Progress_Text 関数を呼び出すように応答を返します。

// ファイルがアップロードされていない場合は終了する
if (!isset($_FILES["upfile"])) { return; }
if (!is_uploaded_file($_FILES["upfile"]["tmp_name"])) { return; }

// アップロードされたファイルをオープンする
$handle = fopen($_FILES["upfile"]["tmp_name"], "rb+");
$proc_length = 0; // ファイル処理サイズ

while (!feof($handle)) {
    
    // ファイルの読み込み
    $contents = fread($handle, 8192);
    $proc_length += strlen($contents);

    $data = '<script type="text/javascript">'
           .   'parent.Show_Progress_Text(\'' . $proc_length . 'バイトの処理が完了しました。\');'
           . '</script>';

    // サファリでは、1024 バイトのパディングが必要であり,IE では 256 バイトの
    // パディングが必要である。サイズが小さいとスクリプトが実行されない。
    // また、サファリでは <br/> タグも必要とのこと
    echo str_pad($data . '<br />', 1024, ' ', STR_PAD_RIGHT) . "\n";

    // ブラウザに応答を出力させる
    flush();
    ob_flush();
    sleep(1);    // 動作確認しやすいように1秒待機
}
fclose($handle);
参考
スポンサーリンク


Pocket

Leave a Comment

Your email address will not be published. Required fields are marked *