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'] 这样就可以了。