我有一个带有我的数据库和服务数据库的处理服务器来提供带宽成本低的文件。在处理服务器上,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);
将文件存入内存然后允许我将其ftp到我的其他服务器。这正是我想要的,除了我还想在发送之前压缩数据 - 最好只使用像ziparchive这样的php的原生部分而不是用于特殊流操作的其他自定义类。我知道我非常接近以下......
$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)。看起来拉链很好,使文件在'php:// memory'中,但由于某种原因getStream仍然失败,尽管我可能还不完全理解ZipArchive如何制作拉链...
如何从字符串转到压缩的文件指针,以便我可以将zip压缩到我的其他服务器?记住我不能制作任何文件,否则我只会制作zip文件然后将其翻过来。
编辑:根据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是0字节大,所以我不认为'php:// memory'的工作方式与我想的一样......它实际上在关闭步骤失败了 - $ zip-> close()返回false,这让我想知道我是否可以在'php:// memory'中打开zips。有谁知道我可以尝试沿着这些线来获取拉链?
答案 0 :(得分:2)
$zip->getStream('test')
正在获取一个流以从存档中提取文件'test'
。由于存档中没有文件'test'
,因此失败。这是不您要使用的功能。
正如您所说,您要做的是将完成的存档发送到ftp服务器。在这种情况下,您需要关闭zip存档,然后重新打开php://memory
作为普通文件(使用fopen
)发送它。
我不知道,但您也可以直接使用$zip
作为资源,而无需关闭并重新打开该文件。
答案 1 :(得分:2)
我认为您可以尝试直接从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.";
答案 2 :(得分:1)
它必须是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);
?>