道者编程


PHP CURL模拟RESTFu风格

HTTP常规的请求方式:GET,POST,而RESTFull方法有: GET, POST, PUT, PATCH, DELETE等几种。要支持其他方法怎么办?

我们基于PHP强大的CURL函数封装一个:这里我只增加PUT和DELETE,可以扩展:

 
class Curl{
    private static $instance;

    private $parameter = array(
        'url' => '', //远程地址
        'send' => '',//发送的数据,数组键值对:key:字段,value:数据;也可任意数据
        'header' =>'', //设置发送头
        'time' =>30 //设置默认30秒超时
    );
    
    public static function url($url){
        if (!self::$instance instanceof self) { 
            self::$instance = new Curl($url);
        }
        return self::$instance;
    }

    private function __construct($url){
         $this->parameter['url'] = $url;
    }

    public function send($data){
        $this->parameter['send'] = $data;
        return $this;
    }

    public function header($list){
        $this->parameter['header'] = $list;
        return $this;
    }

     public function time($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');
    }
    
    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_SSL_VERIFYHOST,  2);
        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);
        return $data;
    }

    private function sendData($ch){
        if($this->parameter['send']){
            $fields = $this->urlStr($this->parameter['send']);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Length: ' . strlen($fields)));
            curl_setopt($ch, CURLOPT_POSTFIELDS,$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']);
        $body = substr($result, $res['header_size']);
        $response = array(
            'code' => $res['http_code'],
            'ResponseHeader'=>explode("\r\n", $header),
            'ResponseInfo'=>$res,
            'body'=>$body
        );
        return (object) $response;
    }
}
 

具体使用:

调用方法:

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


最新评论:
1楼 广东省广州市 电信 发表于 2019-10-16 17:22:16
66666666
共有 1 条记录  首页 上一页 下一页 尾页 1
我要评论:

看不清楚


道知

about me

身体是革命的本钱,健身,养生,运动,公众号都有!

链接