PHP CURL模拟RESTFu风格
HTTP常规的请求方式:GET,POST,而RESTFull方法有: GET, POST, PUT, PATCH, DELETE等几种。要支持其他方法怎么办?
我们基于PHP强大的CURL函数封装一个:这里我只增加PUT和DELETE,可以扩展:
<?php /** * php curl 封装 * * @author jacken 2421102982 * @version 1.0 版本号 */ namespace Great\lib; interface interfaceCurl{ public static function url($url); public function send($data); public function header($list); public function time($time); public function post(); public function get(); public function put(); public function delete(); } class Curl implements interfaceCurl{ /** * 单例,CURL对象 * * @var object */ private static $instance; /** * 发送构造 * * @param string $url 远程地址 * @param string $send 发送的数据,数组键值对:key:字段,value:数据;也可任意数据 * @param list $header 设置发送头 * @param string $time 设置默认30秒超时 */ private $parameter = array( 'url' => '', 'send' => '', 'header' =>'', 'time' =>30 ); /** * 重置参数 * */ private function reset(){ $this->parameter['send'] = ''; $this->parameter['header'] = ''; } /** * 静态方法,类实例化连接调用 * * @access public * @param string $url 设置url * return pdo object */ public static function url($url){ if (!self::$instance instanceof self) { self::$instance = new Curl($url); } self::$instance->parameter['url'] = $url; return self::$instance; } /** * 请求 * * @access public * @param array $data 请求参数 */ public function send($data=''){ $this->parameter['send'] = $data; return $this; } /** * 设置http header参数 * * @access public * @param array $list header参数 */ public function header($list){ $this->parameter['header'] = $list; return $this; } /** * 设置超时时间 * * @access public * @param int $time 默认30秒 */ public function time($time=''){ if(!empty($time)){ $this->parameter['time'] = $time; } return $this; } /** * POST方式 */ public function post(){ return $this->execute('POST'); } /** * GET方式 */ public function get(){ return $this->execute('GET'); } /** * PUT方式 */ public function put(){ return $this->execute('PUT'); } /** * DELETE方式 */ public function delete(){ return $this->execute('DELETE'); } /** * 下载图片 * return Array * ( * [file_name] => images/555.jpeg * [dir] => E:\peptiles_php\images\news/ * [name] => 555.jpeg * [w] => 640 * [h] => 379 * [type] => jpeg * ) */ public function download($name,$dir=''){ $imageData = $this->execute('GET'); /* foreach($imageData->ResponseHeader as $key =>$val){ if( stristr($val,'Content-Type:') !== false ){ $type_str = $val; break; } } $type_list = (explode('/',$type_str)); $img_type = '.'.$type_list['1']; //图片类型 */ $imgData = getimagesize($this->parameter['url']); $type_list = (explode('/',$imgData['mime'])); $img_type = '.'.$type_list['1']; //图片类型 $img_name = $dir.$name; $tp = fopen($img_name.$img_type,'a'); //保存图片 fwrite($tp, $imageData->body); fclose($tp); //$imgData = getimagesize($img_name.$img_type); return [ 'file_name'=>$img_name.$img_type, 'dir'=>$dir, 'name'=>$name.$img_type, 'w'=>$imgData['0'], 'h'=>$imgData['1'], 'type'=>$type_list['1'] ]; } private function execute($type){ $ch = curl_init(); if($type == 'GET' && $this->parameter['send']) { curl_setopt($ch, CURLOPT_URL,$this->parameter['url'].'?'.$this->urlStr($this->parameter['send'])); } else{ curl_setopt($ch, CURLOPT_URL,$this->parameter['url']); } curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // https请求 不验证hosts curl_setopt($ch, CURLOPT_TIMEOUT,$this->parameter['time']); curl_setopt($ch, CURLOPT_HEADER, true); //返回http头 if($this->parameter['header']){ //发送指定header头 curl_setopt($ch, CURLOPT_HTTPHEADER, $this->parameter['header']); } switch ($type){ case "GET": curl_setopt($ch, CURLOPT_HTTPGET, true); break; case "POST": curl_setopt($ch, CURLOPT_POST,true); $this->sendData($ch); break; case "PUT": curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, "PUT"); $this->sendData($ch); break; case "DELETE": curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); $this->sendData($ch); break; } $result=curl_exec ($ch); if($result === false ){ //无法访问,或者网络异常等 code为0时表示异常,error返回异常原因 $data = (object) array('code' => 0,'ResponseHeader'=>'','ResponseInfo'=>'','body'=>'','error'=>curl_error($ch)); }else{ $data = $this->curlHeader($ch,$result); } curl_close ($ch); $this->reset(); return $data; } private function sendData($ch){ $fields = $this->urlStr($this->parameter['send']); //curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Length: ' . strlen($fields))); curl_setopt($ch, CURLOPT_POSTFIELDS,$fields); } /** * 格式化URL参数 * @return string $fields */ private function urlStr($fields){ return $fields = (is_array($fields)) ? http_build_query($fields) : $fields; } private function curlHeader($ch,$result){ $res = curl_getinfo($ch); $header = substr($result, 0, $res['header_size']); $header = explode("\r\n", $header); $body = substr($result, $res['header_size']); $response = array( 'code' => $res['http_code'], 'ResponseHeader'=>$header, 'ResponseInfo'=>$res, 'Authorization'=>$this->Authorization($header), 'body'=>$body ); return (object) $response; } /** * 获取响应的Authorization * @return string */ private function Authorization($data){ $Bearer = 'Authorization: Bearer'; foreach($data as $key){ if( strstr($key, $Bearer) ){ $list = explode($Bearer,$key); return $list['1']; } } return ''; } }
具体使用:
调用方法:
1:请求方法:get;post;put;delete (必填)
2:设置方法:
url:远程请求地址;(必填)
send:发送内容(多个字段发送采用:数组键值对,其他可以任何方式,如json,xml等,GET方式可以直接接在后面,也可以使用此参数)(选填)
header:设置发送头,数组 (选填)
time:超时时间,我这里默认30秒(选填)
//GET方式,发送a=123 $curl = Curl::url('127.0.0.1/4.php?a=123')->get(); //也可以用send方法发送数据 $curl = Curl::url('127.0.0.1/4.php')->send(['a'=>123])->get(); //设置 3秒超时 $curl = Curl::url('127.0.0.1/4.php?a=123')->time(3)->get(); //发送POST,字段a $curl = Curl::url('127.0.0.1/4.php')->send(['a'=>123])->post(); //发送POST json $data = json_encode(['a'=>123],JSON_UNESCAPED_UNICODE); $header= array('Content-Type: application/json'); //设置header,可设置多个,具体参考:CURLOPT_HTTPHEADER $curl = Curl::url('127.0.0.1/4.php')->send($data)->header($header)->post(); //发送PUT,字段a $curl = Curl::url('127.0.0.1/4.php')->send(['a'=>123])->put(); //发送DELETE,字段a $curl = Curl::url('127.0.0.1/4.php')->send(['a'=>123])->delete();返回方法:
$curl->code; //HTTP 响应状态码 0表示异常,可通过$curl->error,查看原因,其他为标准HTTP状态码 $curl->body; //响应内容,取数据就用这个 $curl->ResponseHeader;//响应头 数组 $curl->ResponseInfo; //其他响应信息 数组 此数据为 curl_getinfo 信息 $curl->Authorization; //获取响应的Authorization: Bearer返回4部分内容,可以根据需要提取。
php怎么获取?GET和POST都知道怎么获取,那么PUT和DELETE怎么获取?
通过判断参数$_SERVER['REQUEST_METHOD'],然后用parse_str设置即可:
// 设置 $_PUT if ('PUT' === $_SERVER['REQUEST_METHOD']) { parse_str(file_get_contents('php://input'), $_PUT); } echo $_PUT['a']; /************************************************************/ // 设置 $_DELETE if ('DELETE' === $_SERVER['REQUEST_METHOD']) { parse_str(file_get_contents('php://input'), $_DELETE); } echo $_DELETE['a']这样就可以了。