Я ' m пытается предоставить пользователям большие zip-файлы. Когда есть 2 одновременных подключения, серверу не хватает памяти (RAM). Я увеличил объем памяти с 300 МБ до 4 ГБ (Dreamhost VPS), и тогда все заработало.
Мне нужно разрешить более двух одновременных подключений. Фактические 4 ГБ позволят примерно 20 одновременных подключений (очень плохо).
Ну, текущий код, который я использую, требует вдвое больше памяти, чем фактический размер файла. Это очень плохо. Я хочу что-то вроде «потоковой передачи» файла пользователю. Таким образом, я бы выделил не больше, чем кусок, обслуживаемый пользователями.
Следующий код - это тот, который я использую в CodeIgniter (инфраструктура PHP):
ini_set('memory_limit', '300M'); // it was the maximum amount of memory from my server
set_time_limit(0); // to avoid the connection being terminated by the server when serving bad connection downloads
force_download("download.zip", file_get_contents("../downloads/big_file_80M.zip"));exit;
Функция force_download выглядит следующим образом (вспомогательная функция CodeIgniter по умолчанию):
function force_download($filename = '', $data = '')
{
if ($filename == '' OR $data == '')
{
return FALSE;
}
// Try to determine if the filename includes a file extension.
// We need it in order to set the MIME type
if (FALSE === strpos($filename, '.'))
{
return FALSE;
}
// Grab the file extension
$x = explode('.', $filename);
$extension = end($x);
// Load the mime types
@include(APPPATH.'config/mimes'.EXT);
// Set a default mime if we can't find it
if ( ! isset($mimes[$extension]))
{
$mime = 'application/octet-stream';
}
else
{
$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
}
// Generate the server headers
if (strpos($_SERVER['HTTP_USER_AGENT'], "MSIE") !== FALSE)
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".strlen($data));
}
else
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".strlen($data));
}
exit($data);
}
Я попробовал несколько кодов на основе фрагментов, которые нашел в Google, но файл всегда доставлялся поврежденным. Вероятно, из-за плохого кода.
Кто-нибудь может мне помочь?