在 PHP 中通过 SFTP 传输大文件

Transfer large file via SFTP in PHP

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

Allowed memory size of 134217728 bytes exhausted (tried to allocate 4133 bytes) in /app/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php

有什么方法可以用 PHP cron job 做到这一点吗?

代码很简单,其中 $localFile 是一个已经存在的 CSV 文件

$sftp->put('/Import/coupons/coupons_import_test.csv', $localFile, NET_SFTP_LOCAL_FILE);

PS。这需要在 PHP/tmp 文件夹中生成该文件之后完成,因此传输脚本的时间必须发挥作用。

[编辑] 我不打算增加内存限制,因为以后的文件可能更大。我可以分部分传输文件(追加模式)或将一些 shell 脚本与 PHP cron 一起使用的解决方案可能是值得的

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

[修复后编辑] 从1.0版换到2.0.2版后问题消失 我不得不修改 put

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

代替看到您正在使用的代码,我的猜测是您正在尝试将 200mb 文件作为字符串加载,并且正在尝试将其作为字符串上传。例如。 $sftp->put('filename.remote', file_get_contents('filename.local'));。如果是这样,那么试试这个:

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

Phpseclib 应该可以很好地传输大文件而无需增加可用内存。

我想你可能遇到了老问题"SSH2: don't count data length against window size"。您很可能正在使用旧版本的 Phpseclib(旧的故障版本甚至与相对较新的软件捆绑在一起,例如 Magento 1.9.*)

检查您的版本,如果不是最新的,请从 https://github.com/phpseclib/phpseclib

重新下载

这实际上随着 phpseclib 版本 >= 2.0.5 发生了一些变化。你应该包括命名空间 use phpseclib\Net\SFTP; ,然后做这样的事情:

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