Home >Backend Development >PHP Tutorial >php fsockopen()有什么用?

php fsockopen()有什么用?

PHPz
PHPzOriginal
2016-06-13 11:11:501901browse

php fsockopen()有什么用?

php fsockopen()函数

函数说明:fsockopen — 打开一个网络连接或者一个Unix套接字连接

语法:

resource fsockopen  ( string $hostname  [, int $port  = -1  [, int &$errno  [, string &$errstr  [, float $timeout  = ini_get("default_socket_timeout")  ]]]] )

参数:

  • hostname 如果安装了OpenSSL,那么你也许应该在你的主机名地址前面添加访问协议ssl://或者是tls://,从而可以使用基于TCP/IP协议的SSL或者TLS的客户端连接到远程主机。 

  • port 端口号。如果对该参数传一个-1,则表示不使用端口,例如unix://。 

  • errno 如果errno的返回值为0,而且这个函数的返回值为 FALSE ,那么这表明该错误发生在套接字连接(connect())调用之前,导致连接失败的原因最大的可能是初始化套接字的时候发生了错误。 

  • errstr 错误信息将以字符串的信息返回。 

  • timeout 设置连接的时限,单位为秒。

返回值:

fsockopen() 将返回一个文件句柄,之后可以被其他文件类函数调用(例如: fgets() , fgetss() , fwrite() , fclose() 还有 feof() )。如果调用失败,将返回 FALSE 。

php fsockopen使用案例

1、fsockopen 来模拟生成 HTTP 连接 

$url="http://www.manongjc.com";
$port=80;
$t=30;
/**fsockopen 抓取页面
 * @parem $url 网页地址
 * @parem $port 端口 默认 80
 * @parem $t 设置连接的时间 默认30s
 * */
