如何向http客户发送几百兆 1G的大文件?PHP读取大文件一般采用每次读取一块字符串,至到文件结束。问题是向浏览器发送第一块后http协议就会关闭会话,后续块无法发送。 比如通过浏览器下载文件这种应用。
这有个例子,摘自workerman/WebServer.php里的一个发送文件的方法。
function sendFile($connection, $file_path) { _// Check 304. _$info = _stat_($file_path); $modified_time = $info ? _date_('D, d M Y H:i:s', $info) . ' ' . _date_default_timezone_get_() : ''; if (!empty($_SERVER) && $info) { _// Http 304. _if ($modified_time === $_SERVER) { _// 304 _Http::_header_('HTTP/1.1 304 Not Modified'); _// Send nothing but http headers.. _$connection->close(''); return; } } _// Http header. _if ($modified_time) { $modified_time = "Last-Modified: $modified_time\r\n"; } $file_size = _filesize_($file_path); $file_info = _pathinfo_($file_path); $extension = isset($file_info) ? $file_info : ''; $file_name = isset($file_info) ? $file_info : ''; $header = "HTTP/1.1 200 OK\r\n"; //if (isset(self::_$mimeTypeMap_)) { //$header .= "Content-Type: " . self::_$mimeTypeMap_ . "\r\n"; //} else { $header .= "Content-Type: application/octet-stream\r\n"; $header .= "Content-Disposition: attachment; filename=\"$file_name\"\r\n"; //} $header .= "Connection: keep-alive\r\n"; $header .= $modified_time; $header .= "Content-Length: $file_size\r\n\r\n"; $trunk_limit_size = 1024*1024; if ($file_size < $trunk_limit_size) { return $connection->send($header._file_get_contents_($file_path), true); } $connection->send($header, true); _// Read file content from disk piece by piece and send to client. _$connection->fileHandler = _fopen_($file_path, 'r'); $do_write = function()use($connection) { _// Send buffer not full. _while(empty($connection->bufferFull)) { _// Read from disk. _$buffer = _fread_($connection->fileHandler, 8192); _// Read eof. _if($buffer === '' || $buffer === false) { return; } $connection->send($buffer, true); } }; _// Send buffer full. _$connection->onBufferFull = function($connection) { $connection->bufferFull = true; }; _// Send buffer drain. _$connection->onBufferDrain = function($connection)use($do_write) { $connection->bufferFull = false; $do_write(); }; $do_write(); }
谢谢
这有个例子,摘自workerman/WebServer.php里的一个发送文件的方法。
谢谢