<?php
/**
* http请求类(php + socket)
* @todo 这里还有很多未完善的地方,仅有简单的get post head请求
* @author chuangrain@gmail.com
* @version 1.0.0
*/ class HttpClient { const CRLF = "\r\n";
private $fh = null; //socket handle
private $errno = -1; //socket open error no
private $errstr = ''; //socket open error message
private $timeout = 30; //socket open timeout
private $line = array(); //request line
private $header = array();//request header
private $body = array(); //request body
private $url = array(); //request url
private $response = ''; //response
private $version = '1.1'; //http version public function __construct() { } /**
* 发送HTTP get请求
* @access public
* @param string $url 请求的url
*/
public function get($url = '') {
$this->setUrl($url);
$this->setLine();
$this->setHeader();
$this->request();
return $this->response;
} /**
* 发送HTTP post请求
* @access public
*/
public function post() {
$this->setLine('POST');
$this->request();
return $this->response;
} /**
* HTTP -> HEAD 方法,取得服务器响应一个 HTTP 请求所发送的所有标头
* @access public
* @param string $url 请求的url
* @param int $fmt 数据返回形式,关联数组与普通数组
* @return array 返回响应头信息
*/
public function head($url = '', $fmt = 0) {
$headers = null;
if (is_string($url)) {
$headers = get_headers($url, $fmt);
}
return $headers;
} /**
* 设置要请求的 url
* @todo 这里未做url验证
* @access public
* @param string $url request url
* @return bool
*/
public function setUrl($url = '') {
if (is_string($url)) {
$this->url = parse_url($url);
if (!isset($this->url['port'])) {//设置端口
$this->url['port'] = 80;
}
} else {
return false;
}
} /**
* 设置HTTP协议的版本
* @access public
* @param string $version HTTP版本,default value = 1.1
* @return bool 如果不在范围内返回false
*/
public function setVersion($version = "1.1") {
if ($version == '1.1' || $version == '1.0' || $version == '0.9') {
$this->version = $version;
} else {
return false;
}
} /**
* 设置HTTP请求行
* @access public
* @param string $method 请求方式 default value = GET
*/
private function setLine($method = "GET") {
//请求空:Method URI HttpVersion
if (isset($this->url['query'])) {
$this->line[0] = $method . " " . $this->url['path'] . "?" . $this->url['query'] . " HTTP/" . $this->version;
} else {
$this->line[0] = $method . " " . $this->url['path'] . " HTTP/" . $this->version;
}
} /**
* 设置HTTP请求头信息
* @access public
* @param array $header 请求头信息
*/
public function setHeader($header = null) {
$this->header[0] = "Host: " . $this->url['host'];
if (is_array($header)) {
foreach($header as $k => $v) {
$this->setHeaderKeyValue($k, $v);
}
}
} /**
* HTTP请求主体
* @access public
* @param array $body 请求主体
*/
public function setBody($body = null) {
if (is_array($body)) {
foreach ($body as $k => $v) {
$this->setBodyKeyValue($k, $v);
}
}
} /**
* 单条设置HTTP请求主体
* @access public
* @param string $key 请求主体的键
* @param string $value 请求主体的值
*/
public function setBodyKeyValue($key, $value) {
if (is_string($key)) {
$this->body[] = $key . "=" . $value;
}
} /**
* 单条设置HTTP请求头信息
* @access public
* @param string $key 请求头信息的键
* @param string $value 请求头信息的键
*/
public function setHeaderKeyValue($key, $value) {
if (is_string($key)) {
$this->header[] = $key . ": " . $value;
}
} /**
* socket连接host, 发送请求
* @access private
*/
private function request() {
//构造http请求
if (!empty($this->body)) {
$bodyStr = implode("&", $this->body);
$this->setHeaderKeyValue("Content-Length", strlen($bodyStr));
$this->body[] = $bodyStr;
$req = array_merge($this->line, $this->header, array(""), array($bodyStr), array(""));
} else {
$req = array_merge($this->line, $this->header, array(""), $this->body, array(""));
}
$req = implode(self::CRLF, $req); //socket连接host
$this->fh = fsockopen($this->url['host'], $this->url['port'], $this->errno, $this->errstr, $this->timeout); if (!$this->fh) {
echo "socket connect fail!";
return false;
} //写请求
fwrite($this->fh, $req); //读响应
while (!feof($this->fh)) {
$this->response .= fread($this->fh, 1024);
}
} /**
* 关闭socket连接
* @access public
*/
public function __destruct() {
if ($this->fh) {
fclose($this->fh);
}
} } $url = "http://localhost/xdebug/post_test.php"; /** get test **/
$http1 = new HttpClient();
var_dump($http1->get($url)); /** post test **/
$http2 = new HttpClient();
$header = array(
"Content-Type" => "application/x-www-form-urlencoded"
);
$body = array(
"username" => "1234",
"submit" => "Login"
);
$http2->setUrl($url);
$http2->setHeader($header);
$http2->setBody($body);
var_dump($http2->post()); /** head test **/
$http3 = new HttpClient();
var_dump($http3->head($url, 1));
post_test.php code list
[php] view plaincopyprint?
<?php var_dump($_POST); ?> <!DOCTYPE html>
<html>
<head>
<title>post request test</title>
</head>
<body>
<form action="" method="post">
<input type="text" name="username">
<input type="submit" name="submit" value="Login">
</form>
</body>
</html>

