PHP OAuth集成Curl报错:CURLOPT_HTTPHEADER必须传入数组值
错误信息
致命错误:Uncaught TypeError: curl_setopt(): The CURLOPT_HTTPHEADER option must have an array value in /mnt/sdb1/home/18011506/public_html/BSCHons/WP/A1/OAuth.class.php:11 堆栈跟踪:#0 /mnt/sdb1/home/18011506/public_html/BSCHons/WP/A1/OAuth.class.php(11): curl_setopt() #1 /mnt/sdb1/home/18011506/public_html/BSCHons/WP/A1/OAuth.class.php(53): CurlHandler->__construct() #2 /mnt/sdb1/home/18011506/public_html/BSCHons/WP/A1/OAuth.class.php(151): OAuth->getAuth() #3 /mnt/sdb1/home/18011506/public_html/BSCHons/WP/A1/OAuth.class.php(144): ProviderHandler->processCode() #4 /mnt/sdb1/home/18011506/public_html/BSCHons/WP/A1/index.php(12): ProviderHandler->performAction() #5 {main} thrown in /mnt/sdb1/home/18011506/public_html/BSCHons/WP/A1/OAuth.class.php on line 11
问题根源
错误直接指向CurlHandler构造函数第11行:你给CURLOPT_HTTPHEADER传了字符串'Content-Type: application/x-www-form-urlencoded',但该选项要求必须传入数组类型的值。之前修改getAuth和setHeader方法的操作,并没有修复构造函数里的这行核心错误代码,所以问题持续存在。
修复方案
第一步:修正构造函数的头参数格式
修改CurlHandler类的构造函数,把字符串类型的请求头改成数组:
public function __construct($url=''){ $this->curl = curl_init($url); curl_setopt($this->curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($this->curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 将字符串改为数组格式 curl_setopt($this->curl, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']); $this->setPost(); }
第二步:处理请求头覆盖问题(可选)
后续在getAuth方法中调用setHeader设置Accept: application/json时,会覆盖构造函数里设置的Content-Type头。如果需要同时保留两个请求头,可调整getAuth的逻辑,将两个头合并到同一个数组:
public function getAuth($code) { $curl=new CurlHandler($this->tokenURL); // 合并多个请求头到数组中 $headers = [ 'Content-Type: application/x-www-form-urlencoded', 'Accept: application/json' ]; $curl->setHeader($headers); $params = array( 'grant_type' => 'authorization_code', 'client_id' => $this->cid, 'client_secret' => $this->secret, 'redirect_uri' => REDIRECTTOKENURI, 'code' => $code ); $curl->setQuery($params); $result = json_decode($curl->runCurl()); return $result; }
如果需要支持动态追加请求头而非覆盖,可修改setHeader方法:
public function setHeader($header) { // 获取当前已设置的请求头 $currentHeaders = curl_getinfo($this->curl, CURLINFO_HEADER_OUT) ? explode("\r\n", curl_getinfo($this->curl, CURLINFO_HEADER_OUT)) : []; // 处理单个字符串的情况 if (!is_array($header)) { $header = [$header]; } // 合并新旧请求头 $allHeaders = array_merge($currentHeaders, $header); curl_setopt($this->curl, CURLOPT_HTTPHEADER, $allHeaders); }
内容的提问来源于stack exchange,提问作者Harry Main

