123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- <?php
- namespace components\components;
- use Yii;
- use yii\base\Component;
- use yii\helpers\Json;
- use yii\web\HttpException;
- /**
- * CUrl Model
- * cURL 模型
- * ----------------
- * @version 1.0.0
- * @author Verdient。
- */
- class CUrl extends Component
- {
- /**
- * const CURLOPT_QUERY
- * 查询参数
- * -------------------
- * @author Verdient。
- */
- const CURLOPT_QUERY = 'query';
- /**
- * @var public $onlyContent
- * 只返回消息体
- * ------------------------
- * @author Verdient。
- */
- public $onlyContent = true;
- /**
- * @var private $_response
- * 响应内容
- * -----------------------
- * @author Verident。
- */
- private $_response = null;
- /**
- * @var private $_responseCode
- * 状态码
- * ---------------------------
- * @author Verdient。
- */
- private $_responseCode = null;
- /**
- * @var private $_options
- * 参数
- * ----------------------
- * @author Verdient。
- */
- private $_options = [];
- /**
- * @var private $_curl
- * cUrl实例
- * -------------------
- * @author Verdient。
- */
- private $_curl = null;
- /**
- * @var private $_defaultOptions
- * 默认参数
- * -----------------------------
- * @author Verdient。
- */
- private $_defaultOptions = [
- CURLOPT_USERAGENT => 'Yii2-CUrl-Agent',
- CURLOPT_TIMEOUT => 30,
- CURLOPT_CONNECTTIMEOUT => 30,
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_HEADER => false,
- CURLOPT_SSL_VERIFYPEER => false,
- CURLOPT_SSL_VERIFYHOST => false,
- CURLOPT_HTTPHEADER => [],
- self::CURLOPT_QUERY => [],
- ];
- /**
- * get(String $url, String $dataType)
- * 通过get方式获取数据
- * ------------------------------
- * @param String $url url地址
- * @param String $dataType 返回数据格式
- * ------------------------------------
- * @return Mixed
- * @author Verdient。
- */
- public function get($url, $dataType = null){
- return $this->_httpRequest('GET', $url, $dataType);
- }
- /**
- * head(String $url)
- * 通过head方式获取数据
- * --------------------
- * @param String $url url地址
- * --------------------------
- * @return Mixed
- * @author Verdient。
- */
- public function head($url){
- return $this->_httpRequest('HEAD', $url);
- }
- /**
- * post(String $url, String $dataType)
- * 通过post方式获取数据
- * -----------------------------------
- * @param String $url url地址
- * @param String $dataType 返回数据格式
- * ------------------------------------
- * @return Mixed
- * @author Verdient。
- */
- public function post($url, $dataType = null){
- return $this->_httpRequest('POST', $url, $dataType);
- }
- /**
- * put(String $url, String $dataType)
- * 通过put方式获取数据
- * -------------------
- * @param String $url url地址
- * @param String $dataType 返回数据格式
- * ------------------------------------
- * @return Mixed
- * @author Verdient。
- */
- public function put($url, $dataType = null){
- return $this->_httpRequest('PUT', $url, $dataType);
- }
- /**
- * delete(String $url, String $dataType)
- * 通过delete方式获取数据
- * -------------------------------------
- * @param String $url url地址
- * @param String $dataType 返回数据格式
- * ------------------------------------
- * @return Mixed
- * @author Verdient。
- */
- public function delete($url, $dataType = null){
- return $this->_httpRequest('DELETE', $url, $dataType);
- }
- /**
- * setHeader(Array $headers)
- * 设置发送的头部信息
- * --------------------------
- * @param Array $headers 头部信息
- * ------------------------------
- * @return Mixed
- * @author Verdient。
- */
- public function setHeader(Array $headers){
- $header = [];
- foreach($headers as $key => $value){
- $header[] = $key . ':' . $value;
- }
- $this->setOption(CURLOPT_HTTPHEADER, $header);
- }
- /**
- * setData(Array $data, Callable / String $callback = null)
- * 设置发送的数据
- * --------------------------------------------------------
- * @param Array $data 发送的数据
- * @param Callable / String $callback 回调函数
- * -------------------------------------------
- * @return Object
- * @author Verdient。
- */
- public function setData(Array $data, $callback = null){
- if(is_string($callback)){
- if(strtoupper($callback) == 'JSON'){
- $data = Json::encode($data);
- $this->setHeader(['Content-Type' => 'application/json', 'Content-Length' => strlen($data)]);
- return $this->setOption(CURLOPT_POSTFIELDS, $data);
- }
- }
- if(is_callable($callback)){
- $data = call_user_func($callback, $data);
- }
- return $this->setOption(CURLOPT_POSTFIELDS, $callback == null ? http_build_query($data) : $data);
- }
- /**
- * setQuery(Array $query)
- * 设置查询信息
- * ----------------------
- * @param Array $query 查询信息
- * ---------------------------
- * @return Mixed
- * @author Verdient。
- */
- public function setQuery(Array $query){
- $this->setOption(self::CURLOPT_QUERY, $query);
- }
- /**
- * setOption(String $key, Mixed $value)
- * 设置选项
- * ------------------------------------
- * @param String $key 选项名称
- * @param Mixed $value 选项内容
- * ----------------------------
- * @return Object
- * @author Verdient。
- */
- public function setOption($key, $value){
- if(isset($this->_options[$key]) && is_array($this->_options[$key])){
- $this->_options[$key] = array_merge($this->_options[$key], $value);
- }else{
- $this->_options[$key] = $value;
- }
- return $this;
- }
- /**
- * setOptions(Array $options)
- * 批量设置选项
- * --------------------------
- * @param String $options 选项集合
- * -------------------------------
- * @return Object
- * @author Verdient。
- */
- public function setOptions($options){
- foreach($options as $key => $value){
- $this->setOption($key, $value);
- }
- return $this;
- }
- /**
- * unsetOption(String $key)
- * 删除选项
- * ------------------------
- * @param String $key 选项名称
- * --------------------------
- * @return Object
- * @author Verdient。
- */
- public function unsetOption($key){
- if(isset($this->_options[$key])){
- unset($this->_options[$key]);
- }
- return $this;
- }
- /**
- * resetOptions()
- * 重置选项
- * --------------
- * @return Object
- * @author Verdient。
- */
- public function resetOptions(){
- if (isset($this->_options)) {
- $this->_options = [];
- }
- return $this;
- }
- /**
- * reset()
- * 重置
- * -------
- * @return Object
- * @author Verdient。
- */
- public function reset(){
- if($this->_curl !== null){
- @curl_close($this->_curl);
- }
- $this->_curl = null;
- $this->_options = [];
- $this->_response = null;
- $this->_responseCode = null;
- return $this;
- }
- /**
- * getOption(String $key)
- * 获取选项内容
- * ----------------------
- * @param String $key 选项名称
- * ---------------------------
- * @return Object
- * @author Verdient。
- */
- public function getOption($key){
- $mergesOptions = $this->getOptions();
- return isset($mergesOptions[$key]) ? $mergesOptions[$key] : false;
- }
- /**
- * getOptions()
- * 获取所有的选项内容
- * ------------------
- * @return Object
- * @author Verdient。
- */
- public function getOptions(){
- return $this->_options + $this->_defaultOptions;
- }
- /**
- * getInfo(String $opt)
- * 获取连接资源句柄的信息
- * ----------------------
- * @param String $opt 选项名称
- * ---------------------------
- * @return Object
- * @author Verdient。
- */
- public function getInfo($opt = null){
- if($this->_curl !== null && $opt === null){
- return curl_getinfo($this->_curl);
- }else if($this->_curl !== null && $opt !== null){
- return curl_getinfo($this->_curl, $opt);
- }else{
- return [];
- }
- }
- /**
- * getResponse()
- * 获取响应内容
- * -------------
- * @return Mixed
- * @author Verdient。
- */
- public function getResponse(){
- return $this->_response;
- }
- /**
- * getResponseCode()
- * 获取状态码
- * -----------------
- * @return Integer
- * @author Verdient。
- */
- public function getResponseCode(){
- return $this->_responseCode;
- }
- /**
- * _httpRequest(String $method, String $url, String $dataType)
- * http请求
- * -----------------------------------------------------------
- * @param String $method 请求方式
- * @param String $url 请求地址
- * @param String $dataType 返回数据格式
- * ------------------------------------
- * @return Object
- * @author Verdient。
- */
- private function _httpRequest($method, $url, $dataType = null){
- $this->setOption(CURLOPT_CUSTOMREQUEST, strtoupper($method));
- if($method === 'HEAD'){
- $this->setOption(CURLOPT_NOBODY, true);
- $this->unsetOption(CURLOPT_WRITEFUNCTION);
- }
- $query = $this->getOption(self::CURLOPT_QUERY);
- if(!empty($query)){
- $url = $url . '?' . http_build_query($query);
- }
- $this->_curl = curl_init($url);
- $options = $this->getOptions();
- $curlOptions = [];
- foreach($options as $key => $value){
- if(is_numeric($key)){
- $curlOptions[$key] = $value;
- }
- }
- curl_setopt_array($this->_curl, $curlOptions);
- $body = curl_exec($this->_curl);
- if($body === false){
- $errorCode = curl_errno($this->_curl);
- Yii::error(['code' => $errorCode, 'type' => curl_strerror($errorCode), 'message' => curl_error($this->_curl), 'info' => curl_getinfo($this->_curl), 'version' => curl_version()], __METHOD__);
- switch($errorCode){
- case 7:
- throw new HttpException(504, 'CUrl requset timeout');
- break;
- default:
- throw new HttpException(502, 'CUrl requset error(' . $errorCode . ')');
- break;
- }
- }
- $this->_responseCode = curl_getinfo($this->_curl, CURLINFO_HTTP_CODE);
- $this->_response = $body;
- if($this->getOption(CURLOPT_CUSTOMREQUEST) === 'HEAD'){
- $this->reset();
- return true;
- }
- Yii::trace(['method' => $method, 'url' => $url, 'options' => $options, 'code' => $this->_responseCode, 'response' => $this->_response], __METHOD__);
- switch(strtoupper($dataType)){
- case 'JSON':
- try{
- $this->_response = Json::decode($this->_response);
- }catch(\Exception $e){
- Yii::warning(['method' => $method, 'url' => $url, 'options' => $options, 'responseCode' => $this->_responseCode, 'response' => $this->_response], __METHOD__);
- }
- break;
- }
- if($this->onlyContent === true){
- $response = $this->_response;
- }else{
- $response = ['code' => $this->_responseCode, 'content' => $this->_response];
- }
- $this->reset();
- return $response;
- }
- }
|