文档章节

php 利用socket发送GET,POST请求

hansonwong
 hansonwong
发布于 2017/07/20 14:24
字数 970
阅读 1
收藏 0

php 利用socket发送GET,POST请求

  作为php程序员一定会接触http协议,也只有深入了解http协议,编程水平才会更进一步。最近我一直在学习php的关于http的编程,许多东西恍然大悟,受益匪浅。希望分享给大家。本文需要有一定http基础的开发者阅读。

  今天给大家带来的是如何利用socket发送GET,POST请求。我借用燕十八老师封装好的一个Http类给进行说明。

  在日常编程中相信很多人和我一样大部分时间是利用浏览器向服务器提出GET,POST请求,那么可否利用其它方式提出GET,POST请求呢?答案必然是肯定的。了解过HTTP协议的人知道,浏览器提交请求的实质是向服务器发送一个请求信息,这个请求信息有请求行,请求头,请求体(非必须)构成。服务器根据请求信息返回一个响应信息。连接断开。

   HTTP请求的格式如下所示:

1 <request-line>
2 <headers>
3 <blank line>
4 [<request-body>]

 

  HTTP响应的格式与请求的格式十分相似:

<status-line>
<headers>
<blank line>

[<response-body>]

  我们可以利用HTTP发送请求的原理,可以重新考虑利用socket发送HTTP请求。

  Socket的英文原义是“孔”或“插座”。通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。如此看来,其实利用socket操作远程文件和读写本地的文件一样容易,把本地文件看成通过硬件传输,远程文件通过网线传输就行了。

  因而可以将发送请求的考虑成 建立连接->打开socket接口(fsockopen())->写入请求(fwrite())->读出响应(fread()->关闭文件(fclose())。话不多说,直接上代码:

 

<?php 

interface Proto {
    // 连接url
    function conn($url);

    //发送get查询
    function get();

    // 发送post查询
    function post();

    // 关闭连接
    function close();
}



class Http implements Proto {

    const CRLF  = "\r\n";

    protected $errno = -1;
    protected $errstr = '';
    protected $response = '';

    protected $url = null;
    protected $version = 'HTTP/1.1';
    protected $fh = null;
    
    protected $line = array();
    protected $header = array();
    protected $body = array();

    
    public function __construct($url) {
        $this->conn($url);
        $this->setHeader('Host: ' . $this->url['host']);
    }

    // 此方法负责写请求行
    protected function setLine($method) {
        $this->line[0] = $method . ' ' . $this->url['path'] . '?' .$this->url['query'] . ' '. $this->version;
    }

    // 此方法负责写头信息
    public function setHeader($headerline) {
        $this->header[] = $headerline; 
    }

    // 此方法负责写主体信息
    protected function setBody($body) {
         $this->body[] = http_build_query($body);
    }


    // 连接url
    public function conn($url) {
        $this->url = parse_url($url);
        // 判断端口
        if(!isset($this->url['port'])) {
            $this->url['port'] = 80;
        }

        // 判断query
        if(!isset($this->url['query'])) {
            $this->url['query'] = '';
        }

        $this->fh = fsockopen($this->url['host'],$this->url['port'],$this->errno,$this->errstr,3);
    }

    //构造get请求的数据
    public function get() {
        $this->setLine('GET');
        $this->request();
        return $this->response;
    }

    // 构造post查询的数据
    public function post($body = array()) {      
        $this->setLine('POST');

        // 设计content-type
        $this->setHeader('Content-type: application/x-www-form-urlencoded');
        
        // 设计主体信息,比GET不一样的地方
        $this->setBody($body);


        // 计算content-length
        $this->setHeader('Content-length: ' . strlen($this->body[0]));

        $this->request();

        return $this->response;
    }

    // 真正请求
    public function request() {
        // 把请求行,头信息,实体信息 放在一个数组里,便于拼接
        $req = array_merge($this->line,$this->header,array(''),$this->body,array(''));
        //print_r($req);

        $req = implode(self::CRLF,$req); 
        //echo $req; exit;

        fwrite($this->fh,$req);
        
        while(!feof($this->fh)) {
            $this->response .= fread($this->fh,1024);
        }

        $this->close(); // 关闭连接
    }


    // 关闭连接
    public function close() {
        fclose($this->fh);
    }

}

      利用此类发送一个简单的GET请求:

<?php

//记得引用Http类
$url="http://home.cnblogs.com/u/DeanChopper/";
$http=new Http($url);


$response=$http->get();

print_r($response);

  返回值为信息,可以对响应信息进行进一步处理,得到自己想得到的内容。

本文转载自:

共有 人打赏支持
hansonwong
粉丝 4
博文 176
码字总数 32310
作品 0
广州
私信 提问
使用PHP Socket 编程模拟Http post和get请求

这里给大家分享一段使用PHP Socket 编程模拟Http post和get请求的代码,非常的实用,结尾部分我们再讨论下php模拟http请求的几种方法。 php 模拟 http请求 方法一:利用php的socket编程来直接...

JK_OPERA
2018/07/31
0
0
Android网络编程概述

首先,应该了解的几个问题: 1)Android平台网络相关API接口 a) Java.net.*(标准Java接口) java.net.*提供与联网有关的类,包括流、数据包套接字(socket)、Internet协议、常见Http处理等。比...

