使用WordPress Filesystem_API上传文件至远程FTP服务器失败问题咨询
既然原生ftp_put()和FileZilla都能正常上传,说明FTP服务器本身没问题,问题大概率出在WordPress Filesystem API的使用细节上。我碰到过好几个类似的情况,核心都是路径处理、初始化逻辑或者模式设置的小问题,咱们一步步来解决:
1. 先搞清楚远程FTP的实际工作路径,别瞎猜根目录
很多FTP服务商的“根目录”并不是你以为的/——比如有些服务器的FTP根目录实际是/home/your_username/或者/public_html/,而WP Filesystem API里直接写/test.txt,可能指向的是服务器的系统根目录(根本没有写入权限)。
你可以先加一行代码,打印当前FTP连接的工作目录:
echo "当前FTP工作目录:" . $wp_filesystem->pwd();
比如输出是/home/mujuonly/,那你要上传的文件路径应该写成/home/mujuonly/test.txt,而不是/test.txt。
2. 别只看返回false,要拿具体错误信息
WP Filesystem API会记录详细的错误,但默认不会主动输出。在put_contents失败后,一定要获取错误信息,这能直接帮你定位问题:
$success = $wp_filesystem->put_contents('/正确的路径/test.txt', "hello"); if (!$success) { echo "上传失败原因:" . $wp_filesystem->get_error_message(); }
比如会提示你“Permission denied”(权限不足)或者“No such file or directory”(路径不存在),比单纯看false有用多了。
3. 修正WP_Filesystem的初始化逻辑
你的代码里手动实例化了WP_Filesystem_ftpext,但其实WP_Filesystem()函数已经会帮你初始化全局的$wp_filesystem,重复实例化可能导致连接状态异常。修改后的初始化逻辑应该是这样:
function remote_ftp_upload_using_standard_wp($ftp_profile) { global $wp_filesystem; require_once ABSPATH . '/wp-admin/includes/file.php'; $connection_options = array( 'connection_type' => 'ftpext', 'hostname' => $ftp_profile['server'], 'username' => $ftp_profile['user_name'], 'password' => $ftp_profile['password'], 'port' => $ftp_profile['port'], ); // 让WP_Filesystem自动完成初始化,不用手动new if (!WP_Filesystem($connection_options)) { echo "WP Filesystem初始化失败"; return false; } // 先确认当前工作目录 echo "当前FTP工作目录:" . $wp_filesystem->pwd() . "<br>"; // 尝试上传到当前目录下的test.txt $success = $wp_filesystem->put_contents('test.txt', "hello"); if (!$success) { echo "上传失败:" . $wp_filesystem->get_error_message(); } else { echo "上传成功"; } return $wp_filesystem; }
4. 试试关闭被动模式
有些FTP服务器不支持被动模式,而WP的ftpext默认会开启被动模式。你可以在连接成功后手动关闭试试:
// 连接成功后添加这段代码 if ($wp_filesystem->method == 'ftpext') { ftp_pasv($wp_filesystem->link, false); }
5. 确认目标目录的写入权限
虽然FileZilla能上传,但要确认你用的FTP账号对目标目录有写入权限(有些目录需要设置755或777权限,具体看服务器配置)。可以用下面的代码检查:
$target_dir = "/目标目录路径"; if (!$wp_filesystem->is_writable($target_dir)) { echo "目标目录没有写入权限"; }
按照上面的步骤排查,尤其是获取错误信息那一步,基本就能快速定位问题了。
内容的提问来源于stack exchange,提问作者mujuonly

