У меня есть сервер обработки с моей базой данных и обслуживающей базой данных для обслуживания файлов с низкой пропускной способностью. На сервере обработки php не может создавать файлы, поэтому все должно выполняться с потоками и / или оставаться в памяти перед отправкой на другой сервер для загрузки. Несколько дней назад я узнал об абстракции потока с помощью «php: // memory» и что я могу сделать что-то вроде
$fp=fopen('php://memory','w+'); fwrite($fp,"Hello world"); fseek($fp,0,SEEK_SET); //make a ftp connection here with $conn_id $upload = ftp_fput($conn_id,"targetpath/helloworld.txt",$fp,FTP_BINARY);
чтобы сделать файл в памяти, а затем разрешить мне передать его на другой сервер. Это именно то, что я хочу, за исключением того, что я также хочу заархивировать данные перед их отправкой – желательно использовать только собственные части php, такие как ziparchive, а не дополнительные пользовательские классы для специальной обработки потока. Я знаю, что я очень близок к следующему …
$zip = new ZipArchive(); if($zip->open('php://memory', ZIPARCHIVE::CREATE)) { $zip->addFromString('testtext.txt','Hello World!'); $fp = $zip->getStream('test'); if(!$fp) print "no filepointer"; //make a ftp connection here with $conn_id $upload = ftp_fput($conn_id,"targetpath/helloworld.zip",$fp,FTP_BINARY); } else print "couldn't open a zip like that";
Точка, в которой это не удается, – это вызов getStream (который всегда возвращает false, хотя я считаю, что правильно использую). Похоже, что zip прекрасно делает файл в «php: // memory», но по какой-то причине getStream все еще не работает, хотя, возможно, я недостаточно понимаю, как ZipArchive делает zips …
Как я могу перейти от строки к zipped filepointer, чтобы я мог почерпнуть zip на другой сервер? Помните, я не могу делать какие-либо файлы, иначе я просто сделаю zip-файл, а затем ftp.
EDIT: в соответствии с предложениями skinnynerd ниже я пробовал следующее
$zip = new ZipArchive(); if($zip->open('php://memory', ZIPARCHIVE::CREATE)) { $zip->addFromString('testtext.txt','Hello World!'); $zip->close(); $fp = fopen('php://memory','r+'); fseek($fp,0,SEEK_SET); //connect to ftp $upload = ftp_fput($conn_id,"upload/transfer/helloworld.zip",$fp,FTP_BINARY); }
Это делает zip и отправляет его, но zip имеет размер 0 байт, поэтому я не думаю, что «php: // memory» работает так, как я думал … на самом деле он не работает на закрытом шаге – $ zip -> close () возвращает false, что заставляет меня задаться вопросом, могу ли я вообще открыть zip в 'php: // memory'. Кто-нибудь знает, что я могу попробовать по этой линии, чтобы получить почтовый индекс?
Должен ли быть Zip-архив? Поскольку вы пытаетесь сохранить полосу пропускания, это может быть gzip.
<?php $ftp_credentials = "ftp://USER:PASSWORD@HOST/helloworld.gz"; $gz = gzencode("Hello World!", 9); $options = array('ftp' => array('overwrite' => true)); $stream_context = stream_context_create($options); file_put_contents($ftp_credentials, $gz, 0, $stream_context); ?>
$zip->getStream('test')
получает поток для извлечения файла 'test'
из архива. Поскольку в архиве нет файла 'test'
, это терпит неудачу. Это не функция, которую вы хотите использовать.
Как вы сказали, вы хотите отправить готовый архив на ftp-сервер. В этом случае вам нужно закрыть zip-архив, а затем повторно открыть php://memory
как обычный файл (используя fopen
), чтобы отправить его.
Я не знаю, но вы также можете использовать $zip
в качестве ресурса напрямую, без необходимости закрывать и снова открывать файл.
И я думаю, вы можете попробовать создать потоковый канал непосредственно с ftp-сервера
<?php $zip = new ZipArchive(); if($zip->open('ftp://user:password@ftp.host.com/upload/transfer/helloworld.zip', ZipArchive::CREATE)) { $zip->addFromString('testtext.txt','Hello World!'); $zip->close(); } else print "couldn't open zip file on remote ftp host.";