浏览器发送 POST 请求:
表单 form.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="a.php" method="post">
username: <input type="text" name="username">
password: <input type="password" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
a.php 接收数据
<?php
print_r($_POST);
HTTP POST 的请求和响应
telnet 模拟 POST 请求:
POST /php/http/a.php HTTP/1.1
Host: 127.0.0.17
Content-type: application/x-www-form-urlencoded
Content-length: 28 username=dee&password=123456HTTP/1.1 200 OK
Date: Sat, 11 Jul 2015 17:05:31 GMT
Server: Apache/2.2.21 (Win32) PHP/5.3.10
X-Powered-By: PHP/5.3.10
Content-Length: 57
Content-Type: text/html Array
(
[username] => dee
[password] => 123456
)
http 发送类 http.calss.php 补全 POST 请求:
测试打印拼接的 POST 请求的请求行、头信息、主体信息,代码:
<?php
/*
PHP + socket 编程
@发送 HTTP 请求
@模拟下载
@实现注册、登录、批量发帖
*/ //http 请求类的接口
interface Proto{
//连接 url
function conn($url); //发送 GET 请求
function get(); //发送 POST 请求
function post(); //关闭连接
function close();
} class Http implements Proto{ //换行符
const CRLF = "\r\n"; //fsocket 的错误号与错误描述
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->version;
} //写头信息
protected function setHeader($headerline){
$this->header[] = $headerline;
} //写主体信息
protected function setBody($body){
//构造 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;
}
$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 和 Content-length
$this->setHeader('Content-type: application/x-www-form-urlencoded'); //构造主体信息, 和 GET 请求不一样的地方
$this->setBody($body); $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(''));
$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);
}
} set_time_limit(0); //$url = 'http://book.douban.com/subject/26376603/';
$url = 'http://127.0.0.17/php/http/a.php'; $http = new Http($url);
//echo $http->get(); //打乱
$str = str_shuffle('abcdefghijklmnopqrstuvwxyz0123456789');
$username = substr($str, 0, 5);
$password = substr($str, 6, 12); $body = array(
'username'=>$username,
'password'=>$password
);
$http->post($body); echo $username,'--',$password;
输出:
然后发送请求,同时配合 for 循环就可以进行(不注册且没有验证码的)批量注册(把 username 换成 title,password 换成 content,可以使用 php 的命令行工具 ,在 cmd 中执行 php.exe 文件路径)。
使用命令行如下所示:
完整代码:
<?php
/*
PHP + socket 编程
@发送 HTTP 请求
@模拟下载
@实现注册、登录、批量发帖
*/ //http 请求类的接口
interface Proto{
//连接 url
function conn($url); //发送 GET 请求
function get(); //发送 POST 请求
function post(); //关闭连接
function close();
} class Http implements Proto{ //换行符
const CRLF = "\r\n"; //fsocket 的错误号与错误描述
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->version;
} //写头信息
protected function setHeader($headerline){
$this->header[] = $headerline;
} //写主体信息
protected function setBody($body){
//构造 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;
}
$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 和 Content-length
$this->setHeader('Content-type: application/x-www-form-urlencoded'); //构造主体信息, 和 GET 请求不一样的地方
$this->setBody($body); $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(''));
$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);
}
} set_time_limit(0); //$url = 'http://book.douban.com/subject/26376603/';
$url = 'http://127.0.0.17/php/http/a.php'; $http = new Http($url);
//echo $http->get(); //批量
for($i = 1; $i < 100; $i++){ //打乱
$str = str_shuffle('abcdefghijklmnopqrstuvwxyz0123456789');
$username = substr($str, 0, 5);
$password = substr($str, 6, 12); $body = array(
'username'=>$username,
'password'=>$password
);
$http->post($body); echo $username,'--',$password; usleep(2000);
}