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

WP ALL Export PHP代码在HostGator可用,AWS服务器无法FTP传输

WP ALL Export FTP传输在AWS cPanel服务器失效问题

问题详情

我用WordPress插件WP ALL Export导出CSV文件后,采用官方提供的代码片段(仅修改个人FTP信息)实现自动FTP传输。这段代码在HostGator独立服务器上运行完全正常,但部署到AWS托管的cPanel服务器后,无法将文件传输至目标FTP服务器。

运行导出时无任何报错信息,进度条很快到100%,但仍需等待约2分钟才完成流程。已确认目标FTP服务器无拦截规则,且两台服务器均已安装cURL扩展。

使用的代码如下:

function wpae_after_export( $export_id ) {

    // Retrieve export object.
    $export = new PMXE_Export_Record();
    $export->getById($export_id);
    
    // Check if "Secure Mode" is enabled in All Export > Settings.
    $is_secure_export = PMXE_Plugin::getInstance()->getOption('secure');

    // Retrieve file path when not using secure mode.
    if ( !$is_secure_export) {
        $filepath = get_attached_file($export->attch_id);

    // Retrieve file path when using secure mode.                    
    } else {
        $filepath = wp_all_export_get_absolute_path($export->options['filepath']);
    }

    // Path to the export file.
    $localfile = $filepath;

    // File name of remote file (destination file name).
    $remotefile = basename($filepath);
    
    // Remote FTP server details.
    // The 'path' is relative to the FTP user's login directory.
    $ftp = array(
        'server' => 'ftp URL',
        'user' => 'ftp Password',
        'pass' => 'ftp Username',
        'path' => '/'
    );

    // Ensure username is formatted properly
    $ftp['user'] = str_replace('@', '%40', $ftp['user']);
    
    // Ensure password is formatted properly
    $ftp['pass'] = str_replace(array('#','?','/','\\'), array('%23','%3F','%2F','%5C'), $ftp['pass']);
    
    // Remote FTP URL.
    $remoteurl = "ftp://{$ftp['user']}:{$ftp['pass']}@{$ftp['server']}{$ftp['path']}/{$remotefile}";

    // Retrieve cURL object.
    $ch = curl_init();

    // Open export file.
    $fp = fopen($localfile, "rb");
    
    // Proceed if the local file was opened.
    if ($fp) {
        
        // Provide cURL the FTP URL.
        curl_setopt($ch, CURLOPT_URL, $remoteurl);

        // Prepare cURL for uploading files.
        curl_setopt($ch, CURLOPT_UPLOAD, 1);

        // Provide the export file to cURL.
        curl_setopt($ch, CURLOPT_INFILE, $fp);

        // Provide the file size to cURL.
        curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localfile));
        
        // Start the file upload.
        curl_exec($ch);

        // If there is an error, write error number & message to PHP's error log.
        if($errno = curl_errno($ch)) {
            if (version_compare(phpversion(), '5.5.0', '>=')) {
                
                // If PHP 5.5.0 or greater is used, use newer function for cURL error message.
                $error_message = curl_strerror($errno);

            } else {

                // Otherwise, use legacy cURL error message function.
                $error_message = curl_error($ch);
            }

            // Write error to PHP log.
            error_log("cURL error ({$errno}): {$error_message}");

        }
        
        // Close the connection to remote server.
        curl_close($ch);
        
    } else {

        // If export file could not be found, write to error log.
        error_log("Could not find export file");

    }
}

add_action('pmxe_after_export', 'wpae_after_export', 10, 1);

排查与解决步骤

  • 修正FTP信息赋值错误:代码里明显把用户名和密码搞反了,这是核心问题!
    原代码中$ftp['user']赋值的是密码,$ftp['pass']赋值的是用户名,修正后:

    $ftp = array(
        'server' => 'ftp URL',
        'user' => 'ftp Username', // 改为用户名
        'pass' => 'ftp Password', // 改为密码
        'path' => '/'
    );
    

    这个错误在部分宽松环境下可能没触发报错,但AWS环境下会直接导致FTP认证失败。

  • 检查AWS安全组出站规则:AWS服务器的安全组默认可能限制了FTP流量,需要确保:

    • 允许出站访问目标FTP服务器的21端口(主动FTP模式)
    • 若使用被动FTP,需允许出站访问目标服务器指定的被动端口范围(通常是1024-65535)
  • 验证cPanel防火墙设置:AWS上的cPanel大概率启用了CSF等防火墙工具,检查是否有规则阻止服务器向外部FTP发起连接:

    • 可临时关闭防火墙测试是否恢复正常
    • 或添加允许出站到目标FTP服务器IP的规则
  • 强制启用被动FTP模式:AWS环境下被动FTP兼容性更强,在cURL初始化后添加以下配置:

    curl_setopt($ch, CURLOPT_FTP_USE_EPSV, false);
    curl_setopt($ch, CURLOPT_FTPPORT, ''); // 启用被动模式
    
  • 增加调试日志定位问题:添加cURL verbose日志,获取连接过程的详细信息:

    // 在curl_init()之后添加
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_VERBOSE, true);
    $verbose_log = fopen(WP_CONTENT_DIR . '/curl_ftp_debug.log', 'w');
    curl_setopt($ch, CURLOPT_STDERR, $verbose_log);
    

    执行导出后查看wp-content/curl_ftp_debug.log文件,从中提取连接失败的具体原因。

  • 确认文件权限与路径:在代码中添加日志,验证导出文件是否存在且可读取:

    // 在$localfile赋值后添加
    error_log("Export file path: " . $localfile);
    error_log("File exists: " . (file_exists($localfile) ? "Yes" : "No"));
    error_log("File readable: " . (is_readable($localfile) ? "Yes" : "No"));
    

内容的提问来源于stack exchange,提问作者user2367177

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 21:15:36