使用PHP通过SFTP传输大文件

8
我有一个大文件(超过200 MB)。我需要通过PHP cron job传输它。使用Phpseclib会出现以下错误:

在/app/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php中,尝试分配4133字节时已用尽134217728字节的允许内存大小

有没有办法可以使用PHP cron job完成这个任务?
代码只有一行,其中$localFile是一个已经存在的CSV文件。
$sftp->put('/Import/coupons/coupons_import_test.csv', $localFile, NET_SFTP_LOCAL_FILE);

注意:此操作需要在PHP生成位于/tmp文件夹内的文件之后进行,因此传输脚本的时间要考虑在内。

[编辑] 我不打算增加内存限制,因为稍后的文件可能会更大。可以将文件分成多个部分(追加模式)传输,或使用带有PHP Cron的shell脚本也是一个可行的解决方案。

远程服务器上的文件大小为111.4 MB,而本地实际文件的大小要大得多。

[修复后的编辑] 在从版本1.0更改为版本2.0.2后,问题消失了。 我不得不修改代码才能完成放置。

$sftp->put('/Import/coupons/coupons_import.csv', $localFile, $sftp::SOURCE_LOCAL_FILE);

你使用的 Phpseclib 版本是什么? - revo
我之前问过这个问题,但没有得到答案,所以我会再问一次(因为你刚刚发布了悬赏):你能发一些代码吗?此外,当您遇到内存错误时,文件的多少已上传?Pawel Dubiel的想法也很好,所以请尝试一下,如果不行,也许可以回答我的问题。 - neubert
Phpseclib的版本是1.0。我已经编辑了问题,加入了一行代码。 - Abhishek
你能否尝试将这个文件传输到另一台服务器上,看看是否存在相同的问题? - Pawel Dubiel
显示剩余5条评论
3个回答

2
Phpseclib应该可以很好地传输大文件,无需增加可用内存。我认为您可能遇到了旧的bug“SSH2:不要将数据长度计入窗口大小”。您很可能正在使用较旧版本的Phpseclib(即使是相对较新的软件,例如Magento 1.9.*也捆绑了较旧的有缺陷版本)。请检查您的版本是否不是最新的,如果不是,请从https://github.com/phpseclib/phpseclib重新下载。

我正在使用composer require在heroku设置中安装phpseclib 1.0。 - Abhishek
我不知道是不是你指出的版本1.0中的那个bug导致了这个问题,但当我改用版本2.0.2时,问题消失了。不过我还得稍微修改一下代码。 - Abhishek
@aeonsleo - 你使用的是哪个1.0版本?如果2.0.2也可以解决问题,似乎composer update也可以修复该问题。 - neubert

1

根据我的猜测,你试图将200MB的文件作为字符串加载并尝试将其作为字符串上传,但我并没有看到你使用的代码。例如:$sftp->put('filename.remote', file_get_contents('filename.local'));。如果是这样,请尝试使用以下方法:

$sftp->put('filename.remote', 'filename.local', NET_SFTP_LOCAL_FILE);

我正在按照你所提到的方式进行。 - Abhishek
2
要进一步评论,我需要看到一些代码。你可以将它编辑到你的原始帖子中。另外,当你遇到内存错误时,有多少文件已经上传了? - neubert

0

这在phpseclib版本 >= 2.0.5 中有所改变。你应该包含命名空间 use phpseclib\Net\SFTP;,然后像这样进行操作:

$sftp->put('filename.remote', 'filename.local', SFTP::SOURCE_LOCAL_FILE);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接