zoukankan      html  css  js  c++  java
  • PHP Socket编程 之 fsockopen指定ip获取远程数据 及 301自动跳转

    当域名与ip不相符,又无法修改系统hosts时,我们需要指定ip来获取远程数据,通过搜索php curl相关资料,未发现可用方法,故写了如下两个函数。

    函数支持get或者post方式,301自动跳转,支持自定义header,仅支持ipv4的http协议。

    代码已集成到AlonePHP中。

    /* http_get_with_ip,用于ip解析错误或者需要指定ip的时候以get方式获取数据
     * @param string $url 远程地址
     * @param string $ip 需要访问的ip
     * @param array $header 需要添加的其它header参数
     * @return string|boolean 返回获取的内容,访问失败返回false
     */
    function http_get_with_ip($url, $ip = '', $header = array()) {
    	return curl_post_with_ip($url, null, $ip, $header);
    }
     
    /* http_post_with_ip,用于ip解析错误或者需要指定ip的时候以post方式获取数据
     * @param string $url 远程地址
     * @param array|null $post_data 以post方式提交数据,如果此参数为null,则使用get方式
     * @param string $ip 需要访问的ip
     * @param array $header 需要添加的其它header参数
     * @return string|boolean 返回获取的内容,访问失败返回false
     */
    function http_post_with_ip($url, $post_data = null, $ip = '', $header = array()) {
    	/* 最大循环跳转次数 */
    	$loop_max_count = 5;
     
    	static $loop_count = 0;
    	$errstr = '';
    	$errno = '';
    	/* 解析URL */
    	$url_array = parse_url($url);
    	if ($url_array === false) {
    		$loop_count = 0;
    		return false;
    	}
    	$host = $url_array['host'];
    	/* 域名解析失败则退出 */
    	if (!$host) {
    		$loop_count = 0;
    		return false;
    	}
    	/* 获取端口 */
    	$port = isset($url_array['port']) ? $url_array['port'] : 80;
    	/* 获取ip */
    	if ($ip === '') {
    		$ip = gethostbyname($host);
    	}
     
    	$fp = fsockopen($ip, $port, $errno, $errstr, 90);
    	if (!$fp) {
    		$loop_count = 0;
    		return false;
    	} else {
    		$out = (is_array($post_data) ? "POST" : "GET") . " {$url} HTTP/1.0
    ";
    		/* 最终的header数组 */
    		$header_result = array();
    		$header_result['Host'] = $host;
    		/* 处理post数据 */
    		if (is_array($post_data)) {
    			$post_values = array();
    			foreach ($post_data as $key => $value) {
    				array_push($post_values, urlencode($key) . "=" . urlencode($value));
    			}
    			$post_content = implode("&", $post_values);
    			$header_result['Content-type'] = "application/x-www-form-urlencoded";
    			$header_result['Content-length'] = strlen($post_content);
    		}
    		/* 设置默认的header */
    		$header_result['User-Agent'] = "Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0";
    		$header_result = array_merge($header_result, $header);
    		/* 载入用户的header */
    		foreach ($header_result as $key => $value) {
    			$out .= $key . ": " . $value . "
    ";
    		}
    		$out .= "Connection: close
    
    ";
    		if (is_array($post_data)) {
    			$out .= $post_content;
    		}
    		fputs($fp, $out);
     
    		$response = '';
    		while (($line = fread($fp, 4096))) {
    			$response .= $line;
    		}
    		fclose($fp);
     
    		//分离Header头信息
    		$pos = strpos($response, "
    
    ");
    		$header_content = substr($response, 0, $pos);
    		$response = substr($response, $pos + 4);
     
    		if (preg_match("/HTTP/d.d (d+) /", $header_content, $matches) !== 1) {
    			$loop_count = 0;
    			return false;
    		}
     
    		$http_status = $matches[1];
    		/* 如果是30x,就跳转 */
    		if ($http_status == 301 || $http_status == 302) {
    			if (preg_match("/Location:(.*?)
    /", $header_content, $matches) !== 1) {
    				$loop_count = 0;
    				return false;
    			}
    			$url = trim($matches[1]);
    			$loop_count++;
    			return curl_post_with_ip($url, $post_data, $ip, $header);
    		}
     
    		$loop_count = 0;
    		return $response;
    	}
    }
    

    https://actom.me/blog/php%E4%BD%BF%E7%94%A8fsockopen%E6%8C%87%E5%AE%9Aip%E9%80%9A%E8%BF%87get%E6%88%96%E8%80%85post%E8%8E%B7%E5%8F%96%E8%BF%9C%E7%A8%8B%E6%95%B0%E6%8D%AE.html/comment-page-1

  • 相关阅读:
    打造基于CentOS7的xfce最简工作环境
    Linux下C程序的编辑,编译和运行以及调试
    修正 XE6 TListView 上方 SearchBok 右边的清除钮显示
    TabControl 显示彩色的图示 (XE6 Firemonkey)
    TSwitch 中文简繁显示支持(XE6 Android)
    改变 TMemo 的背景颜色 (Firemonkey)
    修正 XE5 Android 键盘三个问题
    Delphi 收藏
    展示 Popup 的使用方法
    ListView 下拉更新 (支持 Android)
  • 原文地址:https://www.cnblogs.com/7qin/p/13296846.html
Copyright © 2011-2022 走看看