Я использую этот код для загрузки файла в память из ftp:
public static function getFtpFileContents($conn_id , $file) { ob_start(); $result = ftp_get($conn_id, "php://output", $file, FTP_BINARY); $data = ob_get_contents(); ob_end_clean(); if ($resul) return $data; return null; }
Как я могу заставить его напрямую отправлять файл пользователю (браузеру) без сохранения на диск и без перенаправления на ftp-сервер?
Просто удалите буферизацию вывода ( ob_start()
и другие).
Используйте только это:
ftp_get($conn_id, "php://output", $file, FTP_BINARY);
Хотя, если вы хотите добавить заголовок Content-Length
, сначала нужно запросить размер файла, используя ftp_size
:
$conn_id = ftp_connect("ftp.example.com"); ftp_login($conn_id, "username", "password"); $file_path = "remote/path/file.zip"; $size = ftp_size($conn_id, $file_path); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=" . basename($file_path)); header("Content-Length: $size"); ftp_get($conn_id, "php://output", $file_path, FTP_BINARY);
public static function getFtpFileContentsWithSize($conn_id , $file) { ob_start(); $result = ftp_get($conn_id, "php://output", $file, FTP_BINARY); $data = ob_get_contents(); $datasize = ob_get_length( ); ob_end_clean(); if ($result) return array( 'data' => $data, 'size' => $datasize ); return null; } $mapfile = SUPERFTP::getFtpFileContentsWithSize($ftpconn, $curmap['filename']); ftp_close($ftpconn); if (!$mapfile) { $viewParams['OutContext'] = "Error. File not found." ; } header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename='.$curmap['filename']); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . $mapfile['size']); echo $mapfile['data']; exit( );
Этот код работает. Спасибо всем.