Передача большого файла через SFTP в PHP

у меня большой файл (200 МБ вверх). Мне нужно передать его через PHP cron job. Используя Phpseclib выдает следующую ошибку:

разрешенный размер памяти 134217728 байт исчерпаны (пытался выделить 4133 байта) в /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 папка, поэтому время сценария передачи должно вступить в игру.

[редактирование] Я не намерен увеличивать лимит памяти как файлы могут быть больших размеров. Решение, в котором я могу передать файл по частям (режим добавления) или использовать некоторый сценарий оболочки с PHP cron, может быть полезным

размер файла на удаленном сервере 111.4 МБ пока фактический файл намного больше на локальном.

[изменить после исправления] Проблема исчезла после изменения версии 2.0.2 с версии 1.0 Мне пришлось изменить код для put

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

3 ответов


Phpseclib должен делать только прекрасную передачу больших файлов без необходимости увеличения доступной памяти.

Я думаю, вы, вероятно, попали в старую ошибку "SSH2: не подсчитывайте длину данных против размера окна". Вы, скорее всего, можете использовать более старую версию Phpseclib ( более старая неисправная версия поставляется даже с относительно новым программным обеспечением, таким как, например, Magento 1.9.* )

проверьте свою версию, если это не последняя перезагрузка https://github.com/phpseclib/phpseclib


вместо того, чтобы видеть код, который вы используете, я предполагаю, что вы пытаетесь загрузить файл 200mb как строку, и вы пытаетесь загрузить его как строку. например. $sftp->put('filename.remote', file_get_contents('filename.local'));. Если да, то попробуйте вместо этого:

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

это фактически немного изменилось с версией phpseclib >= 2.0.5. Вы должны включить пространство имен use phpseclib\Net\SFTP; , потом сделать что-то вроде этого:

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