- 2006-08-26 (土) 0:06
- PHP
ThinkPHPでlighttpd+PHPを使ったファイルダウンロードが紹介されていました。PHP側で特定のヘッダを付けておけば、lighttpdがファイルを出力してくれる、という内容です。
ファイルが大きい、サーバ( or クライアント)の帯域が細い等でダウンロードに時間がかかるとその間FastCGI-PHPが占有されることになります。この方法であればPHPはヘッダだけを出力すればスクリプト実行を終了できるので、ダウンロード完了を待たずに他のリクエストを処理できます。PHPは必要な箇所だけ処理して、あとはlighttpdに任せるというわけですね。
# 餅は餅屋の発想ですな。
方法は以下になります。
- lighttpdの設定ファイルにallow-x-send-fileを記述
- PHPでX-LIGHTTPD-send-fileヘッダを出力
1.lighttpdの設定ファイルにallow-x-send-fileを記述
fastcgi.server = ( ".php" => ( "localhost" => ( "socket" => "/tmp/php-fastcgi.socket", "bin-path" => "/home/shin/php5/bin/php-fcgi", "broken-scriptfilename" => "enable", "allow-x-send-file" => "enable" ) ) )
2.PHPでX-LIGHTTPD-send-fileヘッダを出力
PHPではX-LIGHTTPD-send-fileヘッダ(lighttpd1.5まではX-Sendfileヘッダ)で出力するファイルパスを出力します。この時にContent-LengthやContent-Dispositionヘッダなど他のヘッダを出力しても問題無いです。
<?php $path = "/path/to/file"; header("X-LIGHTTPD-send-file: " . $path); header("Content-Disposition: attachment; filename=\"" . basename($path) . '"' ); header("Content-Length: " . filesize($path)); ?>
ちなみに上記方法とPHPでファイルを出力させる方法を試してみたところ明らかに前者の方がPHPの負荷が小さかったです。(前者はヘッダを出力するだけなので当たり前ですが)
ただlighttpdはディスク上のファイルを出力するだけなので、ダウンロードデータをPHPで動的に生成する場合はデータを一度ディスクに書き込む必要がありますね。
これはPHPじゃなくてもfastcgi経由で起動するものならPerlでもRubyでもPtyhonでもいけるでしょう。
>>
■参考サイト
ThinkPHP
X-Sendfile fro lighty’s life
HowToFightDeepLinking – lighttpd – Trac
>>
テスト用にlighttpdをインストールした時につまった箇所をメモ。(CentOS4.2)
- pcre-develをインストールしておく
- fastcgi+PHPを使う時は–enable-fastcgiでfastcgi対応のphpをインストールしておく。(php -v で(cgi-fcgi)が出ればOK)
- /usr/local/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.confで動作確認
- Newer: まるごとPerl vol.1
- Older: 天才少年ライダー・中上貴晶君の挑戦
トラックバック:0
- このエントリーのトラックバックURL
- /blog/2006/08/lighttpd_php_sendfile.html/trackback
- Listed below are links to weblogs that reference
- lighttpd+PHPでファイルダウンロード from Shin x blog