PageRenderTime 26ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/application/library/Comm/Request/Single.php

https://gitlab.com/flyhope/Hiblog
PHP | 276 lines | 129 code | 31 blank | 116 comment | 21 complexity | cfc0503467ea4ccb0f0b71a2037bc154 MD5 | raw file
  1. <?php
  2. /**
  3. * HTTP Request请求,支持批量处理
  4. *
  5. * @author Chengxuan <i@chengxuan.li>
  6. * @package Comm
  7. */
  8. namespace Comm\Request;
  9. class Single {
  10. /**
  11. * CURL资源
  12. *
  13. * @var resource
  14. */
  15. protected $_ch;
  16. /**
  17. * 设置头信息
  18. *
  19. * @var array
  20. */
  21. protected $_headers = array();
  22. /**
  23. * CURL配置
  24. *
  25. * @var array
  26. */
  27. protected $_option = array();
  28. /**
  29. * 构造方法
  30. *
  31. * @param string $url URL
  32. * @param array $post_data 提交的数据内容
  33. *
  34. * @return void
  35. */
  36. public function __construct($url=null, array $post_data=null) {
  37. $this->_ch = curl_init();
  38. $this->_option[CURLOPT_RETURNTRANSFER] = true;
  39. //跳过证书验证
  40. if(defined('CURLOPT_SSL_VERIFYPEER')) {
  41. $this->_option[CURLOPT_SSL_VERIFYPEER] = false;
  42. }
  43. if(defined('CURLOPT_SSL_VERIFYPEER')) {
  44. $this->_option[CURLOPT_SSL_VERIFYPEER] = false;
  45. }
  46. $url !== null && $this->setUrl($url);
  47. $post_data !== null && $this->setPostData($post_data);
  48. }
  49. /**
  50. * 析构方法
  51. *
  52. * @return void
  53. */
  54. public function __destruct() {
  55. //关闭CURL句柄
  56. curl_close($this->_ch);
  57. }
  58. /**
  59. * 设置请求的URL
  60. *
  61. * @param string $url URL
  62. *
  63. * @return \Comm\Request\Single
  64. */
  65. public function setUrl($url) {
  66. $this->_option[CURLOPT_URL] = $url;
  67. return $this;
  68. }
  69. /**
  70. * 设置提交参数
  71. * @param mixed $post_param 提交参数,字符串或数组
  72. * @param boolean $build_query 是否自动执行http_build_query
  73. *
  74. * @return \Comm\Request\Single
  75. */
  76. public function setPostData($post_param, $build_query=true) {
  77. if($build_query && is_array($post_param)) {
  78. $post_param = array_filter($post_param, function($value) {
  79. return $value !== null;
  80. });
  81. $post_param = http_build_query($post_param);
  82. }
  83. $this->_option[CURLOPT_POSTFIELDS] = $post_param;
  84. return $this;
  85. }
  86. /**
  87. * 请求头
  88. *
  89. * @param array $headers HTTP头信息
  90. *
  91. * @return \Comm\Request\Single
  92. */
  93. public function setHeader(array $headers) {
  94. $this->_headers = $headers;
  95. return $this;
  96. }
  97. /**
  98. * 追加Header信息
  99. *
  100. * @param array $headers
  101. *
  102. * @return \Comm\Request\Single
  103. */
  104. public function appendHeader(array $headers) {
  105. $this->_headers = array_merge($this->_headers, $headers);
  106. return $this;
  107. }
  108. /**
  109. * 设置用户代理
  110. *
  111. * @param string $user_agent 用户代理字符串
  112. *
  113. * @return \Comm\Request\Single
  114. */
  115. public function setUserAgent($user_agent) {
  116. $this->_option[CURLOPT_USERAGENT] = $user_agent;
  117. return $this;
  118. }
  119. /**
  120. * 设置CURL选项
  121. *
  122. * @param int $key
  123. * @param mixed $value
  124. *
  125. * @return \Comm\Request\Single
  126. */
  127. public function setOption($key, $value) {
  128. $this->_option[$key] = $value;
  129. return $this;
  130. }
  131. /**
  132. * 设置超时时间
  133. *
  134. * @param int $timeout 设置超时时间
  135. *
  136. * @return \Comm\Request\Single
  137. */
  138. public function setTimeout($timeout) {
  139. if(defined('CURLOPT_TIMEOUT_MS')) {
  140. $timeout *= 1000;
  141. $this->_option[CURLOPT_TIMEOUT_MS] = $timeout;
  142. } else {
  143. $this->_option[CURLOPT_TIMEOUT] = ceil($timeout);
  144. }
  145. return $this;
  146. }
  147. /**
  148. * 获取CURL资源
  149. *
  150. * @return resource
  151. */
  152. public function fetchCurl() {
  153. if($this->_headers) {
  154. $this->_option[CURLOPT_HTTPHEADER] = $this->_headers;
  155. }
  156. curl_setopt_array($this->_ch, $this->_option);
  157. return $this->_ch;
  158. }
  159. /**
  160. * 获取CLI命令行中的curl命令
  161. *
  162. * @return string
  163. */
  164. public function fetchCurlCli() {
  165. $url = addslashes($this->_option[CURLOPT_URL]);
  166. $result = "curl \"{$url}\"";
  167. if(isset($this->_option[CURLOPT_COOKIE])) {
  168. $cookie = addslashes($this->_option[CURLOPT_COOKIE]);
  169. $result .= " -b \"{$cookie}\"";
  170. }
  171. if(isset($this->_option[CURLOPT_USERAGENT])) {
  172. $user_agent = addslashes($this->_option[CURLOPT_USERAGENT]);
  173. $result .= " -A \"{$user_agent}\"";
  174. }
  175. if(isset($this->_option[CURLOPT_POSTFIELDS])) {
  176. if(!is_array($this->_option[CURLOPT_POSTFIELDS])) {
  177. $post = addslashes($this->_option[CURLOPT_POSTFIELDS]);
  178. $result .= " -d \"{$post}\"";
  179. }
  180. }
  181. if(isset($this->_headers)) {
  182. foreach($this->_headers as $header) {
  183. $header = addslashes($header);
  184. $result .= " -H \"{$header}\"";
  185. }
  186. }
  187. return $result;
  188. }
  189. /**
  190. * 执行CURL请求
  191. *
  192. * @param string $response_header 引用返回响应头信息
  193. *
  194. * @return string
  195. */
  196. public function exec(& $response_header = null) {
  197. $numargs = func_num_args();
  198. if($numargs) {
  199. curl_setopt($this->_ch, CURLOPT_HEADER, true);
  200. }
  201. $this->fetchCurl($this->_ch);
  202. $response = curl_exec($this->_ch);
  203. //执行失败抛出异常
  204. $curl_info = curl_getinfo($this->_ch);
  205. if($response === false) {
  206. $code = curl_errno($this->_ch);
  207. $message = curl_error($this->_ch);
  208. $metadata = array(
  209. 'info' => $curl_info,
  210. 'curl_cli_command' => $this->fetchCurlCli(),
  211. );
  212. throw new \Exception\Request($message, $code, $metadata);
  213. }
  214. if($numargs && !empty($curl_info['http_code'])) {
  215. list($response_header, $result) = explode("\r\n\r\n", $response);
  216. } else {
  217. $result = $response;
  218. }
  219. unset($response);
  220. return $result;
  221. }
  222. /**
  223. * 获取信息
  224. *
  225. * @return mixed
  226. */
  227. public function showInfo() {
  228. return curl_getinfo($this->_ch);
  229. }
  230. /**
  231. * 加载一个文件上传
  232. *
  233. * @param string $file_path 文件路径
  234. *
  235. * @return mixed
  236. */
  237. static public function file($file_path) {
  238. if(class_exists('\CURLFile', false)) {
  239. $result = new \CURLFile($file_path);
  240. } else {
  241. $result = "@{$file_path}";
  242. }
  243. return $result;
  244. }
  245. }