PHPでファイルをDL(ダウンロード)させる際のPHPコード例

PHPでファイルをDLさせる際のPHPコード例:phpspot開発日誌
を見て、タイムリーだったので私の書きかけコードを置いてみます。

やりたいのは、

  • PHP
  • ある程度大きなファイルを
  • 文字化けしないように
  • ローカルにダウンロードさせる

ということです。

文字化け云々については自信が無いので、以前のエントリ のリンク先を参照するといいかもしれません。

<?php
/************************************************
PHPを使ったファイルのダウンロード。

/tmp/hoge.xls を 'はてな_ダイアリー.xls'という名前でダウンロードします。

注意点
-Shift_JISでファイルを書いています。
-5MBくらいのファイルで動作確認
-PHP4.3で動作確認
-IE6 on WindowsXPで動作確認
-Firefox2 on WindowsXPで動作確認
-Opera9 on WindowsXPで動作確認
-Safari on MacOS10.4で動作確認

author: morningmist7
*************************************************/
  //ダウンロードするファイル
  $filePath = "/tmp/hoge.xls";

  //ファイル名部分を抽出
  $pathInfo = pathinfo($filePath);
  $fileName = 'はてな ダイアリー.xls'; //あえてスペースを入れてみる

  /**
   * ファイルの存在チェック
   */
  if (!file_exists($filePath)) {
    die("Error: ファイル " . $filePath . " が見つかりませんでした");
  }

  /**
   * オープンできるかチェック
   */
  if (!($fp = fopen($filePath, "r"))) {
    die("Error:  ファイル " . $filePath . " をオープンできませんでした");
  }
  fclose($fp);

  /**
   * ファイルサイズを取得して、Content-Lengthヘッダに使う
   */
  $contentLength = 0;
  $fileSize = filesize($filePath);
  if ($fileSize == 0) {
    die("Error:  ファイル " . $filePath . " のサイズが 0 Byteのためオープンできませんでした");
  }
  $contentLength = $fileSize;

  /**
   * ブラウザの判別
   */
  $msie = false;
  $safari = false;
  $opera = false;
  $useragent = getenv("HTTP_USER_AGENT");
  if (ereg("Mozilla/4.0 \(compatible; MSIE", $useragent)) {
    $msie = true;
  }
  if (ereg("Safari", $useragent)) {
    $safari = true;
  }
  if (ereg("Opera", $useragent)) {
    $opera = true;
  }

  //ファイル名にスペースが入っているとダウンロード名が切れるブラウザがあるので_(アンダーバー)で補完する。
  $fileName = str_replace(' ', '_', $fileName);

  /**
   * HTTPヘッダの生成
   */
  if ($msie == true) {  //IEの場合
    Header("Content-Disposition: attachment; filename=" . $fileName); 
    Header('Pragma: private');
    Header('Cache-Control: private');
    Header("Content-Type: application/octet-stream-dummy");
  } else {	//IE以外
    //UTF-8にファイル名を変換
    $fileName = mb_convert_encoding($fileName, "UTF-8", "SJIS-win");
    if ($safari == true) {
    	//Safariの場合は全角文字が全て化けるので、何かしら固定のファイル名にして回避
        $fileName = 'your-browser-is-safari.' . $pathInfo['extension'];
    }
    Header("Content-Disposition: attachment; filename=" . $fileName); 
    Header("Content-Type: application/octet-stream; name=" . $fileName); 
  }
  Header("Content-Length: ". $contentLength);

  /**
   * ファイルのダウンロード
   */
  $handle = fopen($filePath, "r");	//対象のファイルをOpen
  while(!feof($handle))
  {
    $buffer = fgets($handle, 4096);	//4kづつレスポンスしていく
    echo $buffer;
    ob_flush(); //出力バッファの内容を送信
    flush();    //出力バッファをフラッシュ
  }
  fclose ($handle);
?>