123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- <?php
- namespace loyalsoft;
- include_once 'IPQuery/IPQuery.php';
- /**
- * Http辅助类,可以发送请求/接收请求(提取参数)
- * @author gwang (email: mail@wanggangzero.cn)
- * @copyright 2016-3-12 ©SJZ LoyalSoft Corporation & gwang. All rights reserved.
- */
- class HttpUtil {
- /**
- * 从请求字符串中解析请求参数
- * @param type $queryStr
- * @return type 注意:解析过程未加入url_decode, 请调用方根据情况自行处理.
- */
- public static function parseQueryParas($queryStr) {
- // $queryStr = urldecode($queryStr);
- $arr = explode('&', $queryStr);
- $queryParas = array();
- foreach ($arr as $value) {
- $paras = explode('=', $value);
- $queryParas[$paras[0]] = isset($paras[1]) ? $paras[1] : "";
- }
- return $queryParas;
- }
- /**
- * 执行一个 HTTP 请求
- *
- * @param string $url 执行请求的URL
- * @param mixed $params 表单参数, 可以是array, 也可以是经过url编码之后的string
- * @param mixed $cookie cookie参数, 可以是array, 也可以是经过拼接的string, 默认array()
- * @param array $header http请求头, 默认array()
- * @param string $method 请求方法 post / get, 默认='post'
- * @param string $protocol http协议类型 http / https, 默认='http'
- * @return array 结果数组 {"result":bool,"msg":返回值/curlErrMsg,"errno":curl错误码,"ifno":curlInfo}
- */
- public static function makeRequest($url, $params, $cookie = array(), #
- $header = array(), $method = 'post', $protocol = 'https') {
- $query_string = self::makeQueryString($params);
- $cookie_string = self::makeCookieString($cookie);
- $ch = curl_init();
- if ('GET' == strtoupper($method)) { # Get
- curl_setopt($ch, CURLOPT_URL, "$url?$query_string");
- } else { # POST
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string); # postdata
- }
- curl_setopt($ch, CURLOPT_HEADER, false); # 控制是否返回响应头信息
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); # 超时时间
- // 如果客户端要发送一段很大的数据, 可以先向服务器发送一个expect: 100-continue,
- // 等待服务器响应 100以后, 继续发送数据体. 比如nginx默认接收客户端数据的大小为1M,PHP2M.
- if (strlen($query_string) > 1024 * 1024) {
- if (is_array($header)) { # http header是个数组,
- $header[] = 'Expect: 100-continue'; # 补充一个'Expect:', 避免出现 100-continue.
- } else if (is_string($header)) { # 如果header传过来了一个字符串
- $header = array($header, 'Expect: 100-continue'); # 拼接一个数组
- } else { # 其他情况,直接忽略, 覆盖掉
- $header = array('Expect: 100-continue');
- }
- }
- curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
- if (!empty($cookie_string)) {
- curl_setopt($ch, CURLOPT_COOKIE, $cookie_string);
- }
- if ('https' == $protocol or substr($url, 0, 5) == 'https') { # 若为https协议
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); # 若是出错,检查php.ini中curl.cainfo配置
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- }
- // curl_setopt($ch, CURLOPT_PROXYPORT, 8888); # 代理,调试用的
- // curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1');
- $ret = curl_exec($ch);
- $err = curl_error($ch);
- if (false === $ret || !empty($err)) {
- $errno = curl_errno($ch);
- $info = curl_getinfo($ch);
- curl_close($ch);
- return array(
- 'result' => false,
- 'msg' => $err,
- 'errno' => $errno,
- 'info' => $info,
- );
- }
- curl_close($ch);
- return array(
- 'result' => true,
- 'msg' => $ret,
- );
- }
- /**
- * 从参数构造请求串
- * @param type $params 如果是字符串直接返回,(关联)数组或者object(仅取public字段)
- * @return string 编码规范-RFC3986
- */
- public static function makeQueryString($params) {
- if (is_string($params)) {
- return $params;
- }
- return http_build_query($params, "", '&', PHP_QUERY_RFC3986); # 3986
- }
- /**
- * 从参数构造Cookie字符串
- * @param type $params 如果是字符串直接返回,(关联)数组或者object(仅取public字段)
- * @return string 编码规范-RFC3986
- */
- public static function makeCookieString($params) {
- if (is_string($params)) {
- return $params;
- }
- return http_build_query($params, "", "; ", PHP_QUERY_RFC3986); # 3986
- }
- /**
- * 取Request过来的Data转为关联数组
- * @return array
- */
- public static function getQueryParas() {
- $param = $_REQUEST;
- if (isset($_SERVER['REQUEST_METHOD'])) {
- switch ($_SERVER['REQUEST_METHOD']) {
- case 'GET':
- $param = $_REQUEST;
- break;
- case 'POST':
- $str = file_get_contents('php://input'); # 注意: 若是multipart/form-data,则PHP不会填充input.
- $param = array_merge($param, ( strlen($str) > 0 ? self::parseQueryParas($str) : array()));
- break;
- default:
- }
- }
- return $param;
- }
- /**
- * 取Request过来的数据流转为字符串
- * @return string
- */
- public static function getQueryString() {
- $queryStr = null;
- if (isset($_SERVER['REQUEST_METHOD'])) {
- switch ($_SERVER['REQUEST_METHOD']) {
- case 'GET':
- $queryStr = $_SERVER['QUERY_STRING'];
- break;
- case 'POST':
- $queryStr = file_get_contents('php://input');
- break;
- default:
- }
- }
- return $queryStr;
- }
- /**
- * 用于确保服务器只响应POST方法.
- */
- public static function PostOnly() {
- if ($_SERVER['REQUEST_METHOD'] != 'POST') {
- header('Allow: POST ', false, 405);
- exit();
- }
- }
- /**
- * 测试是否支持tls1.2
- * @return bool true:支持, false:不支持
- */
- public static function CanSurpotTls_1_2() {
- $target_url = 'https://www.baidu.com/'; # 测试地址
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $target_url);
- curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- return curl_exec($ch) !== false; # 响应结果不为false则支持
- }
- /**
- * 获取客户端ip地址及端口
- * @return ip:port
- */
- public static function getClientEP() {
- return $_SERVER['REMOTE_ADDR'] . ":" . $_SERVER['REMOTE_PORT'];
- }
- /**
- * 获取客户端IP地址(摘自discuz)
- * @return string
- */
- public static function clientIP() {
- $ip = '未知IP';
- if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
- return self::is_ip($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : $ip;
- } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
- return self::is_ip($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $ip;
- } elseif (!empty($_SERVER['REMOTE_ADDR'])) {
- return self::is_ip($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : $ip;
- } else {
- return $ip;
- }
- }
- /**
- * 获取ip的位置信息(中文)
- * @param type $ip
- * @return string
- */
- public static function IpInfo($ip) {
- $query = new \IPQuery();
- $info = $query->query($ip);
- return "{$info["pos"]}-{$info["isp"]}";
- }
- private static function is_ip($str) {
- $ip = explode('.', $str);
- for ($i = 0; $i < count($ip); $i++) {
- if ($ip[$i] > 255) {
- return false;
- }
- }
- return preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/', $str);
- }
- }
- /**
- * 取Request过来的Data转为关联数组
- * @return array
- */
- function query_paras() {
- return HttpUtil::getQueryParas();
- }
- /**
- * 取Request过来的数据流转为字符串
- * @return string
- */
- function query_string() {
- return HttpUtil::getQueryString();
- }
|