You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

php5.6-fpm环境下ftp_put()返回网络流读取失败问题咨询

问题根因

你遇到的问题是PHP5.6 FPM环境下FTP扩展对FTPS连接的被动模式支持存在BUG,你调用的ftp_pasv未实际生效,从FTP日志可以看到所有数据传输都使用了PORT主动模式,而非预期的PASV被动模式,主动模式下FTP服务端无法成功回连到NAT环境下的PHP服务器,最终抛出流读取错误。

解决方案

方案1:修复FTP扩展参数配置(推荐,无需更换上传方式)

在原有代码基础上新增ftp_set_option配置,并确保被动模式开启的位置正确,修改后的代码如下:

<?php
$remotePath  = '/httpdocs/2/3/9/6/7/8/8/';
$newFileName = time() . '.png';

$ftp = ftp_ssl_connect( 'example.com', 21 );
if (!$ftp) {
    die('连接FTP失败');
}

$login_result = ftp_login( $ftp, 'username', 'password' );
if (!$login_result) {
    die('FTP登录失败');
}

// 核心修复1:关闭被动模式地址校验,避免FTP服务器返回内网地址无法连接
ftp_set_option($ftp, FTP_USEPASVADDRESS, false);
// 核心修复2:登录后显式开启被动模式,确保在所有数据操作前执行
ftp_pasv( $ftp, true );

$upload_result = ftp_put( $ftp, $remotePath . $newFileName, $_FILES['upload']['tmp_name'], FTP_BINARY );
if (!$upload_result) {
    die('上传失败: ' . error_get_last()['message']);
}

ftp_close( $ftp );

修改后重启php5.6-fpm服务即可验证,核心修复逻辑:

  • 开启FTP_USEPASVADDRESS = false:强制PHP使用FTP连接的目标地址作为被动模式传输地址,忽略FTP服务端返回的内网地址,避免NAT场景下的连接异常
  • 确保被动模式开启在登录后、所有数据传输操作前执行,PHP5.6下连接状态变更会重置被动模式标记

方案2:调整php.ini配置

如果方案1未生效,检查php5.6-fpm的php.ini配置:

  1. 打开php5.6-fpm的配置文件,通常路径为/etc/php/5.6/fpm/php.ini
  2. 搜索ftp.allow_passive配置项,确保值为On,如果不存在该配置项,新增一行ftp.allow_passive = On
  3. 保存后执行systemctl restart php5.6-fpm重启服务生效

方案3:更换为CURL实现FTPS上传(兼容性最佳)

如果上述两种方案都无效,可以使用兼容性更强的CURL扩展实现FTPS上传,完全避开PHP5.6 FTP扩展的BUG,代码示例如下:

<?php
$remoteFile = 'ftp://example.com/httpdocs/2/3/9/6/7/8/8/' . time() . '.png';
$localFile = $_FILES['upload']['tmp_name'];

$ch = curl_init();
$fp = fopen($localFile, 'r');

curl_setopt($ch, CURLOPT_URL, $remoteFile);
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localFile));
// FTPS配置
curl_setopt($ch, CURLOPT_FTP_SSL, CURLFTPSSL_ALL);
curl_setopt($ch, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_TLS);
// 开启被动模式
curl_setopt($ch, CURLOPT_FTPPORT, '-');
// 自签名证书可开启以下配置,生产环境建议关闭并配置可信证书
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
fclose($fp);

if ($error) {
    die('上传失败: ' . $error);
}

内容的提问来源于stack exchange,提问作者Andrea D.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 14:24:04