mp3のようなファイルを配信する場合、次のように書きます:
$this->autoRender = false; $download_file = $file_dir . DS . $file_id . ".mp3"; $response = $this->response->withFile($download_file); return $response;
このままでは、mp3がその場で再生され、ダウンロードできません。
当初は、ダウンロードするリンクにdownload
属性を付けていたのですがIE11ではサポートされていません:
<a href="/Audios/download.php?id=100" download>クリックしてダウンロード</a>
解決策は至って簡単でした。withFileの第2引数に['download' => true, 'name' => 'ファイル名']と指定してあげるだけです:
$this->autoRender = false; $download_file = $file_dir . DS . $file_id . ".mp3"; $response = $this->response->withFile($download_file, ['download' => true, 'name' => 'ファイル名'); return $response;
とするだけです。これで、IE11を含めて、正しくダウンロードしてくれます。
念のため、どのような仕組みかソースを見てみました。ファイルはvendor/cakephp/cakephp/src/Http/Response.php
です。
if ($options['download']) { $agent = env('HTTP_USER_AGENT'); if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent)) { $contentType = 'application/octet-stream'; } elseif (preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) { $contentType = 'application/force-download'; } if (isset($contentType)) { $new = $new->withType($contentType); } $name = $options['name'] ?: $file->name; $new = $new->withDownload($name) ->withHeader('Content-Transfer-Encoding', 'binary'); }
なお、aタグにdownload属性をつけるのを怠ると、Safariでは再生とダウンロードが両方走ります。