微笑的江豚
2016/06/13
30
0
PHP爬虫工具包--spider-utils-for-php

spider-utils-for-php: 原则: 简单、易用、灵活、任性任性任性就是任性! 特色: php 界内最简单易用的 http-utils,自动识别支持 curl、socket、filegetcontents 三种方式。 http 请求支持...

deajunny
2015/03/28
3.5K
0
python用httplib模块和发送get和post请求

httplib是一个相对底层的http请求模块,其上有专门的包装模块,如urllib内建模块,goto等第三方模块,但是封装的越高就越不灵活,比如urllib模块里请求错误时就不会返回结果页的内容,只有头...

天道酬勤VIP
2017/08/26
0
0
djunny/spider-utils-for-php

简单、易用、灵活的网络类,spider/network for PHP , too simple . spider-utils-for-php: ##原则: 简单、易用、灵活、任性任性任性就是任性! ##特色: php 界内最简单易用的 http-utils...

djunny
2015/03/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Nextjs+React非页面组件SSR渲染

@随风溜达的向日葵 Nextjs Nextjs是React生态中非常受欢迎的SSR(server side render——服务端渲染)框架,只需要几个步骤就可以搭建一个支持SSR的工程(_Nextjs_的快速搭建见Next.js入门)...

随风溜达的向日葵
56分钟前
0
0
如何在 Linux 系统查询机器最近重启时间

在你的 Linux 或类 UNIX 系统中,你是如何查询系统上次重新启动的日期和时间?怎样显示系统关机的日期和时间? last 命令不仅可以按照时间从近到远的顺序列出该会话的特定用户、终端和主机名...

来来来来来
今天
3
0
Redis协议是什么样的

前言 我们用过很多redis的客户端,有没有相过自己撸一个redis客户端? 其实很简单,基于socket,监听6379端口,解析数据就可以了。 redis协议 解析数据的过程主要依赖于redis的协议了。 我们...

春哥大魔王的博客
今天
6
0
乱入Linux界的我是如何学习的

欢迎来到建哥学Linux,咳!咳!咳!开个玩笑哈,我是一个IT男,IT界的入门选手,正在学习Linux。 在之前,一直想进军IT界,学习IT技术,但是苦于没有人指导,也不知道学什么,最开始我自己在...

linuxCool
今天
4
0
携程Apollo统一配置中心的搭建和使用(java)

一.Apollo配置中心介绍 1、What is Apollo 1.1 Apollo简介 Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到...

morpheusWB
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部