道者编程

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


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

看不清楚