我正在尝试使用php中的fopen()向一个通过ftp打开的文件写入大块数据。该协议包装器是ftp,因此文件对于运行php代码的服务器来说是远程的。我要写入的文件位于Windows服务器上。
我验证了我的php代码确实创建了该文件,但问题在于文件内的数据要么不存在(0KB),要么写入到文件时提前停止。不确定为什么会出现这种情况。
以下是我用于处理操作的代码:
奇怪的是,echo语句显示如下内容:
**更新** 我与Rackspace Cloud代表交谈,他们提到如果要从他们的服务器进行FTP,则需要使用被动FTP。我设置了远程服务器以处理被动FTP连接,并验证了通过OSX Transmit FTP客户端现在可以在远程服务器上使用被动FTP。我添加了:
在fopen()语句之后,但我收到PHP的错误提示说我没有提供有效的资源给ftp_pasv()。我该如何确保PHP连接到ftp站点是PASV而不是ACTIVE,并仍然使用fwrite()?顺便说一下,我注意到Windows机器报告我的PHP代码正在写入的文件在磁盘上为4096字节。它从未超过这个数量。这导致我将output_buffering php值更改为65536只是为了进行故障排除,但这也没有解决问题...
** PART DUEX更新 **
在Rackspace Cloud Sites产品上调试问题太困难了,因为他们没有足够的管理员权限。我在Rackspace的Cloud Server产品上创建了一个非常小的云服务器,并将所有内容配置到我仍然看到与fwrite()相同的错误。为了确保我可以从该服务器写入文件到远程服务器,我在云服务器上的bash shell中使用基本的ftp命令。它很好用。因此,我认为php实现fwrite()中存在某种类型的数据限制问题的bug。当我从具有缓慢上行速度的本地环境向远程服务器写入时,它可以正常工作。有没有办法有效地降低写入的速度?只是问一下:)
** PART III更新 **
因此,我采纳了@a sad dude的建议并实施了一个函数,可能有助于尝试写入新文件并通过ftp发送它的人:
我验证了我的php代码确实创建了该文件,但问题在于文件内的数据要么不存在(0KB),要么写入到文件时提前停止。不确定为什么会出现这种情况。
以下是我用于处理操作的代码:
$file_handle = fopen($node['ftp'].$path_to_lut, "wb", 0, $node['ftp_context']);
include_once($file);
if ($file_handle)
{
fwrite($file_handle, $string); //$string is inside included $file
fclose($file_handle);
} else {
die('There was a problem opening the file.');
}
当我将这段代码托管在本地机器上时,它可以正常工作,但是当我将其上传到我的Web主机(Rackspace Cloud)时,它就会失败。这让我相信这是与Rackspace服务器配置相关的问题,但我想知道是否有什么我可以做到我的PHP代码更加健壮。
有没有任何想法来确保fwrite实际上将字符串写入远程机器?
谢谢!
好的,我已经修改了写入文件的代码,如下所示:
if ($file_handle)
{
if ($bytesWritten = fwrite($file_handle, $string) ) {
echo "There were " . $bytesWritten . " bytes written to the text file.";
}
if (!fflush($file_handle)) {
die("There was a problem outputting all the data to the text file.");
}
if (!fclose($file_handle)) {
die("There was a problem closing the text file.");
}
} else {
die("No file to write data to. Sorry.");
}
奇怪的是,echo语句显示如下内容:
然而,当我通过FTP验证文本文件大小时,它显示为0K,并且文件内部的数据实际上被截断了。我无法想象这是否与FTP服务器本身有关,因为如果PHP托管在Rackspace Cloud之外的机器上,则可以正常工作。已向文本文件写入10330字节。
**更新** 我与Rackspace Cloud代表交谈,他们提到如果要从他们的服务器进行FTP,则需要使用被动FTP。我设置了远程服务器以处理被动FTP连接,并验证了通过OSX Transmit FTP客户端现在可以在远程服务器上使用被动FTP。我添加了:
ftp_pasv($file_handle, true);
在fopen()语句之后,但我收到PHP的错误提示说我没有提供有效的资源给ftp_pasv()。我该如何确保PHP连接到ftp站点是PASV而不是ACTIVE,并仍然使用fwrite()?顺便说一下,我注意到Windows机器报告我的PHP代码正在写入的文件在磁盘上为4096字节。它从未超过这个数量。这导致我将output_buffering php值更改为65536只是为了进行故障排除,但这也没有解决问题...
** PART DUEX更新 **
在Rackspace Cloud Sites产品上调试问题太困难了,因为他们没有足够的管理员权限。我在Rackspace的Cloud Server产品上创建了一个非常小的云服务器,并将所有内容配置到我仍然看到与fwrite()相同的错误。为了确保我可以从该服务器写入文件到远程服务器,我在云服务器上的bash shell中使用基本的ftp命令。它很好用。因此,我认为php实现fwrite()中存在某种类型的数据限制问题的bug。当我从具有缓慢上行速度的本地环境向远程服务器写入时,它可以正常工作。有没有办法有效地降低写入的速度?只是问一下:)
** PART III更新 **
因此,我采纳了@a sad dude的建议并实施了一个函数,可能有助于尝试写入新文件并通过ftp发送它的人:
function writeFileAndFTP($filename=null, $data=null, $node=null, $local_path=null, $remote_path=null)
{
// !Determin the path and the file to upload from the webserver
$file = $local_path.'/'.$filename;
// !Open a new file to write to on the local machine
if (!($file_handle = fopen($file, "wb", 0))) {
die("There was a problem opening ".$file." for writing!");
}
// !Write the file to local disk
if ($bytesWritten = fwrite($file_handle, $data) ) {
//echo "There were " . $bytesWritten . " bytes written to " . $file;
}
// !Close the file from writing
if (!fclose($file_handle)) {
die("There was a problem closing " . $file);
}
// !Create connection to remote FTP server
$ftp_cxn = ftp_connect($node['addr'], $node['ftp_port']) or die("Couldn't connect to the ftp server.");
// !Login to the remote server
ftp_login($ftp_cxn, $node['user'], getPwd($node['ID'])) or die("Couldn't login to the ftp server.");
// !Set PASV or ACTIVE FTP
ftp_pasv($ftp_cxn, true);
// !Upload the file
if (!ftp_put($ftp_cxn, $remote_path.'/'.$filename, $file, FTP_ASCII)) {
die("There was an issue ftp'ing the file to ".$node['addr'].$remote_path);
}
// !Close the ftp connection
ftp_close($ftp_cxn);
}
include_once($file);
- 这段代码在哪里? - hakrevar_dump(stream_get_meta_data($file_handle));
的输出结果为:array(10) { ["wrapper_data"]=> NULL ["wrapper_type"]=> string(3) "ftp" ["stream_type"]=> string(14) "tcp_socket/ssl" ["mode"]=> string(2) "r+" ["unread_bytes"]=> int(0) ["seekable"]=> bool(false) ["uri"]=> string(119) "ftp://user:pass@mydomain.com:21/vars.txt" ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) }
。 - ariestav