function fsock($url,$port=80,$t=30)
{   $info=parse_url($url);
    $fp = fsockopen($info['host'],$port,$errno,$errstr,$t);
    if (!$fp)
    {
        echo "$errstr ($errno)<br />\n";
    }
    else
    {
        $out = "GET ".$info[&#39;path&#39;]." HTTP/1.1".PHP_EOL;     $out .= "Host: ".$info[&#39;host&#39;].".PHP_EOL;     $out .= "Connection: Close".PHP_EOL.PHP_EOL;
        fwrite($fp, $out);
        $content = &#39;&#39;;
        while (!feof($fp))
        {
            $content .= fgets($fp);
        }
        echo $content;
        fclose($fp);
    }
}// 函数调用
fsock($url, $port,$t);

2、PHP fsockopen模拟POST/GET方法

  fsockopen除了像上面实例模拟生成 HTTP 连接之外,还能实现很多功能,比如模拟post 和 get 传送数据的方法。 

$url = "http://localhost/test/test.php"; #url 地址必须 http://xxxxx
$port=80;
$t=30;
$data = array(
    &#39;foo&#39;=>&#39;bar&#39;,
    &#39;baz&#39;=>&#39;boom&#39;,
    &#39;site&#39;=>&#39;www.manongjc.com&#39;,
    &#39;name&#39;=>&#39;nowa magic&#39;);

/**fsockopen 抓取页面
 * @parem $url 网页地址 host 主机地址  * @parem $port 网址端口 默认80 * @parem $t 脚本请求时间 默认30s
 * @parem $method 请求方式 get/post
 * @parem $data 如果单独传数据为 post 方式
 * @return 返回请求回的数据
 * */
function sock_data($url,$port=80,$t=30,$method=&#39;get&#39;,$data=null)
{
    $info=parse_url($url);
    $fp = fsockopen($info["host"],$port, $errno, $errstr,$t);

    // 判断是否有数据
    if(isset($data) && !empty($data))
    {
        $query = http_build_query($data); // 数组转url 字符串形式
    }else
    {
        $query=null;
    }
    // 如果用户的$url "http://www.manongjc.com/";  缺少 最后的反斜杠
    if(!isset($info[&#39;path&#39;]) || empty($info[&#39;path&#39;]))
    {
       $info[&#39;path&#39;]="/index.html";
    }
    // 判断 请求方式
    if($method==&#39;post&#39;)
    {
        $head = "POST ".$info[&#39;path&#39;]." HTTP/1.0".PHP_EOL;
    }else
    {
        $head = "GET ".$info[&#39;path&#39;]."?".$query." HTTP/1.0".PHP_EOL;
    }

   $head .= "Host: ".$info[&#39;host&#39;].PHP_EOL; // 请求主机地址
   $head .= "Referer: http://".$info[&#39;host&#39;].$info[&#39;path&#39;].PHP_EOL;
    if(isset($data) && !empty($data) && ($method==&#39;post&#39;))
    {
        $head .= "Content-type: application/x-www-form-urlencoded".PHP_EOL;
        $head .= "Content-Length: ".strlen(trim($query)).PHP_EOL;
        $head .= PHP_EOL;
        $head .= trim($query);
    }else
    {
        $head .= PHP_EOL;
    }
    $write = fputs($fp, $head); //写入文件(可安全用于二进制文件)。 fputs() 函数是 fwrite() 函数的别名
    while (!feof($fp))
    {
        $line = fread($fp,4096);
        echo $line;
    }
}
// 函数调用
sock_data($url,$port,$t,&#39;post&#39;,$data);

3、fsockopen以Socket方式模拟HTTP下载文件

/**   PHP设置脚本最大执行时间的三种方法
  1.php.ini文件中
     max_execution_time = 120;
    2、通过PHP的ini_set函数设置
    ini_set("max_execution_time", "120");
    3、通过set_time_limit 函数设置
    set_time_limit(120);
    以上几个数字设置为0则无限制,脚本会一直执行下去,直到执行结束。
 * */
set_time_limit(0);

$url = &#39;http://localhost/test/img.zip&#39;;
$port = &#39;80&#39;;
/** sockopen 下载文件
 * @parem $url 访问文件的url 地址
 * @parem $port 默认 80 * @parem $down_name 下载指定路径文件名称 例如 ../aa.zip 
 * */
function sock_down($url,$port=80,$down_name=null)
{
    $info=parse_url($url);

    # 建立连接
    $fp = fsockopen($info["host"],$port,$errno,$errstr,$t);
    /*
     为资源流设置阻塞或者阻塞模式  参数:资源流(),0是非阻塞,1是阻塞
    bool stream_set_blocking ( resource $stream , int $mode )
    阻塞的好处是,排除其它非正常因素,阻塞的是按顺序执行的同步的读取。将会一直等到从资源流里面获取到数据才能返回
    而非阻塞,因为不必等待内容,所以能异步的执行,现在读到读不到都没关系,执行读取操作后会立即返回数据
     * */
    stream_set_blocking($fp, 1);

    if(!$fp)
    {
        echo "$errno : $errstr<br/>";
    }
    else
    {
        # 发送一个HTTP请求信息头
        $request_header="GET ".$info[&#39;path&#39;]." HTTP/1.1".PHP_EOL;
        # 起始行
        # 头域
        $request_header.="Host: ".$info["host"].PHP_EOL;
        # 再一个回车换行表示头信息结束
        $request_header.=PHP_EOL;

        # 发送请求到服务器
        fputs($fp,$request_header);

        if(!isset($down_name) || empty($down_name))
        {
            $down_name=basename($url); //默认当前文件同目录
        }
        # 接受响应
        $fp2=fopen($down_name,&#39;w&#39;); // 要下载的文件名  下载到指定目录
        $line=&#39;&#39;;
        while (!feof($fp))
        {
            $line.= fputs($fp2,fgets($fp));
        }
        if(feof($fp))
        {
            echo "<script>alert(&#39;已下载到当前目录&#39;)</script>";
        }
        # 关闭
        fclose($fp2);
        fclose($fp);
    }
}
//函数调用
sock_down($url,$port);

4、使用 fsockopen 伪造来源网址、路径

更多相关知识,请访问 PHP中文网!!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn