[关闭]
@a5635268 2015-10-10T17:44:02.000000Z 字数 16638 阅读 1077

【PHPsocket编程专题(实战篇②)】兼容 Curl/Socket/Stream 的 HTTP 操作类

PHP


  1. <?php
  2. /************************************************************
  3. * 描述:HTTP操作类
  4. * 作者:heiyeluren
  5. * 创建:2009/12/13 04:43
  6. * 修改:2009/12/16 10:30 实现基本HTTP各种接口操作支持
  7. ************************************************************/
  8. /**
  9. * HTTP功能工厂方法类
  10. * 调用示例代码:
  11. * try {
  12. * $http = Http::factory('http://www.baidu.com', Http::TYPE_SOCK );
  13. * echo $http->get();
  14. * $http = Http::factory('http://127.0.0.1/test/i.php', Http::TYPE_SOCK );
  15. * echo $http->post('', array('user'=>'我们', 'nick'=>'ASSADF@#!32812989+-239%ASDF'), '', array('aa'=>'bb', 'cc'=>'dd'));
  16. * } catch (Exception $e) {
  17. * echo $e->getMessage();
  18. * }
  19. */
  20. class Http{
  21. /**
  22. * @var 使用 CURL
  23. */
  24. const TYPE_CURL = 1;
  25. /**
  26. * @var 使用 Socket
  27. */
  28. const TYPE_SOCK = 2;
  29. /**
  30. * @var 使用 Stream
  31. */
  32. const TYPE_STREAM = 3;
  33. /**
  34. * 保证对象不被clone
  35. */
  36. private function __clone(){
  37. }
  38. /**
  39. * 构造函数
  40. */
  41. private function __construct(){
  42. }
  43. /**
  44. * HTTP工厂操作方法
  45. * @param string $url 需要访问的URL
  46. * @param int $type 需要使用的HTTP类
  47. * @return object
  48. */
  49. public static function factory($url = '' , $type = self::TYPE_SOCK){
  50. if ($type == '') {
  51. $type = self::TYPE_SOCK;
  52. }
  53. switch ($type) {
  54. case self::TYPE_CURL :
  55. if (!function_exists('curl_init')) {
  56. throw new Exception(__CLASS__ . " PHP CURL extension not install");
  57. }
  58. $obj = Http_Curl::getInstance($url);
  59. break;
  60. case self::TYPE_SOCK :
  61. if (!function_exists('fsockopen')) {
  62. throw new Exception(__CLASS__ . " PHP function fsockopen() not support");
  63. }
  64. $obj = Http_Sock::getInstance($url);
  65. break;
  66. case self::TYPE_STREAM :
  67. if (!function_exists('stream_context_create')) {
  68. throw new Exception(__CLASS__ . " PHP Stream extension not install");
  69. }
  70. $obj = Http_Stream::getInstance($url);
  71. break;
  72. default:
  73. throw new Exception("http access type $type not support");
  74. }
  75. return $obj;
  76. }
  77. /**
  78. * 生成一个供Cookie或HTTP GET Query的字符串
  79. * @param array $data 需要生产的数据数组,必须是 Name => Value 结构
  80. * @param string $sep 两个变量值之间分割的字符,缺省是 &
  81. * @return string 返回生成好的Cookie查询字符串
  82. */
  83. public static function makeQuery($data , $sep = '&'){
  84. $encoded = '';
  85. while (list($k , $v) = each($data)) {
  86. $encoded .= ($encoded ? "$sep" : "");
  87. $encoded .= rawurlencode($k) . "=" . rawurlencode($v);
  88. }
  89. return $encoded;
  90. }
  91. }
  92. /**
  93. * 使用CURL 作为核心操作的HTTP访问类
  94. * @desc CURL 以稳定、高效、移植性强作为很重要的HTTP协议访问客户端,必须在PHP中安装 CURL 扩展才能使用本功能
  95. */
  96. class Http_Curl{
  97. /**
  98. * @var object 对象单例
  99. */
  100. static $_instance = NULL;
  101. /**
  102. * @var string 需要发送的cookie信息
  103. */
  104. private $cookies = '';
  105. /**
  106. * @var array 需要发送的头信息
  107. */
  108. private $header = array();
  109. /**
  110. * @var string 需要访问的URL地址
  111. */
  112. private $uri = '';
  113. /**
  114. * @var array 需要发送的数据
  115. */
  116. private $vars = array();
  117. /**
  118. * 构造函数
  119. * @param string $configFile 配置文件路径
  120. */
  121. private function __construct($url){
  122. $this->uri = $url;
  123. }
  124. /**
  125. * 保证对象不被clone
  126. */
  127. private function __clone(){
  128. }
  129. /**
  130. * 获取对象唯一实例
  131. * @param string $configFile 配置文件路径
  132. * @return object 返回本对象实例
  133. */
  134. public static function getInstance($url = ''){
  135. if (!(self::$_instance instanceof self)) {
  136. self::$_instance = new self($url);
  137. }
  138. return self::$_instance;
  139. }
  140. /**
  141. * 设置需要发送的HTTP头信息
  142. * @param array /string 需要设置的头信息,可以是一个 类似 array('Host: example.com', 'Accept-Language: zh-cn') 的头信息数组
  143. * 或单一的一条类似于 'Host: example.com' 头信息字符串
  144. * @return void
  145. */
  146. public function setHeader($header){
  147. if (emptyempty($header)) {
  148. return;
  149. }
  150. if (is_array($header)) {
  151. foreach ($header as $k => $v) {
  152. $this->header[] = is_numeric($k) ? trim($v) : (trim($k) . ": " . trim($v));
  153. }
  154. } elseif (is_string($header)) {
  155. $this->header[] = $header;
  156. }
  157. }
  158. /**
  159. * 设置Cookie头信息
  160. * 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
  161. * @param string /array 需要设置的Cookie信息,一个类似于 'name1=value1&name2=value2' 的Cookie字符串信息,
  162. * 或者是一个 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  163. * @return void
  164. */
  165. public function setCookie($cookie){
  166. if (emptyempty($cookie)) {
  167. return;
  168. }
  169. if (is_array($cookie)) {
  170. $this->cookies = Http::makeQuery($cookie , ';');
  171. } elseif (is_string($cookie)) {
  172. $this->cookies = $cookie;
  173. }
  174. }
  175. /**
  176. * 设置要发送的数据信息
  177. * 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
  178. * @param array 设置需要发送的数据信息,一个类似于 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  179. * @return void
  180. */
  181. public function setVar($vars){
  182. if (emptyempty($vars)) {
  183. return;
  184. }
  185. if (is_array($vars)) {
  186. $this->vars = $vars;
  187. }
  188. }
  189. /**
  190. * 设置要请求的URL地址
  191. * @param string $url 需要设置的URL地址
  192. * @return void
  193. */
  194. public function setUrl($url){
  195. if ($url != '') {
  196. $this->uri = $url;
  197. }
  198. }
  199. /**
  200. * 发送HTTP GET请求
  201. * @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
  202. * @param array $vars 需要单独返送的GET变量
  203. * @param array /string 需要设置的头信息,可以是一个 类似 array('Host: example.com', 'Accept-Language: zh-cn') 的头信息数组
  204. * 或单一的一条类似于 'Host: example.com' 头信息字符串
  205. * @param string /array 需要设置的Cookie信息,一个类似于 'name1=value1&name2=value2' 的Cookie字符串信息,
  206. * 或者是一个 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  207. * @param int $timeout 连接对方服务器访问超时时间,单位为秒
  208. * @param array $options 当前操作类一些特殊的属性设置
  209. * @return unknown
  210. */
  211. public function get($url = '' , $vars = array() , $header = array() , $cookie = '' , $timeout = 5 , $options = array()){
  212. $this->setUrl($url);
  213. $this->setHeader($header);
  214. $this->setCookie($cookie);
  215. $this->setVar($vars);
  216. return $this->send('GET' , $timeout);
  217. }
  218. /**
  219. * 发送HTTP POST请求
  220. * @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
  221. * @param array $vars 需要单独返送的GET变量
  222. * @param array /string 需要设置的头信息,可以是一个 类似 array('Host: example.com', 'Accept-Language: zh-cn') 的头信息数组
  223. * 或单一的一条类似于 'Host: example.com' 头信息字符串
  224. * @param string /array 需要设置的Cookie信息,一个类似于 'name1=value1&name2=value2' 的Cookie字符串信息,
  225. * 或者是一个 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  226. * @param int $timeout 连接对方服务器访问超时时间,单位为秒
  227. * @param array $options 当前操作类一些特殊的属性设置
  228. * @return unknown
  229. */
  230. public function post($url = '' , $vars = array() , $header = array() , $cookie = '' , $timeout = 5 , $options = array()){
  231. $this->setUrl($url);
  232. $this->setHeader($header);
  233. $this->setCookie($cookie);
  234. $this->setVar($vars);
  235. return $this->send('POST' , $timeout);
  236. }
  237. /**
  238. * 发送HTTP请求核心函数
  239. * @param string $method 使用GET还是POST方式访问
  240. * @param array $vars 需要另外附加发送的GET/POST数据
  241. * @param int $timeout 连接对方服务器访问超时时间,单位为秒
  242. * @param array $options 当前操作类一些特殊的属性设置
  243. * @return string 返回服务器端读取的返回数据
  244. */
  245. public function send($method = 'GET' , $timeout = 5 , $options = array()){
  246. //处理参数是否为空
  247. if ($this->uri == '') {
  248. throw new Exception(__CLASS__ . ": Access url is empty");
  249. }
  250. //初始化CURL
  251. $ch = curl_init();
  252. curl_setopt($ch , CURLOPT_HEADER , 0);
  253. curl_setopt($ch , CURLOPT_FOLLOWLOCATION , 1);
  254. curl_setopt($ch , CURLOPT_RETURNTRANSFER , 1);
  255. curl_setopt($ch , CURLOPT_TIMEOUT , $timeout);
  256. //设置特殊属性
  257. if (!emptyempty($options)) {
  258. curl_setopt_array($ch , $options);
  259. }
  260. //处理GET请求参数
  261. if ($method == 'GET' && !emptyempty($this->vars)) {
  262. $query = Http::makeQuery($this->vars);
  263. $parse = parse_url($this->uri);
  264. $sep = isset($parse['query']) ? '&' : '?';
  265. $this->uri .= $sep . $query;
  266. }
  267. //处理POST请求数据
  268. if ($method == 'POST') {
  269. curl_setopt($ch , CURLOPT_POST , 1);
  270. curl_setopt($ch , CURLOPT_POSTFIELDS , $this->vars);
  271. }
  272. //设置cookie信息
  273. if (!emptyempty($this->cookies)) {
  274. curl_setopt($ch , CURLOPT_COOKIE , $this->cookies);
  275. }
  276. //设置HTTP缺省头
  277. if (emptyempty($this->header)) {
  278. $this->header = array('User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)' , //'Accept-Language: zh-cn',
  279. //'Cache-Control: no-cache',
  280. );
  281. }
  282. curl_setopt($ch , CURLOPT_HTTPHEADER , $this->header);
  283. //发送请求读取输数据
  284. curl_setopt($ch , CURLOPT_URL , $this->uri);
  285. $data = curl_exec($ch);
  286. if (($err = curl_error($ch))) {
  287. curl_close($ch);
  288. throw new Exception(__CLASS__ . " error: " . $err);
  289. }
  290. curl_close($ch);
  291. return $data;
  292. }
  293. }
  294. /**
  295. * 使用 Socket操作(fsockopen) 作为核心操作的HTTP访问接口
  296. * @desc Network/fsockopen 是PHP内置的一个Sokcet网络访问接口,必须安装/打开 fsockopen 函数本类才能工作,
  297. * 同时确保其他相关网络环境和配置是正确的
  298. */
  299. class Http_Sock{
  300. /**
  301. * @var object 对象单例
  302. */
  303. static $_instance = NULL;
  304. /**
  305. * @var string 需要发送的cookie信息
  306. */
  307. private $cookies = '';
  308. /**
  309. * @var array 需要发送的头信息
  310. */
  311. private $header = array();
  312. /**
  313. * @var string 需要访问的URL地址
  314. */
  315. private $uri = '';
  316. /**
  317. * @var array 需要发送的数据
  318. */
  319. private $vars = array();
  320. /**
  321. * 构造函数
  322. * @param string $configFile 配置文件路径
  323. */
  324. private function __construct($url){
  325. $this->uri = $url;
  326. }
  327. /**
  328. * 保证对象不被clone
  329. */
  330. private function __clone(){
  331. }
  332. /**
  333. * 获取对象唯一实例
  334. * @param string $configFile 配置文件路径
  335. * @return object 返回本对象实例
  336. */
  337. public static function getInstance($url = ''){
  338. if (!(self::$_instance instanceof self)) {
  339. self::$_instance = new self($url);
  340. }
  341. return self::$_instance;
  342. }
  343. /**
  344. * 设置需要发送的HTTP头信息
  345. * @param array /string 需要设置的头信息,可以是一个 类似 array('Host: example.com', 'Accept-Language: zh-cn') 的头信息数组
  346. * 或单一的一条类似于 'Host: example.com' 头信息字符串
  347. * @return void
  348. */
  349. public function setHeader($header){
  350. if (emptyempty($header)) {
  351. return;
  352. }
  353. if (is_array($header)) {
  354. foreach ($header as $k => $v) {
  355. $this->header[] = is_numeric($k) ? trim($v) : (trim($k) . ": " . trim($v));
  356. }
  357. } elseif (is_string($header)) {
  358. $this->header[] = $header;
  359. }
  360. }
  361. /**
  362. * 设置Cookie头信息
  363. * 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
  364. * @param string /array 需要设置的Cookie信息,一个类似于 'name1=value1&name2=value2' 的Cookie字符串信息,
  365. * 或者是一个 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  366. * @return void
  367. */
  368. public function setCookie($cookie){
  369. if (emptyempty($cookie)) {
  370. return;
  371. }
  372. if (is_array($cookie)) {
  373. $this->cookies = Http::makeQuery($cookie , ';');
  374. } elseif (is_string($cookie)) {
  375. $this->cookies = $cookie;
  376. }
  377. }
  378. /**
  379. * 设置要发送的数据信息
  380. * 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
  381. * @param array 设置需要发送的数据信息,一个类似于 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  382. * @return void
  383. */
  384. public function setVar($vars){
  385. if (emptyempty($vars)) {
  386. return;
  387. }
  388. if (is_array($vars)) {
  389. $this->vars = $vars;
  390. }
  391. }
  392. /**
  393. * 设置要请求的URL地址
  394. * @param string $url 需要设置的URL地址
  395. * @return void
  396. */
  397. public function setUrl($url){
  398. if ($url != '') {
  399. $this->uri = $url;
  400. }
  401. }
  402. /**
  403. * 发送HTTP GET请求
  404. * @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
  405. * @param array $vars 需要单独返送的GET变量
  406. * @param array /string 需要设置的头信息,可以是一个 类似 array('Host: example.com', 'Accept-Language: zh-cn') 的头信息数组
  407. * 或单一的一条类似于 'Host: example.com' 头信息字符串
  408. * @param string /array 需要设置的Cookie信息,一个类似于 'name1=value1&name2=value2' 的Cookie字符串信息,
  409. * 或者是一个 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  410. * @param int $timeout 连接对方服务器访问超时时间,单位为秒
  411. * @param array $options 当前操作类一些特殊的属性设置
  412. * @return unknown
  413. */
  414. public function get($url = '' , $vars = array() , $header = array() , $cookie = '' , $timeout = 5 , $options = array()){
  415. $this->setUrl($url);
  416. $this->setHeader($header);
  417. $this->setCookie($cookie);
  418. $this->setVar($vars);
  419. return $this->send('GET' , $timeout);
  420. }
  421. /**
  422. * 发送HTTP POST请求
  423. * @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
  424. * @param array $vars 需要单独返送的GET变量
  425. * @param array /string 需要设置的头信息,可以是一个 类似 array('Host: example.com', 'Accept-Language: zh-cn') 的头信息数组
  426. * 或单一的一条类似于 'Host: example.com' 头信息字符串
  427. * @param string /array 需要设置的Cookie信息,一个类似于 'name1=value1&name2=value2' 的Cookie字符串信息,
  428. * 或者是一个 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  429. * @param int $timeout 连接对方服务器访问超时时间,单位为秒
  430. * @param array $options 当前操作类一些特殊的属性设置
  431. * @return unknown
  432. */
  433. public function post($url = '' , $vars = array() , $header = array() , $cookie = '' , $timeout = 5 , $options = array()){
  434. $this->setUrl($url);
  435. $this->setHeader($header);
  436. $this->setCookie($cookie);
  437. $this->setVar($vars);
  438. return $this->send('POST' , $timeout);
  439. }
  440. /**
  441. * 发送HTTP请求核心函数
  442. * @param string $method 使用GET还是POST方式访问
  443. * @param array $vars 需要另外附加发送的GET/POST数据
  444. * @param int $timeout 连接对方服务器访问超时时间,单位为秒
  445. * @param array $options 当前操作类一些特殊的属性设置
  446. * @return string 返回服务器端读取的返回数据
  447. */
  448. public function send($method = 'GET' , $timeout = 5 , $options = array()){
  449. //处理参数是否为空
  450. if ($this->uri == '') {
  451. throw new Exception(__CLASS__ . ": Access url is empty");
  452. }
  453. //处理GET请求参数
  454. if ($method == 'GET' && !emptyempty($this->vars)) {
  455. $query = Http::makeQuery($this->vars);
  456. $parse = parse_url($this->uri);
  457. $sep = isset($parse['query']) && ($parse['query'] != '') ? '&' : '?';
  458. $this->uri .= $sep . $query;
  459. }
  460. //处理POST请求数据
  461. $data = '';
  462. if ($method == 'POST' && !emptyempty($this->vars)) {
  463. $data = Http::makeQuery($this->vars);
  464. $this->setHeader('Content-Type: application/x-www-form-urlencoded');
  465. $this->setHeader('Content-Length: ' . strlen($data));
  466. }
  467. //解析URL地址
  468. $url = parse_url($this->uri);
  469. $host = $url['host'];
  470. $port = isset($url['port']) && ($url['port'] != '') ? $url['port'] : 80;
  471. $path = isset($url['path']) && ($url['path'] != '') ? $url['path'] : '/';
  472. $path .= isset($url['query']) ? "?" . $url['query'] : '';
  473. //组织HTTP请求头信息
  474. array_unshift(&$this->header , $method . " " . $path . " HTTP/1.1");
  475. $this->setHeader('User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)');
  476. if (!preg_match("/^[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}$/" , $host)) {
  477. $this->setHeader("Host: " . $host);
  478. }
  479. if ($this->cookies != '') {
  480. $this->setHeader("Cookie: " . $this->cookies);
  481. }
  482. $this->setHeader("Connection: Close");
  483. //'Accept-Language: zh-cn',
  484. //'Cache-Control: no-cache',
  485. //构造请求信息
  486. $header = '';
  487. foreach ($this->header as $h) {
  488. $header .= $h . "\r\n";
  489. }
  490. $header .= "\r\n";
  491. if ($method == 'POST' && $data != '') {
  492. $header .= $data . "\r\n";
  493. }
  494. //连接服务器发送请求数据
  495. $ip = gethostbyname($host);
  496. if (!($fp = fsockopen($ip , $port , &$errno , &$errstr , $timeout))) {
  497. throw new Exception(__CLASS__ . ": Can't connect $host:$port, errno:$errno,message:$errstr");
  498. }
  499. fputs($fp , $header);
  500. $lineSize = 1024;
  501. //处理301,302跳转页面访问
  502. $line = fgets($fp , $lineSize);
  503. $first = preg_split("/\s/" , trim($line));
  504. if (isset($first[1]) && in_array($first[1] , array('301' , '302'))) {
  505. while (!feof($fp)) {
  506. $line = fgets($fp , $lineSize);
  507. $second = preg_split("/\s/" , trim($line));
  508. if (ucfirst(trim($second[0])) == 'Location:' && $second[1] != '') {
  509. $this->header = array();
  510. return $this->get(trim($second[1]));
  511. }
  512. }
  513. }
  514. //正常读取返回数据
  515. $buf = '';
  516. $inheader = 1;
  517. while (!feof($fp)) {
  518. if ($inheader && ($line == "\n" || $line == "\r\n")) {
  519. $inheader = 0;
  520. }
  521. $line = fgets($fp , $lineSize);
  522. if ($inheader == 0) {
  523. $buf .= $line;
  524. }
  525. }
  526. fclose($fp);
  527. return $buf;
  528. }
  529. }
  530. /**
  531. * 使用文件流操作函数为核心操作的HTTP访问接口
  532. * @desc stream_* 和 fopen/file_get_contents 是PHP内置的一个流和文件操作接口,必须打开 fsockopen 函数本类才能工作,
  533. * 同时确保其他相关网络环境和配置是正确的,包括 allow_url_fopen 等设置
  534. */
  535. class Http_Stream{
  536. /**
  537. * @var object 对象单例
  538. */
  539. static $_instance = NULL;
  540. /**
  541. * @var string 需要发送的cookie信息
  542. */
  543. private $cookies = '';
  544. /**
  545. * @var array 需要发送的头信息
  546. */
  547. private $header = array();
  548. /**
  549. * @var string 需要访问的URL地址
  550. */
  551. private $uri = '';
  552. /**
  553. * @var array 需要发送的数据
  554. */
  555. private $vars = array();
  556. /**
  557. * 构造函数
  558. * @param string $configFile 配置文件路径
  559. */
  560. private function __construct($url){
  561. $this->uri = $url;
  562. }
  563. /**
  564. * 保证对象不被clone
  565. */
  566. private function __clone(){
  567. }
  568. /**
  569. * 获取对象唯一实例
  570. * @param string $configFile 配置文件路径
  571. * @return object 返回本对象实例
  572. */
  573. public static function getInstance($url = ''){
  574. if (!(self::$_instance instanceof self)) {
  575. self::$_instance = new self($url);
  576. }
  577. return self::$_instance;
  578. }
  579. /**
  580. * 设置需要发送的HTTP头信息
  581. * @param array /string 需要设置的头信息,可以是一个 类似 array('Host: example.com', 'Accept-Language: zh-cn') 的头信息数组
  582. * 或单一的一条类似于 'Host: example.com' 头信息字符串
  583. * @return void
  584. */
  585. public function setHeader($header){
  586. if (emptyempty($header)) {
  587. return;
  588. }
  589. if (is_array($header)) {
  590. foreach ($header as $k => $v) {
  591. $this->header[] = is_numeric($k) ? trim($v) : (trim($k) . ": " . trim($v));
  592. }
  593. } elseif (is_string($header)) {
  594. $this->header[] = $header;
  595. }
  596. }
  597. /**
  598. * 设置Cookie头信息
  599. * 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
  600. * @param string /array 需要设置的Cookie信息,一个类似于 'name1=value1&name2=value2' 的Cookie字符串信息,
  601. * 或者是一个 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  602. * @return void
  603. */
  604. public function setCookie($cookie){
  605. if (emptyempty($cookie)) {
  606. return;
  607. }
  608. if (is_array($cookie)) {
  609. $this->cookies = Http::makeQuery($cookie , ';');
  610. } elseif (is_string($cookie)) {
  611. $this->cookies = $cookie;
  612. }
  613. }
  614. /**
  615. * 设置要发送的数据信息
  616. * 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
  617. * @param array 设置需要发送的数据信息,一个类似于 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  618. * @return void
  619. */
  620. public function setVar($vars){
  621. if (emptyempty($vars)) {
  622. return;
  623. }
  624. if (is_array($vars)) {
  625. $this->vars = $vars;
  626. }
  627. }
  628. /**
  629. * 设置要请求的URL地址
  630. * @param string $url 需要设置的URL地址
  631. * @return void
  632. */
  633. public function setUrl($url){
  634. if ($url != '') {
  635. $this->uri = $url;
  636. }
  637. }
  638. /**
  639. * 发送HTTP GET请求
  640. * @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
  641. * @param array $vars 需要单独返送的GET变量
  642. * @param array /string 需要设置的头信息,可以是一个 类似 array('Host: example.com', 'Accept-Language: zh-cn') 的头信息数组
  643. * 或单一的一条类似于 'Host: example.com' 头信息字符串
  644. * @param string /array 需要设置的Cookie信息,一个类似于 'name1=value1&name2=value2' 的Cookie字符串信息,
  645. * 或者是一个 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  646. * @param int $timeout 连接对方服务器访问超时时间,单位为秒
  647. * @param array $options 当前操作类一些特殊的属性设置
  648. * @return unknown
  649. */
  650. public function get($url = '' , $vars = array() , $header = array() , $cookie = '' , $timeout = 5 , $options = array()){
  651. $this->setUrl($url);
  652. $this->setHeader($header);
  653. $this->setCookie($cookie);
  654. $this->setVar($vars);
  655. return $this->send('GET' , $timeout);
  656. }
  657. /**
  658. * 发送HTTP POST请求
  659. * @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
  660. * @param array $vars 需要单独返送的GET变量
  661. * @param array /string 需要设置的头信息,可以是一个 类似 array('Host: example.com', 'Accept-Language: zh-cn') 的头信息数组
  662. * 或单一的一条类似于 'Host: example.com' 头信息字符串
  663. * @param string /array 需要设置的Cookie信息,一个类似于 'name1=value1&name2=value2' 的Cookie字符串信息,
  664. * 或者是一个 array('name1'=>'value1', 'name2'=>'value2') 的一维数组
  665. * @param int $timeout 连接对方服务器访问超时时间,单位为秒
  666. * @param array $options 当前操作类一些特殊的属性设置
  667. * @return unknown
  668. */
  669. public function post($url = '' , $vars = array() , $header = array() , $cookie = '' , $timeout = 5 , $options = array()){
  670. $this->setUrl($url);
  671. $this->setHeader($header);
  672. $this->setCookie($cookie);
  673. $this->setVar($vars);
  674. return $this->send('POST' , $timeout);
  675. }
  676. /**
  677. * 发送HTTP请求核心函数
  678. * @param string $method 使用GET还是POST方式访问
  679. * @param array $vars 需要另外附加发送的GET/POST数据
  680. * @param int $timeout 连接对方服务器访问超时时间,单位为秒
  681. * @param array $options 当前操作类一些特殊的属性设置
  682. * @return string 返回服务器端读取的返回数据
  683. */
  684. public function send($method = 'GET' , $timeout = 5 , $options = array()){
  685. //处理参数是否为空
  686. if ($this->uri == '') {
  687. throw new Exception(__CLASS__ . ": Access url is empty");
  688. }
  689. $parse = parse_url($this->uri);
  690. $host = $parse['host'];
  691. //处理GET请求参数
  692. if ($method == 'GET' && !emptyempty($this->vars)) {
  693. $query = Http::makeQuery($this->vars);
  694. $sep = isset($parse['query']) && ($parse['query'] != '') ? '&' : '?';
  695. $this->uri .= $sep . $query;
  696. }
  697. //处理POST请求数据
  698. $data = '';
  699. if ($method == 'POST' && !emptyempty($this->vars)) {
  700. $data = Http::makeQuery($this->vars);
  701. }
  702. //设置缺省头
  703. $this->setHeader('User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)');
  704. if (!preg_match("/^[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}$/" , $host)) {
  705. $this->setHeader("Host: " . $host);
  706. }
  707. if ($this->cookies != '') {
  708. $this->setHeader("Cookie: " . $this->cookies);
  709. }
  710. $this->setHeader("Connection: Close");
  711. //'Accept-Language: zh-cn',
  712. //'Cache-Control: no-cache',
  713. //构造头信息
  714. $opts = array('http' => array('method' => $method , 'timeout' => $timeout ,));
  715. if ($data != '') {
  716. $opts['http']['content'] = $data;
  717. }
  718. $opts['http']['header'] = '';
  719. foreach ($this->header as $h) {
  720. $opts['http']['header'] .= $h . "\r\n";
  721. }
  722. //print_r($opts);exit;
  723. //读取扩展设置选项
  724. if (!emptyempty($options)) {
  725. isset($options['proxy']) ? $opts['http']['proxy'] = $options['proxy'] : '';
  726. isset($options['max_redirects']) ? $opts['http']['max_redirects'] = $options['max_redirects'] : '';
  727. isset($options['request_fulluri']) ? $opts['http']['request_fulluri'] = $options['request_fulluri'] : '';
  728. }
  729. //发送数据返回
  730. $context = stream_context_create($opts);
  731. if (($buf = file_get_contents($this->uri , null , $context)) === false) {
  732. throw new Exception(__CLASS__ . ": file_get_contents(" . $this->uri . ") fail");
  733. }
  734. return $buf;
  735. }
  736. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注