c5_labsci/zciyphp/http.php
2026-01-27 00:52:00 +08:00

561 lines
23 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/* =================================================================================
* License: GPL-2.0 license
* Author: 众产® https://ciy.cn/code
* Version: 0.1.2
====================================================================================*/
/*
//初始化
//指定cookiefile保存路径由curl统一控制cookie不填则自行控制。遇到JS更新Cookie的网站需自行控制。
$http = new http($cookiefile = '');
//GET请求资源
$http->request($url);
//POST请求资源
$post = 'id=123&cn=aab';//该项如果填写则为POST方式否则为GET方式;如需上传文件,需在文件路径前加上@符号
$http->request($url,$post);
//获取网页数据
$data = $http->get_data();
//设置cookie。
$cookie = $http->set_cookie($name,$value,$domain,$path,$expires);
//批量设置cookie。
$cookie = $http->set_cookiebyurl($url,$cookie);
//获取cookie。url必填name不填时返回拼接cookie
$cookie = $http->get_cookie($url,$name);
//设置来源
$http->set_referer($referer);
//设置Header头
$http->set_headeronce($key,$value);//当次请求有效
$http->set_header('X-Requested-With','XMLHttpRequest');//永久有效
//设置浏览器UserAgent
$http->set_useragent($useragent);
//设置超时时间(秒)
$http->set_timeout($sec);
//设置代理服务器信息
$http->set_proxy($host, $port, $user, $pass);
//获取网页响应状态码
$statcode = $http->get_statcode();
//获取原始未处理的响应数据
$response = $http->get_response();
//获取连接资源的信息(返回数组),如平均上传速度 、平均下载速度 、请求的URL等
$response_info = $http->get_info();
//获取网页响应Header
$header = $http->get_header($key);
*/
namespace ciy;
class http {
public $id; //扩展数据1
public $extdata; //扩展数据2
public $obj; //扩展数据3
private $response;
private $response_header;
private $response_data;
private $response_info;
private $timeout = 30;
public $maxredirect = 3;
private $cookiefile = ''; //设置此项cookie相关函数均失效用libcurl的cookie文件统一控制。
private $cookiecontainer = array();
private $useragent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.9.3.1000 Chrome/39.0.2146.0 Safari/537.36';
private $request_referer = '';
private $request_method = '';
private $request_headeronce = array();
private $request_headerfixed = array();
private $request_proxy = array();
public function __construct($cookiefile = '') {
//能有效提高POST大于1M数据时的请求速度
//$this->set_header('Expect');
$this->cookiefile = $cookiefile;
}
public function set_cookie($name, $value = null, $domain = '', $path = '/', $expires = 2114352000) {
$cook = array();
if (is_array($name))
$cook = $name;
else {
$cook['name'] = $name;
$cook['value'] = $value;
$cook['domain'] = $domain;
$cook['path'] = $path;
$cook['expires'] = $expires;
if ($value === null)
$cook['value'] = 'deleted';
if ($expires < time())
$cook['value'] = 'deleted';
}
if (empty($cook['domain']))
return;
$cookiei = -1;
foreach ($this->cookiecontainer as $k => $c) {
if ($c['name'] == $cook['name']) {
if ($this->_verifycookie($c, $cook['domain'], $cook['path']))
$cookiei = $k;
}
}
if ($cookiei < 0) {
if ($cook['value'] != 'deleted')
$this->cookiecontainer[] = $cook;
} else {
if ($cook['value'] == 'deleted')
array_splice($this->cookiecontainer, $cookiei, 1);
else
$this->cookiecontainer[$cookiei] = $cook;
}
}
public function set_cookiebyurl($url, $cookie) {
$purl = parse_url($url);
$doamin = $purl['host'];
$cookieinfo = explode(';', $cookie);
foreach ($cookieinfo as $cinfo) {
$ind = strpos($cinfo, '=');
if ($ind === false)
continue;
$val = substr($cinfo, $ind + 1);
$key = trim(substr($cinfo, 0, $ind));
$this->set_cookie($key, $val, $doamin);
}
}
public function set_useragent($useragent = '') {
$this->useragent = $useragent;
}
public function set_method($method) {
$this->request_method = strtoupper($method);
}
public function set_referer($referer) {
$this->request_referer = $referer;
}
public function set_header($k, $v = '') {
if (!empty($k))
$this->request_headerfixed[] = $k . ':' . $v;
else
$this->request_headerfixed = array();
}
public function set_headeronce($k, $v = '') {
if (!empty($k))
$this->request_headeronce[] = $k . ':' . $v;
else
$this->request_headeronce = array();
}
public function set_timeout($sec) {
if ($sec > ini_get('max_execution_time'))
@set_time_limit($sec);
$this->timeout = $sec;
}
public function set_proxy($host, $port = '', $user = '', $pass = '') {
$this->request_proxy = array('host' => $host, 'port' => $port, 'user' => $user, 'pass' => $pass);
}
public function get_response() {
return $this->response;
}
public function get_header($key = null) {
if ($key == null) {
return $this->response_header;
}
if (!isset($this->response_header[$key])) {
return '';
}
return $this->response_header[$key];
}
public function get_cookie($url = null, $name = null) {
if (empty($url))
return $this->cookiecontainer;
$purl = parse_url($url);
$doamin = $purl['host'];
if (isset($purl['path']))
$path = $purl['path'];
else
$path = '/';
if ($name === null) {
$cook = '';
foreach ($this->cookiecontainer as $k => $c) {
if ($this->_verifycookie($c, $doamin, $path))
$cook .= $c['name'] . '=' . $c['value'] . '; ';
}
if ($cook == '')
return '';
$cook = substr($cook, 0, -2);
return $cook;
}
foreach ($this->cookiecontainer as $k => $c) {
if ($this->_verifycookie($c, $doamin, $path)) {
if ($name == $c['name'])
return $c['value'];
}
}
return '';
}
public function get_file($file) {
return file_put_contents($file, $this->response_data);
}
public function get_data() {
$encode = $this->get_header('Content-Encoding');
if ($encode == 'gzip') {
$flags = ord(substr($this->response_data, 3, 1));
$headerlen = 10;
$extralen = 0;
$filenamelen = 0;
if ($flags & 4) {
$extralen = unpack('v', substr($this->response_data, 10, 2));
$extralen = $extralen[1];
$headerlen += 2 + $extralen;
}
if ($flags & 8)
$headerlen = strpos($this->response_data, chr(0), $headerlen) + 1;
if ($flags & 16)
$headerlen = strpos($this->response_data, chr(0), $headerlen) + 1;
if ($flags & 2)
$headerlen += 2;
$unpacked = @gzinflate(substr($this->response_data, $headerlen));
if ($unpacked === FALSE)
$unpacked = $this->response_data;
return $unpacked;
}
return $this->response_data;
}
public function get_charset() {
$content_type = $this->get_header('Content-Type');
if ($content_type) {
preg_match('/charset=(.+)/i', $content_type, $matches);
if (isset($matches[1])) {
return strtoupper(trim($matches[1]));
}
}
return '';
}
public function get_info() {
return $this->response_info;
}
public function get_statcode() {
return toint($this->response_info['http_code']);
}
/*
$post_data设置
1、Form-data模式 Content-Type: multipart/form-data; boundary=------------------------d8be87f4725b2d84
$postdata = array();
$postdata['name'] = 'AAA';
$postdata['file'] = new CURLFile(@'D:/request.txt'); //上传文件
POST --------------------------d8be87f4725b2d84\r\nContent-Disposition: form-data; name="name"\r\n\r\nAAA
2、Form-urlencoded模式 Content-Type: application/x-www-form-urlencoded
$postdata = array();
$postdata['name'] = 'AAA';
$postdata['car'] = '浙';
$postdata = http_build_query($postdata);
POST name=AAA&car=%E6%B5%99
2、raw模式 Content-Type: application/json;charset=UTF-8
$postdata = array();
$postdata['name'] = 'AAA';
$postdata['car'] = array('color'=>'red','nb'=>'浙');
$postdata = json_encode($postdata);
POST {"name":"AAA","car":{"color":"red","nb":"\u6d59"}}
*/
public function request($url, $post_data = '') {
for ($i = 0; $i < $this->maxredirect; $i++) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $this->useragent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
//强制使用IPV4协议解析域名否则在支持IPV6的环境下请求会异常慢
@curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
if ($post_data) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
if (!is_array($post_data)) {
if ($post_data[0] == '{') {
$content_type = false;
foreach ($this->request_headeronce as $header) {
if (strtolower(substr($header, 0, 12)) == 'content-type') {
$content_type = true;
break;
}
}
if (!$content_type) {
$this->request_headeronce[] = 'content-type: application/json; charset=utf-8';
}
}
}
}
if (empty($this->cookiefile)) {
$purl = parse_url($url);
$doamin = $purl['host'];
if (isset($purl['path']))
$path = $purl['path'];
else
$path = '/';
$cook = '';
$cookdel = array();
foreach ($this->cookiecontainer as $k => $c) {
if ($c['expires'] < time())
$cookdel[] = $k;
}
$cookdel = array_reverse($cookdel);
foreach ($cookdel as $k)
array_splice($this->cookiecontainer, $k, 1);
foreach ($this->cookiecontainer as $k => $c) {
if ($this->_verifycookie($c, $doamin, $path))
$cook .= $c['name'] . '=' . $c['value'] . '; ';
}
if ($cook != '') {
$cook = substr($cook, 0, -2);
curl_setopt($ch, CURLOPT_COOKIE, $cook);
}
} else {
curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookiefile);
curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookiefile);
}
if (!empty($this->request_referer))
curl_setopt($ch, CURLOPT_REFERER, $this->request_referer);
$headers = array_merge($this->request_headeronce, $this->request_headerfixed);
if ($headers)
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$this->request_headeronce = array();
if ($this->request_proxy) {
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true);
$host = $this->request_proxy['host'];
$host .= ($this->request_proxy['port']) ? ':' . $this->request_proxy['port'] : '';
curl_setopt($ch, CURLOPT_PROXY, $host);
if (isset($this->request_proxy['user']) && isset($this->request_proxy['pass'])) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->request_proxy['user'] . ':' . $this->request_proxy['pass']);
}
}
$this->response = curl_exec($ch);
if ($this->response === false) {
$this->response_info['http_code'] = 204;
$this->response_data = 'error: ' . curl_error($ch) . ' (' . curl_errno($ch) . ')URL: ' . $url;
return false;
}
$this->response_info = curl_getinfo($ch);
$content_size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
if ($content_size > 0) {
$this->response_header = substr($this->response, 0, -$content_size);
$this->response_data = substr($this->response, -$content_size);
} else {
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$this->response_header = substr($this->response, 0, $header_size);
$this->response_data = substr($this->response, $header_size);
}
//分解响应头部信息
$this->response_header = explode("\r\n\r\n", trim($this->response_header), 2);
$this->response_header = array_pop($this->response_header);
$this->response_header = explode("\r\n", $this->response_header);
array_shift($this->response_header); //去掉第一行
$purl = null;
$header_assoc = array();
foreach ($this->response_header as $header) {
$kv = explode(': ', $header, 2);
if (strtolower($kv[0]) == 'set-cookie') {
$header_assoc['Set-Cookie'][] = $kv[1];
if (empty($this->cookiefile)) {
$cookieinfo = explode(';', $kv[1]);
//list($name, $value) = explode('=', array_shift($cookieinfo), 2);
$cookname = array_shift($cookieinfo);
$ind = strpos($cookname, '=');
if ($ind === false)
continue;
$cook = array();
$cook['value'] = substr($cookname, $ind + 1);
$cook['name'] = trim(substr($cookname, 0, $ind));
foreach ($cookieinfo as $key) {
$ind = strpos($key, '=');
if ($ind !== false) {
$val = substr($key, $ind + 1);
$key = strtolower(trim(substr($key, 0, $ind)));
}
if ($key == 'expires') {
$cook['expires'] = strtotime($val);
if ($cook['expires'] < time())
$cook['value'] = 'deleted';
} else if ($key == 'path')
$cook['path'] = $val;
else if ($key == 'domain')
$cook['domain'] = $val;
}
if ($purl === null) {
$purl = parse_url($this->response_info['url']);
$doamin = $purl['host'];
if (isset($purl['path']))
$path = $purl['path'];
else
$path = '/';
}
if (!isset($cook['expires']))
$cook['expires'] = 2114352000;
if (!isset($cook['domain']))
$cook['domain'] = $doamin;
if (!isset($cook['path']))
$cook['path'] = '/';
$this->set_cookie($cook);
}
continue;
}
$header_assoc[$kv[0]] = $kv[1];
}
$this->response_header = $header_assoc;
curl_close($ch);
$httpcode = toint($this->response_info['http_code']);
if ($httpcode >= 300 && $httpcode < 400) {
if ($this->response_info['redirect_url']) {
$url = $this->response_info['redirect_url'];
$postdata = '';
continue;
}
}
if ($httpcode == 200)
return true;
return false;
}
return false;
}
public function upfile($url, $file) {
for ($i = 0; $i < $this->maxredirect; $i++) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $this->useragent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
//强制使用IPV4协议解析域名否则在支持IPV6的环境下请求会异常慢
@curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
if (!empty($this->request_method))
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->request_method);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, fopen($file, 'rb'));
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file));
if (empty($this->cookiefile)) {
$purl = parse_url($url);
$doamin = $purl['host'];
if (isset($purl['path']))
$path = $purl['path'];
else
$path = '/';
$cook = '';
$cookdel = array();
foreach ($this->cookiecontainer as $k => $c) {
if ($c['expires'] < time())
$cookdel[] = $k;
}
$cookdel = array_reverse($cookdel);
foreach ($cookdel as $k)
array_splice($this->cookiecontainer, $k, 1);
foreach ($this->cookiecontainer as $k => $c) {
if ($this->_verifycookie($c, $doamin, $path))
$cook .= $c['name'] . '=' . $c['value'] . '; ';
}
if ($cook != '') {
$cook = substr($cook, 0, -2);
curl_setopt($ch, CURLOPT_COOKIE, $cook);
}
} else {
curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookiefile);
curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookiefile);
}
$headers = array_merge($this->request_headeronce, $this->request_headerfixed);
if ($headers)
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$this->request_headeronce = array();
$this->response = curl_exec($ch);
if ($this->response === false) {
$this->response_info['http_code'] = 204;
$this->response_data = 'error: ' . curl_error($ch) . ' (' . curl_errno($ch) . ')URL: ' . $url;
return false;
}
$this->response_info = curl_getinfo($ch);
$content_size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
if ($content_size > 0) {
$this->response_header = substr($this->response, 0, -$content_size);
$this->response_data = substr($this->response, -$content_size);
} else {
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$this->response_header = substr($this->response, 0, $header_size);
$this->response_data = substr($this->response, $header_size);
}
//分解响应头部信息
$this->response_header = explode("\r\n\r\n", trim($this->response_header), 2);
$this->response_header = array_pop($this->response_header);
$this->response_header = explode("\r\n", $this->response_header);
array_shift($this->response_header); //去掉第一行
$header_assoc = array();
$this->response_header = $header_assoc;
curl_close($ch);
$httpcode = toint($this->response_info['http_code']);
if ($httpcode >= 300 && $httpcode < 400) {
if ($this->response_info['redirect_url']) {
$url = $this->response_info['redirect_url'];
continue;
}
}
if ($httpcode == 200)
return true;
return false;
}
return false;
}
public function downurl($url, $path, $filename = '', $fileext = '') {
$ch = curl_init();
$fp = fopen($path . $filename . '.' . $fileext, 'wb');
if (!$fp) {
$this->response_info['http_code'] = 10;
$this->response_data = 'URL: ' . $url . '无法创建本地文件: ' . $path . $filename . '.' . $fileext;
curl_close($ch);
return false;
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FILE, $fp); // 将输出写入文件
curl_setopt($ch, CURLOPT_HEADER, 0); // 不返回头部信息
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向
curl_setopt($ch, CURLOPT_TIMEOUT, 60); // 设置最大执行时间
curl_setopt($ch, CURLOPT_USERAGENT, $this->useragent); // 设置User-Agent
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
fclose($fp);
if ($response === false) {
clog(curl_error($ch) . ' (' . curl_errno($ch) . ')');
$this->response_info['http_code'] = 204;
$this->response_data = 'error: ' . curl_error($ch) . ' (' . curl_errno($ch) . ')URL: ' . $url;
curl_close($ch);
return false;
}
curl_close($ch);
return true;
}
private function _verifycookie($cookie, $domain, $path) {
$sel = false;
if ($cookie['domain'][0] == '.') {
$d = '.' . $domain;
$cc = substr($d, strlen($d) - strlen($cookie['domain']));
if ($cc == $cookie['domain'])
$sel = true;
} else {
if ($domain == $cookie['domain'])
$sel = true;
}
if ($sel) {
if (substr($path, 0, strlen($cookie['path'])) == $cookie['path'])
return true;
}
return false;
}
}