在 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);
我有一个大文件(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);