PHP 如何使用本机 sftp 函数和 fwrite 提高文件上传的性能
How to increase the performance of a file upload using native sftp functions and fwrite in PHP
您好,我正在使用以下代码将一个巨大的文件 (500MB) 上传到 sftp 服务器。
<?php
$connection = ssh2_connect($this->host, $this->port, null);
$sftp = ssh2_sftp($connection);
$connection_string = ((int) $sftp) . $remotePath . $remoteFilename;
$stream = fopen('ssh2.sftp://' . $connection_string, 'w');
$source = fopen($localFilepath, 'r');
if (!$stream) {
throw new Exception('Could not create file: ' . $connection_string);
}
while (!feof($source)) {
// Chunk size 32 MB
if (fwrite($stream, fread($source, 33554432)) === false) {
throw new Exception('Could not send data: ' . $connection_string);
}
}
fclose($source);
fclose($stream);
但是上传非常慢。代码是 Google Cloud 运行 上的 运行。上传速度在8左右MiB/s.
我也尝试通过 shell_exec 使用 lftp,但是由于云 运行,这导致了更多问题 运行。
上行链路不是问题,因为我可以通过 CURL post 毫无问题地发送文件。
有人能帮忙吗?
非常感谢,最好的,
intxcc
问题是即使读取了 32MB 然后将其写入 sftp 流,fwrite 也会以不同的大小分块。我觉得只有几KB。
对于文件系统(这是 fwrite 的常见情况),这很好,但由于 fwriting 到远程服务器而没有高延迟。
所以解决方案是增加 sftp 流的块大小
stream_set_chunk_size($stream, 1024 * 1024);
所以最终的工作代码是:
<?php
$connection = ssh2_connect($this->host, $this->port, null);
$sftp = ssh2_sftp($connection);
$connection_string = ((int) $sftp) . $remotePath . $remoteFilename;
$stream = fopen('ssh2.sftp://' . $connection_string, 'w');
$source = fopen($localFilepath, 'r');
// Stream chunk size 1 MB
stream_set_chunk_size($stream, 1024 * 1024);
if (!$stream) {
throw new Exception('Could not create file: ' . $connection_string);
}
while (!feof($source)) {
// Chunk size 32 MB
if (fwrite($stream, fread($source, 33554432)) === false) {
throw new Exception('Could not send data: ' . $connection_string);
}
}
fclose($source);
fclose($stream);
希望这能帮助下一个头发花白的人解决这个问题 ;)
您好,我正在使用以下代码将一个巨大的文件 (500MB) 上传到 sftp 服务器。
<?php
$connection = ssh2_connect($this->host, $this->port, null);
$sftp = ssh2_sftp($connection);
$connection_string = ((int) $sftp) . $remotePath . $remoteFilename;
$stream = fopen('ssh2.sftp://' . $connection_string, 'w');
$source = fopen($localFilepath, 'r');
if (!$stream) {
throw new Exception('Could not create file: ' . $connection_string);
}
while (!feof($source)) {
// Chunk size 32 MB
if (fwrite($stream, fread($source, 33554432)) === false) {
throw new Exception('Could not send data: ' . $connection_string);
}
}
fclose($source);
fclose($stream);
但是上传非常慢。代码是 Google Cloud 运行 上的 运行。上传速度在8左右MiB/s.
我也尝试通过 shell_exec 使用 lftp,但是由于云 运行,这导致了更多问题 运行。
上行链路不是问题,因为我可以通过 CURL post 毫无问题地发送文件。
有人能帮忙吗?
非常感谢,最好的, intxcc
问题是即使读取了 32MB 然后将其写入 sftp 流,fwrite 也会以不同的大小分块。我觉得只有几KB。
对于文件系统(这是 fwrite 的常见情况),这很好,但由于 fwriting 到远程服务器而没有高延迟。
所以解决方案是增加 sftp 流的块大小
stream_set_chunk_size($stream, 1024 * 1024);
所以最终的工作代码是:
<?php
$connection = ssh2_connect($this->host, $this->port, null);
$sftp = ssh2_sftp($connection);
$connection_string = ((int) $sftp) . $remotePath . $remoteFilename;
$stream = fopen('ssh2.sftp://' . $connection_string, 'w');
$source = fopen($localFilepath, 'r');
// Stream chunk size 1 MB
stream_set_chunk_size($stream, 1024 * 1024);
if (!$stream) {
throw new Exception('Could not create file: ' . $connection_string);
}
while (!feof($source)) {
// Chunk size 32 MB
if (fwrite($stream, fread($source, 33554432)) === false) {
throw new Exception('Could not send data: ' . $connection_string);
}
}
fclose($source);
fclose($stream);
希望这能帮助下一个头发花白的人解决这个问题 ;)