(PHP)PHPでファイルをダンロード(アクセス制限付き)とかぶってる内容ありです。
現在下記のような感じでダウンロードページを構築していました。
ダウンロードボタン押下→サンクスページに遷移→ファイル保存ダイアログが開く。
ちょうど、ベクターのダウロードのような感じです。
これで、現在はファイルをPHPスクリプトを置いてるレンタルサーバ上(ServerA)においてるんですが、このレンタルサーバがファイル転送の速度が遅いので、ダウンロードさせるファイルだけ、もっと高速な別レンタルサーバ(ServerB)に置いて欲しいという要件でした。
(ダウンロード一覧処理やページ遷移後のダウンロードなどは全て CakePHP でDBと連携させてますが、これらは元のレンタルサーバに置いたままとします。)
で、考えたのは、ServerBにダウンロードロジックを置いた PHP スクリプトを置いて、ServerA からリダイレクトでその PHP をたたくという方法です。
以下サンプルソースです。(ServerA側は CakePHP 使ってますが、普通のPHPに書き直しても使えると思います。)
ServerA側の CakePHP ダウンロード用コントローラ
class DownloadsController extends AppController{
var $name = "Downloads";
/**
* ダウンロードファイルリストの一覧作成・表示
*
* @access public
*/
function index(){
//省略。。。ここで、DBからダウンロードさせるファイルの一覧を取得してます。*/
}
/*
* ダウンロードメッセージ表示ページ
* ダウンロード案内のメッセージを表示し、ダウンロードを行うページへの遷移を行う。
*
* @param int $id ダウンロードする対象のid (downloads.id)
* @access public
*/
function get( $id ){
//レイアウトファイルはdown.ctpを使う。
$this->layout = 'down';
//DBから指定されたidのデータ取得
$where = array("id" => $id );
$dwn = $this->Download->find( $where );
//存在しないもしくはダウンロード許可されていない場合はエラーメッセージ
if ($dwn == null)
{
$msg = '存在しないファイルが指定されました。ダウンロードできません。';
}else{
$msg = '
※ダウンロードに関する注意点
お使いのブラウザや設定によっては「セキュリティ保護のため...」という情報バーが表示される場合があります。
もしくは$dwn['Download']['name'] . '">こちらのリンクからダウンロードしてください。
';//ダウンロードページ遷移のヘッダを埋め込む($dwn['Download']['name']にはダウンロードさせるファイル名が格納)
$metaRefresh = '$dwn['Download']['name'] .'">';
//ダウンページ遷移ヘッダをレイアウトにセット(レイアウトファイルのヘッダにこのメタデータを出力する記述がいる)
$this->set('metaRefresh', $metaRefresh);
}
$this->set('msg', $msg);
}
/*
* ダウンロード処理
* 引数で渡されたidのダウンロードファイルを実際にダイアログを表示させてダウンロードさせる。
*
* @param int $filename ダウンロードする対象のファイル名
* @access public
*/
function down( $filename )
{
if ($filename != null)
{
//ServerBのダウンロード処理PHPにリダイレクト
header("Location:http://ServerB/down.php?file=" . $filename);
exit;
}
}
}
?>
ServerA側の CakePHP ダウンロード用レイアウトファイル(ダウンロードページ遷移へのメタデータ)
xmlns="http://www.w3.org/1999/xhtml">
<?php //ダウンロード用メタデータ。メタデータがあれば、それを出力。メタ情報用変数がなければ何もしない ?>
<?php if ( isset( $metaRefresh ) ) : ?>
<?php echo $metaRefresh ?>
<?php endif; ?>
省略....
省略....
ServerB側で実際にダウンロード処理を行うPHP(GET変数でファイル名をもらう)
//ダウンロード開始させる
//GET引数取得(downloadファイル名が入る)
$path_file = $_GET["file"];
/* ファイルの存在確認 */
if (!file_exists($path_file)) {
die("Error: File(".$path_file.") does not exist");
}
/* オープンできるか確認 */
if (!($fp = fopen($path_file, "r"))) {
die("Error: Cannot open the file(".$path_file.")");
}
fclose($fp);
/* ファイルサイズの確認 */
if (($content_length = filesize($path_file)) == 0) {
die("Error: File size is 0.(".$path_file.")");
}
/* ダウンロード用のHTTPヘッダ送信 */
header("Content-Disposition: inline; filename=\"".basename($path_file)."\"");
header("Content-Length: ".$content_length);
header("Content-Type: application/octet-stream");
/* ファイルを読んで出力 */
if (!readfile($path_file)) {
die("Cannot read the file(".$path_file.")");
}
?>