使用PHP的cURL向Moodle插入数据时遭遇404错误求助
问题描述
我在PHP项目中编写了一段cURL代码,想要将数据从PHP服务器发送至Moodle服务器的数据库,实现数据插入操作,但执行时出现了404错误。
我的代码
$data = array( 'auth'=>'Manual', 'confirmed'=>1, 'mnethostid'=>1, 'username' =>$email_address, 'password'=>password_hash('$password', PASSWORD_DEFAULT), 'firstname'=>$first_name, 'lastname'=>$last_name, 'email'=>$email_address, 'country'=>$country, 'address'=>$full_address1 ); echo "<pre>"; print_r($data); $data_json = json_encode($data); echo "<pre>"; print_r($data_json); $url = 'http://localhost/moodles/server/moodle/user/editadvanced.php?id=-1'; $headers = [ 'X-Apple-Tz: 0', 'X-Apple-Store-Front: 143444,12', 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Encoding: gzip, deflate', 'Accept-Language: en-US,en;q=0.5', 'Cache-Control: no-cache', 'Content-Type: application/x-www-form-urlencoded; charset=utf-8', 'Host: www.example.com', 'Referer: http://www.example.com/index.php', // Your referrer address 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:28.0) Gecko/20100101 Firefox/28.0', 'X-MicrosoftAjax: Delta=true' ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_FOLLOWLOCATION, true); // follow redirects curl_setopt($ch,CURLOPT_ENCODING, ""); // handle all encodings // curl_setopt($ch,CURLOPT_USERAGENT, "spider"); // who am i curl_setopt($ch,CURLOPT_AUTOREFERER, true); // set referer on redirect curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,15); // timeout on connect curl_setopt($ch,CURLOPT_TIMEOUT,15); // timeout on response curl_setopt($ch,CURLOPT_MAXREDIRS,10); // stop after 10 redirects $userpwd = base64_encode($uname.":".$pass); curl_setopt($ch, CURLOPT_HEADER,true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authentication : Basic','Content-Type: application/json')); curl_setopt($ch, CURLOPT_USERPWD, $userpwd); //'Content-Length: ' . strlen($data_json))); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_POSTREDIR, 3); curl_setopt($ch,CURLOPT_HTTPAUTH,CURLAUTH_DIGEST); curl_setopt($ch, CURLOPT_POSTFIELDS,$data_json); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); if(curl_exec($ch) === false) { echo 'Curl error: ' . curl_error($ch); } else { $response = curl_exec($ch); } echo "<br>"; var_dump($response); exit; curl_close($ch); $json_a2 = json_decode($response, true);
错误情况
代码执行后返回404错误。
排查与解决方法
1. 先确认请求URL的有效性
404的核心原因是请求的资源不存在,先手动在浏览器访问你设置的URL:http://localhost/moodles/server/moodle/user/editadvanced.php?id=-1:
- 如果浏览器也返回404,说明路径写错了。检查Moodle的实际安装目录,比如是否多写了
server层级?正常Moodle用户编辑页面路径一般是http://localhost/moodle/user/editadvanced.php?id=-1,根据实际部署路径调整。 - 如果浏览器能打开页面,再看是否需要登录才能访问——Moodle后台页面大多需要权限,未登录状态下用cURL请求会被重定向到登录页,可能导致路径变化触发404。
2. 改用Moodle官方Web Services API交互
直接请求editadvanced.php这类前端页面是错误的,这类页面是给浏览器渲染用的,并非API接口。Moodle提供了标准的Web Services来实现数据交互,正确做法是:
- 登录Moodle后台,启用Web Services,生成访问令牌(token)。
- 使用
core_user_create_users接口创建用户,请求URL格式示例:http://localhost/moodle/webservice/rest/server.php?wstoken=你的令牌&wsfunction=core_user_create_users&moodlewsrestformat=json - 调整发送的数据格式,需将用户数据包裹在
users数组中,示例:$data = array( 'users' => array( array( 'auth' => 'manual', 'confirmed' => 1, 'mnethostid' => 1, 'username' => $email_address, 'password' => $password, // 直接传明文,Moodle会自动加密 'firstname' => $first_name, 'lastname' => $last_name, 'email' => $email_address, 'country' => $country, 'address' => $full_address1 ) ) );
3. 修复cURL代码中的明显错误
如果暂时要测试页面请求,你的代码存在以下问题:
- 重复设置HTTP请求头:先设置了认证和JSON类型的头,之后又用
$headers覆盖,导致之前的设置失效。 - 认证方式冲突:同时启用了Basic认证(
CURLOPT_USERPWD)和Digest认证(CURLAUTH_DIGEST),二者选其一即可,Moodle一般用Basic或令牌认证。 - Content-Type不匹配:发送的是JSON数据,但请求头里的
Content-Type是application/x-www-form-urlencoded,格式不匹配会导致服务器无法解析。 - 重复执行请求:代码中
curl_exec执行了两次,一次判断错误,一次获取响应,会造成冗余请求且可能引发异常。 - Host头不匹配:请求的是
localhost,但头里的Host是www.example.com,服务器无法正确识别站点,也可能导致404。
内容的提问来源于stack exchange,提问作者siddhu subrahmanyam
相关产品推荐
相关产品推荐

