使用PHP与curl远程上传安装WordPress插件报错求助
问题原因
- 第一个报错
Please select a file:你对包含CURLFile对象的上传参数数组调用了http_build_query(),这个方法会把参数序列化为application/x-www-form-urlencoded格式,直接把文件对象转成了无效字符串,WordPress自然识别不到你上传的插件包。 - 第二个报错
403 not authorize:两种可能,一是你手动设置multipart/form-data请求头时没有指定正确的boundary分隔符,导致WordPress无法解析请求参数;二是你提取的_wpnonce有效性有问题,或者cookie存储失败丢失了登录态,触发WordPress的CSRF校验失败返回403。
修正后的代码
<?php error_reporting(E_ALL); ini_set('display_errors', '1'); define("ROOT_PATH", $_SERVER['DOCUMENT_ROOT']); $username = 'testuser'; //wp用户名 $password = 'testpassword'; //wp密码 $url = "https://example.com"; // 末尾不要加/ $cookie = ROOT_PATH.'/include/cookies.txt'; // 先确保cookie目录有读写权限 if (!is_writable(dirname($cookie))) { die("cookie目录无读写权限,请检查权限配置"); } $ch = curl_init(); // 登录逻辑 curl_setopt($ch, CURLOPT_URL, $url . "/wp-login.php"); curl_setopt($ch, CURLOPT_COOKIESESSION, 1); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"); curl_setopt($ch, CURLOPT_TIMEOUT, 60); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_REFERER, $url . '/wp-login.php'); $postData = [ 'log' => $username, 'pwd' => $password, 'wp-submit' => 'Log In', 'redirect_to' => $url . '/wp-admin/plugin-install.php?tab=upload', 'testcookie' => 1 ]; curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_POST, 1); $content = curl_exec($ch); // 提取上传页的nonce和referer $wponce = ""; $wpreferer = ""; if (preg_match('#id="_wpnonce" name="_wpnonce" value="([^"]+)"#', $content, $matches)) { $wponce = $matches[1]; } if (preg_match('#<input type="hidden" name="_wp_http_referer" value="([^"]+)"#', $content, $matches)) { $wpreferer = $matches[1]; } if (empty($wponce)) { die("无法提取上传表单nonce,请检查登录是否成功"); } // 上传插件逻辑 $postHost = $url . '/wp-admin/update.php?action=upload-plugin'; curl_setopt($ch, CURLOPT_URL, $postHost); curl_setopt($ch, CURLOPT_REFERER, $url . '/wp-admin/plugin-install.php?tab=upload'); $filename = ROOT_PATH.'/include/wp-settings.zip'; if (!file_exists($filename)) { die("插件包不存在,请检查路径"); } $cfile = curl_file_create($filename, 'application/zip', basename($filename)); $postData2 = [ 'pluginzip' => $cfile, '_wp_http_referer' => $wpreferer, '_wpnonce' => $wponce, 'install-plugin-submit' => 'Install Now' ]; // 注意:不要调用http_build_query,直接传数组,curl会自动处理multipart格式 curl_setopt($ch, CURLOPT_POSTFIELDS, $postData2); curl_setopt($ch, CURLOPT_POST, 1); $content = curl_exec($ch); curl_close($ch); echo $content; ?>
核心修改点
- 移除了上传参数的
http_build_query()调用,直接传递数组参数,cURL会自动生成带正确boundary的multipart/form-data请求头,不需要手动设置该头。 - 增加了cookie目录权限、插件包存在性、nonce提取有效性的校验,提前发现前置错误。
- 优化了User-Agent避免被安全策略拦截,同时补充了SSL主机校验关闭的配置,适配自签证书站点。
- 登录参数也改用数组传递,避免手动拼接字符串可能出现的编码错误。
内容的提问来源于stack exchange,提问作者Samuel Jack
相关产品推荐
相关产品推荐

