大纲
- 实现可用功能
- 明白自己使用方式
- 使用方便
- 获取结果方便
实现功能
弄一个可以使用的类 原型
以下代码就可以实现一个 curl
的功能
代码:
class Curl
{
protected $ch = '';
protected $log= [];
protected $debug= true;
protected $data= [];
public function request()
{
$url = 'http://blog.xyj2156.top';
$data = [];
$ch = curl_init();
$this -> ch = $ch;
$this -> debug && $this -> log[] = '开始设置请求公共数据。';
curl_setopt($this -> ch, CURLOPT_URL, $this -> option['url']);
curl_setopt($this -> ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($this -> ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($this -> ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this -> ch, CURLOPT_HEADER, 1);
curl_setopt($this -> ch, CURLOPT_TIMEOUT, $this -> timeout);
$this -> debug && $this -> log[] = '设置请求公共数据完成。';
$tmp = curl_exec($this -> ch);
return $tmp;
}
}
明白自己的使用方式
为了让自己用起来舒服, 添加了很多额外部分。
添加昨天使用的 数组转对象后 可以对象方式并能数组方式同时访问,方便获取,同时可以转换回来
地址 https://blog.xyj2156.top/posts/php_array_converted_object_and_array
- 添加 各种适合自己的方法
- 各种魔术方法
- 调用起来各种方便
- 获取支持对象调用 数组调用 转换成数组等方法
最终 是下面这个代码了。
namespace Curl;
use \Curl\CurlBody;
use \Curl\CurlHeader;
use \Curl\CurlCookie;
class Curl
{
protected $isPost = false;
protected $debug = true;
protected $log = [];
protected $ch = null;
protected $option = [];
protected $timeout = 10;
protected $error = '';
protected $errorno = 0;
protected $response = [
'cookie' => '',
'result' => '',
'header' => '',
'body' => ''
];
public function __construct($url = null, $data = null)
{
$this -> debug && $this -> log[] = '构造对象';
$this -> ch = curl_init();
if(!is_null($url) && preg_match('/^https?:\/\/[\w\.]+[^\.]\/?[\w\#\?=]?$/', $url)){
$this -> option ['url'] = $url;
}
$this -> data($data);
}
public function post($data = null)
{
$this -> debug && $this -> log[] = '设置 post 数据。'.var_export($data, true);
$this -> isPost = true;
return $this -> data($data);
}
public function data($data){
if(empty($this -> option ['data'])){
$this -> option ['data'] = [];
}
if(!is_null($data)){
if(is_array($data)){
$tmp = $data;
} else if(is_string($data) && preg_match('/([^\&]+=[^\&]*)/', $data)){
parse_str($data, $tmp);
}
if(isset($tmp))
$this -> option ['data'] = array_merge($this -> option ['data'], $tmp);
$this -> debug && $this -> log[] = '设置数据完成。';
}
return $this;
}
public function get($data = null)
{
$this -> debug && $this -> log[] = '设置 get 数据。';
$this -> isPost = false;
return $this -> data($data);
}
public function cookie ($cookie = null)
{
if(empty($this -> option ['cookie'])){
$this -> option ['cookie'] = [];
}
if(!is_null($cookie)){
if(is_array($cookie)){
$tmp = $cookie;
} else if (is_string($cookie)){
parse_str($data, $tmp);
}
if( isset ($tmp))
$this -> option['cookie'] = array_merge($this -> option['cookie'], $tmp);
}
return $this;
}
public function request()
{
if (empty($this -> option)) {
$this ->debug && $this -> log[] = '由于没有 option 导致 调用 request 直接返回 this';
$this -> error = '您没有设置任何选项';
return $this;
}
if (empty($this -> option['url']) || !is_string($this -> option['url'])) {
$this -> error = '您没有正确设置 URL url是:'.var_export($this -> option['url'], 1);
return $this;
}
if (empty($this -> ch)) {
$this -> ch = curl_init();
}
$this -> setOpt();
if($this -> isPost){
curl_setopt($this -> ch, CURLOPT_POST, true);
if(!empty($this -> option['data'])){
curl_setopt($this -> ch, CURLOPT_POSTFIELDS, $this -> option['data']);
}
} else {
curl_setopt($this -> ch, CURLOPT_POST, false);
if(!empty($this -> option['data'])){
$param = http_build_query( $this -> option['data'] );
curl_setopt($this -> ch, CURLOPT_URL, $this -> option['url'].'?'.$param);
}
}
if(!empty($this -> option['cookie']) || (isset($this -> response) && isset($this -> response['cookie']) && is_array($this -> response['cookie']))){
empty($this -> option['cookie']) && ($this -> option['cookie'] = []);
$this -> option['cookie'] = array_merge($this -> option['cookie'], $this -> response['cookie']);
$cookie = http_build_query($this -> option['cookie']);
$cookie = str_replace('&', ';', $cookie);
curl_setopt($this -> ch, CURLOPT_COOKIE, $cookie);
}
if(!empty($this -> option['header'])){
curl_setopt($this -> ch, CURLOPT_HTTPHEADER, $this -> option['header']);
}
$this -> option = [];
$tmp = curl_exec($this -> ch);
$this -> response['result'] = $tmp;
$this -> error = curl_error($this -> ch);
$this -> errorno = curl_errno($this -> ch);
return $this -> parseResponse($tmp);
}
public function __get($name)
{
$this -> debug && $this -> log[] = "由于 获取 {$name} 导致调用魔术方法 get 。";
switch ($name) {
case 'result':
case 'content':
case 'body' :
case 'cookie':
case 'header':
case 'response':
$this -> request();
switch ($name) {
case 'result':
case 'content':
return $this -> response['result'];
case 'body' :
return $this -> response['body'];
case 'cookie':
return $this -> response['cookie'];
case 'header':
return $this -> response['header'];
case 'response':
return $this -> response;
}
case 'option':
return $this -> option;
case 'error':
return $this -> error;
case 'url':
return $this -> option['url'];
default:
return $this;
}
return $this;
}
public function __set($name, $value)
{
$this -> debug && $this -> log[] = "由于 设置 {$name} 导致调用魔术方法 set 值是".var_export($value, true);
switch ($name) {
case 'method':
if(strtolower($value) == 'post'){
$this -> isPost = true;
} else {
$this -> isPost = false;
}
break;
case 'cookie' :
if($value){
$this -> option['cookie'] = $value;
}
break;
case 'data' :
if($value){
$this -> data($value);
}
break;
case 'url' :
if($value){
$this -> option['url'] = ($value);
}
break;
case 'header' :
if($value){
$this -> option['header'] = ($value);
}
break;
}
return $this;
}
private function setOpt()
{
$this -> debug && $this -> log[] = '开始设置请求公共数据。';
curl_setopt($this -> ch, CURLOPT_URL, $this -> option['url']);
curl_setopt($this -> ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($this -> ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($this -> ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this -> ch, CURLOPT_HEADER, 1);
curl_setopt($this -> ch, CURLOPT_TIMEOUT, $this -> timeout);
$this -> debug && $this -> log[] = '设置请求公共数据完成。';
}
private function parseResponse($raw)
{
$this -> debug && $this -> log[] = '开始 处理 返回的数据';
if($raw){
$tmp = explode("\r\n\r\n", $raw);
$body = array_pop($tmp);
$header = array_pop($tmp);
$re = preg_match_all("/(?:set\-cookie:([^\r\n=]+)=([^\r\n;]*);)/i", $header, $matches);
$cookie = [];
if($re && !empty($matches) && !empty($matches[1]) && !empty($matches[2])){
foreach ($matches[1] as $k => $v) {
$a = !empty($matches[2][$k]);
$cookie[$v] = $a ? $matches[2][$k] : '';
}
}
$tmpH = explode("\r\n", $header);
foreach ($tmpH as $v) {
$tmp = preg_split('/[:;]/', $v, 2);
$a = array_shift($tmp);
$b = array_shift($tmp);
if(!$b){
$tmp = explode(' ', $a, 2);
$a = array_shift($tmp);
$b = array_shift($tmp);
}
$tmpH[$a] = $b;
}
$cookieObj = new CurlCookie($cookie);
$tmpH['Set-Cookie'] = $cookieObj;
$json = json_decode($body, 1);
$this -> response['header'] = new CurlHeader($tmpH);
$this -> response['body'] = $json ? new CurlBody($json) : $body;
$this -> response['cookie'] = $cookieObj;
} else {
$this -> response['header'] = '';
$this -> response['body'] = '';
$this -> response['cookie'] = '';
}
$this -> debug && $this -> log[] = '返回数据处理完成。';
return $this;
}
public function __call($name, $value){
$this -> debug && $this -> log[] = "调用 {$name} 引起 魔术方法 call 值:".var_export($value, true);
switch ($name) {
case 'url':
$this -> option['url'] = array_shift($value);
break;
case 'error' :
return $this -> error;
}
return $this;
}
private function __clone(){}
}
关于使用方便
上面的类写的一些魔术方法,自我感觉使用还是挺方便的。
比如:
post(['a' => 1])
这样就能实现 post 方式请求地址。应该还有不足,比如:put
show
delete
等,都没有实现。get(['a' => 1])
这样能用get
方式请求。post('a=1&b=2')
这样也能请求。而且 支持多次调用post(['a' => 1]) -> post('b=2&c=3') -> post(['d' => 4]) -> data('e=5')
。- 设置
$obj -> data = ['aa' => 11]
和->data(['aa' => 11])
功能完全一样。 - 有一点就是
post
还是get
以最后一个为准。
获取更方便
- 返回结果是 json 的时候,返回结果中所有的内容可以用对象方式获取,也可以用数组方式获取,也可以混合获取,还支持 任意一级变成数组 直接在后面使用
-> toArray()
就可以了。
xml 没有解析。(待续……)
评论已关闭