php+socket模拟表单发送请求的更多相关文章

  1. form表单发送请求实例

    <%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncodi ...

  2. Form表单发送到服务器时的编码方式

    ---恢复内容开始--- 表单中的表单中enctype是设置表单的MIME编码. 所谓MIME编码,是指当服务器传送数据给客户端时,必须指定这个文件是什么类型,才能方便客户端调用相应的应用软件来打开该 ...

  3. 织梦cmsf表单提交到邮箱 织梦表单发送到邮箱 织梦自定义表单发邮箱

    大家在做织梦做网站开发时会遇到一个问题:织梦的自定义表单是一个很鸡肋的功能,不仅在后台展示得奇丑,而且也没有提醒功能,使用起来很不方便.很多人用织梦自定义表单时,都想用户提交表单的时候可以发送到自己的 ...

  4. C# POST 表单发送文件

    表单提交协议规定:要先将 HTTP 要求的 Content-Type 设为 multipart/form-data,而且要设定一个 boundary 参数,这个参数是由应用程序自行产生,它会用来识别每 ...

  5. dedecms织梦自定义表单发送到邮箱-用163邮箱发送邮件

    https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=monline_3_dg&wd=dedecms 邮箱&oq=d ...

  6. php表单发送到邮箱V1.0

    html表单代码: <form action="index.php" name="form" method="POST"> &l ...

  7. php Socket模拟表单上传文件函数_学习

    模拟上传文件的php代码 里面访问地址.主机.上传文件名.内容.分隔符可以修改   function postFile($file) {     $clf = "\r\n";   ...

  8. HTTP 笔记与总结(3 )socket 编程:发送 GET 请求

    使用 PHP + socket 模拟发送 HTTP GET 请求,过程是: ① 打开连接 ② 构造 GET 请求的数据:写入请求行.请求头信息.请求主体信息(GET 请求没有主体信息) ③ 发送 GE ...

  9. PHP+SOCKET 模拟HTTP请求

    HTTP消息结构 客户端请求包括四部份:请求行(状态行).请求头.空行.请求主体(数据),如下图: 服务端响应包括四部份:响应行(状态行).响应头.空行.响应主体(数据),如图: HTTP请求方法: ...

随机推荐

  1. PHP全选择删除功能

    <script type="text/javascript" language="javascript"> function selectBox(s ...

  2. openwrt+ndp+ndppd+radvd+dhcpv6,ipv6穿透配置指南

    要用ipv6首先你的openwrt路由内核必须已经支持ipv6,且能安装相关软件! 首先说说最简单的ndp手工ipv6穿透,很简单,看代码详解: 环境: wan口 eth1 lan口 br-lan w ...

  3. mysql问题总结,远程登录

    http://blog.sina.com.cn/s/blog_4550f3ca0101axzd.html 更改mysql数据库的数据库名 http://tech.sina.com.cn/s/s/200 ...

  4. lucene-SpanFirstQuery 和SpanNearQuery 跨度查询

    1.SpanFirstQuery查询 对出现在一个域中前n个位置的跨度查询. public void testSpanFirstQuery() throws Exception{ SpanzFirts ...

  5. Python -- Web -- 使用框架

    Python的web框架有很多: Flask,Django,Zope2,Web.py,Web2py,Pyramid,Bottle, Tornado... Flask 轻量级,比较简单 from fla ...

  6. HDU 5722 Jewelry

    矩形面积并. 需要转化一下思路:记录每一个位置的数以及位置. 对数字进行从小到大排序,数字一样的按位置从小到大排. 这样,一样的数就在一起了.连续的相同的x个数就可以构成很多解,这些解对应于二维平面上 ...

  7. PAT1014

    Suppose a bank has N windows open for service. 一个银行有N个服务的窗口 There is a yellow line in front of the w ...

  8. 解决 Oracle 11g 不能导出空表的问题

    --解决 Oracle 11g 不能导出空表的问题 --执行下面语句,查询数据库中的空表,同时产生分配空间.把生成的结果复制出来并执行. select 'alter table '||table_na ...

  9. sphinx query multiple indexes in php

    http://stackoverflow.com/questions/17494784/searching-a-particular-index-using-sphinx-from-multiple- ...

  10. MiniProfiler找不到jquery的

    我一直在使用MiniProfiler来衡量网站性能.当我从1.9版本升级到2.0,它停止工作.我改变了命名空间从MvcMiniProfiler StackExchange.Profiling的.但是, ...