ファイルのアップロード処理のちょっとした小技を紹介したいと思います。アップロード処理では大きなファイルを送信する場合等に、ポスト後の画面が表示されるまでに非常に時間がかかってしまい、その間はユーザーが操作できなくなってしまいます。そんな、場合には以下の方法を検討してみてはいかがでしょう?

以前、PHPニュースでも紹介したIFRAMEアップロードの方法を使用すれば、メインのページは画面遷移することなく、ユーザーは通常の操作を続けることができます。以下のスクリプトをご覧下さい。

[upload.html]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<title>Tips</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript">
//アップ後にIFRAME側から呼び出す関数
function fupComp(str) {
  var listArea = document.getElementById("uplist");
  listArea.innerHTML += str + "<br>";
}
</script>
</head>
<body>
<iframe name="fup" width="0" height="0" frameborder="0"></iframe>
<!-- formのtarget属性にiframeのnameを指定 -->
<form name="fupform" action="fup.php" enctype="multipart/form-data"
method="post" target="fup">
  <input type="file" name="myfile" />
  <input type="submit" name="upload" value="送信" />
</form>
<p id="uplist">
  <!-- 今回はここにアップしたファイル名を表示していく -->
</p>
</body>
</html>

[fup.php]

<?php
//アップ処理用ファイル
if (isset($_FILES)) {    
    
  
//*1 ~ここでチェック&アップロード処理を行う~

  //以下処理後の出力
  
echo '<html><head><title>-</title></head><body>';
  echo 
'<script type="text/javascript">';
  
//*2 親ウインドウのJavaScript関数fupCompの引数に今回はファイル名を渡す。
  
echo 'window.parent.fupComp("'.
htmlspecialchars($_FILES["myfile"]["name"], ENT_QUOTES) .'");';
  echo 
'</script></body></html>';
  exit;
}
?>

formタグのtarget属性にiframeのnameを指定します。こうすることにより、今見ている画面が遷移することなくデータをPOSTすることができます。

あとは、action属性で指定した送信先ファイル(fup.php)でアップロードの処理を行います。(*1 このスクリプトでは送信されたファイルの保存処理等は省略しています。)

そして、アップ処理完了後にメインページ(親ウインドウ)で定義済みのJavaScript関数を呼び出すJavaScriptコードを出力します。(*2の部分)

上記のスクリプトでは単純にアップされたファイル名を引数に渡しているだけですが、エラー文字列やアップ完了文等を表示させたりする場合も少々手を加えれば簡単に実装できると思います。

ユーザビリティが特に大事にされるこの頃、こういった実装も取り入れてみてはいかがでしょうか。



(アシアル 中川善樹)


この記事は、アシアルが運営するPHP開発者のためのポータル&コミュニティサイト「PHPプロ!」で毎週配信しているPHP・TIPSメーリングリストを再録したものです。
同サイトでは、他にもPHP最新ニュースや、困ったときのQ&A掲示板、初心者向けのPHP講座など、PHP開発者をサポートする情報を掲載しています。