Я пытаюсь загрузить файл .mp4. (около 1,3 ГБ). Я использую следующее:
<?php $path = "video.mp4"; header('Accept-Ranges: bytes'); // For download resume header('Cache-Control: must-revalidate, post-check=0, pre-check=0' ); header('Content-Description: File Transfer' ); header('Content-Disposition: attachment; filename="'.basename( $path ).'"' ); header('Content-Length: ' . filesize($path)); // File size header('Content-Transfer-Encoding: binary'); // For Gecko browsers mainly header('Content-Type: application/octet-stream' ); header('Expires: 0' ); header('Last-Modified: ' . gmdate('D, d MYH:i:s', filemtime($path)) . ' GMT'); header('Pragma: no-cache' ); ob_clean(); flush(); readfile($path);
Я открываю свой php-файл, а firefox появляется с меню «хотите сохранить». Размер выглядит правильно. Я нажимаю кнопку «Сохранить как» на рабочем столе. Окончательный загруженный файл, как случайный размер, составляет около 400 МБ (330, 463 и 440).
Заголовки ответов:
Connection: Keep-Alive Content-Disposition: attachment; filename="//www.frederikspang.dk/elevgallavideo.mp4" Content-Length: 1422778850 Content-Type: video/mp4 Date: Sun, 30 Jun 2013 22:12:30 GMT Keep-Alive: timeout=10, max=50 Pragma: public Server: Apache content-transfer-encoding: binary
Это сложно – большинство настроек php не удастся через 30 секунд. Если вы владеете php.ini, вы можете изменить это на более длинный лимит. Но все же – это того стоит? Я имею в виду – файлы могут стать больше или медленнее в сети – и еще раз вы нажмете таймаут.
Вот почему были сделаны загрузчики – для загрузки больших файлов в более мелкие куски. Half Crazed показал вам код для этого. ЭТОТ ответ (его не только один – это только учитывает один из способов, которым клиенты ведут переговоры о переводах, – но все же его хороший старт ).
Например, Mega.co.nz использует новые функции html5. Загружает файл в браузере с помощью кусков, присоединяется к файлу на пользователе, а затем загружает его с дискового пространства браузера. Он может возобновлять файлы, приостанавливать файлы и так далее. (Извините – для этого нет кода, так как он был бы довольно большим и включал бы несколько языков (php, js)).
PS: измените свой readfile($path);
в:
$handle=fopen($path, 'rb'); while (!feof($handle)) { echo fread($handle, 8192); flush(); } fclose($handle);
Это не будет загружать WHOLE-файл в память, только части 8KiB одновременно, а затем отправлять их пользователю.
<?php $filename = "theDownloadedFileIsCalledThis.mp4"; $myFile = "/absolute/path/to/my/file.mp4"; // Add bellow code for mime type $ext=strtolower(substr($fl,strrpos($myFile,"."))); $mime_types = array( '.txt' => 'text/plain', '.htm' => 'text/html', '.html' => 'text/html', '.php' => 'text/html', '.css' => 'text/css', '.js' => 'application/javascript', '.json' => 'application/json', '.xml' => 'application/xml', '.swf' => 'application/x-shockwave-flash', '.flv' => 'video/x-flv', // images '.png' => 'image/png', '.jpe' => 'image/jpeg', '.jpeg' => 'image/jpeg', '.jpg' => 'image/jpeg', '.gif' => 'image/gif', '.bmp' => 'image/bmp', '.ico' => 'image/vnd.microsoft.icon', '.tiff' => 'image/tiff', '.tif' => 'image/tiff', '.svg' => 'image/svg+xml', '.svgz' => 'image/svg+xml', // video '.3gp' => 'video/3gpp', '.3g2' => 'video/3g2', '.avi' => 'video/avi', '.mp4' => 'video/mp4', '.asf' => 'video/asf', '.mov' => 'video/quicktime', ); if (array_key_exists($ext, $mime_types)){ $mm_type=$mime_types[$ext]; }else{ $mm_type="application/octet-stream"; } $mm_type="application/octet-stream"; header("Cache-Control: public, must-revalidate"); // Avoid this line header("Pragma: public"); // Add this line header("Pragma: hack"); // Avoid this line header("Content-Type: " . $mm_type); header("Content-Length: " .(string)(filesize($myFile)) ); // Avoid this line header('Content-Disposition: attachment; filename="'.$filename.'"'); header('Content-Length: ' . filesize($myFile)); // Add this line header("Content-Transfer-Encoding: binary\n"); ob_clean(); // Add this line readfile($myFile); ?>