PHP的3种发送HTTP请求的方式
1.CURL方式发送数据及上传文件
<?php class IndexController extends ControllerBase
{ public function indexAction()
{
$url = 'http://192.168.10.168/home/index';
$data = array(
'name'=>'网络开发',
'address'=>'123456789',
//"file" => "@".getcwd()."/temp/test.zip",//要上传的本地文件地址"@"上传时候,上传路径前面要有@符号
'file' => new cURLFile(getcwd()."/temp/test.zip"),
); //没有影响,但是还是有少部分服务器不兼容。本文得出的结论是,在没有需要上传文件的
//情况下,尽量对post提交的数据进行http_build_query,然后发送出去,能实现更好的兼容性,
$url = $url."?".http_build_query($data); $res = $this->mycurl($url); //解析xml
//simplexml_load_string($pageContents, 'SimpleXMLElement', LIBXML_NOCDATA)
//$data = json_encode($data);
//$res = $this->mycurl($url,$data);
var_export($res);
}
public function mycurl($url, $postfields = NULL, $method='POST'){
//$url = "http://127.0.0.1:8888";
$result = array( 'header' => '',
'body' => '',
'curl_error' => '',
'http_code' => '',
'last_url' => '');
$timeout = 10;//超时时间
$connectTimeout = 0;//无限等待
$ssl = substr($url, 0, 8) == "https://" ? true : false;
$header = array(
//"Content-Type: application/x-www-form-urlencoded",
"Content-Type: multipart/form-data",
"Keep-Alive: 300"); //开始curl
$ci = curl_init();
//设置curl使用的HTTP协议,CURL_HTTP_VERSION_NONE(让curl自己判断),CURL_HTTP_VERSION_1_0(HTTP/1.0),CURL_HTTP_VERSION_1_1(HTTP/1.1)
curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
//在HTTP请求中包含一个”user-agent”头的字符串。
curl_setopt($ci, CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $connectTimeout); //在发起连接前等待的时间,如果设置为0,则无限等待
curl_setopt($ci, CURLOPT_TIMEOUT, $timeout);
//如果成功只返回TRUE,自动输出返回的内容。如果失败返回FALSE 获取的信息以文件流的形式返回
curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
curl_setopt($ci, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
//header中“Accept-Encoding: ”部分的内容,支持的编码格式为:"identity","deflate","gzip"。如果设置为空字符串,则表示支持所有的编码格式
curl_setopt($ci, CURLOPT_ENCODING, "");
if ($ssl) {
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, 0); // 信任任何证书 浏览器访问https的时候,浏览器会自动加载网站的安全证书进行加密
curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, 1); // 检查证书中是否设置域名 从证书中检查SSL加密算法是否存在
}
//避免data数据过长问题 设置一个header中传输内容的数组
curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:')); //以json方式传输
if(!is_array($postfields) && is_string($postfields)){
curl_setopt($ci, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length:'.strlen($postfields)));
} //已指定header头格式传输
//curl_setopt($ci, CURLOPT_HTTPHEADER, $header);
//设置一个回调函数,这个函数有两个参数,第一个是curl的资源句柄,第二个是输出的header数据。header数据的输出必须依赖这个函数,返回已写入的数据大小
//如果你想把一个头包含在输出中,设置这个选项为一个非零值。 返回response头部信息 显示返回的Header区域内容
curl_setopt($ci, CURLOPT_HEADER, 1); switch ($method) {
case 'POST':
curl_setopt($ci, CURLOPT_POST, 1);// 发送一个常规的Post请求
if (!empty($postfields)) {
curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
}
break;
case 'DELETE':
curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
if (!empty($postfields)) {
$url = "{$url}?{$postfields}";
}
break;
}
curl_setopt($ci, CURLOPT_URL, $url);
//发送请求的字符串头
curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE); $response = curl_exec($ci);
$error = curl_error($ci); //获取http头部信息
$response_header_info = curl_getinfo($ci, CURLINFO_HEADER_OUT);// CURLINFO_HEADER_OUT 必须设置成1 才返回
$http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
$result['http_code'] = $http_code;
$result['last_url'] = curl_getinfo($ci,CURLINFO_EFFECTIVE_URL);
$this->log->info("response_header_info:\n".$response_header_info); //获取错误信息
if ( $error != "" )
{
$this->log->info("状态码:".$http_code." 发送失败:".json_encode($error));
$result['curl_error'] = $error;
$result['curl_error_no'] = curl_errno($ci);
curl_close ($ci);
return $result;
}
if( $response )
{
$header_size = curl_getinfo($ci,CURLINFO_HEADER_SIZE);
$result['header'] = substr($response, 0, $header_size);
$result['body'] = substr( $response, $header_size );
$this->log->info("状态码:".$http_code." 成功发送:".json_encode($response));
}
curl_close ($ci);
return $result; } }
接受方PHP:receive.php
<?php class HomeController extends ControllerBase
{ public function indexAction()
{ echo "Success ok!";
if($_GET){
foreach ($_GET as $k =>$v)
{
$this->log->debug("get----------------$k=$v");
}
}
//只能接收Content-Type: application/x-www-form-urlencoded提交的数据
if($_POST){
foreach ($_POST as $k =>$v)
{
$this->log->debug("post----------------$k=$v");
}
}
//方法2、file_get_contents("php://input"); Content-Type: application/json
$input = file_get_contents("php://input");
if($input){
$json_data = json_decode($input);
if($json_data){
foreach ($json_data as $k =>$v)
{
$this->log->debug("json_decode----------------$k=$v");
}
}
$this->log->debug("file_get----------------$input");
}
//获取上传文件
if($_FILES){
$file = move_uploaded_file($_FILES['file']['tmp_name'], getcwd()."/files/1.rar");
if($file){
echo "保存文件成功";
}
} }
}
2.stream流的方式
stream_context_create — 创建资源流上下文
stream_context_create 作用:创建并返回一个文本数据流并应用各种选项,
可用于 fopen(), file_get_contents() 等过程的超时设置、代理服务器、请求方式、头信息设置的特殊过程。
例子:
<?php
function post($url, $data)
{
$postdata = http_build_query(
$data
); $opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
return $result;
}
3.socket方式
使用套接字建立连接,拼接 HTTP 报文发送数据进行 HTTP 请求。
fsockopen — 打开一个网络连接或者一个Unix套接字连接
说明
$hostname
[, int $port
= -1 [, int &$errno
[, string &$errstr
[, float $timeout
= ini_get("default_socket_timeout") ]]]] )初始化一个套接字连接到指定主机(hostname
)。
PHP支持以下的套接字传输器类型列表 所支持的套接字传输器(Socket Transports)列表。也可以通过stream_get_transports()来获取套接字传输器支持类型。
默认情况下将以阻塞模式开启套接字连接。当然你可以通过stream_set_blocking()将它转换到非阻塞模式。
stream_socket_client()与之非常相似,而且提供了更加丰富的参数设置,包括非阻塞模式和提供上下文的的设置。
参数
hostname
-
如果安装了OpenSSL,那么你也许应该在你的主机名地址前面添加访问协议ssl://或者是tls://,从而可以使用基于TCP/IP协议的SSL或者TLS的客户端连接到远程主机。
port
-
端口号。如果对该参数传一个-1,则表示不使用端口,例如unix://。
errno
-
如果传入了该参数,holds the system level error number that occurred in the system-level connect() call。
如果
errno
的返回值为0,而且这个函数的返回值为FALSE
,那么这表明该错误发生在套接字连接(connect())调用之前,导致连接失败的原因最大的可能是初始化套接字的时候发生了错误。 errstr
-
错误信息将以字符串的信息返回。
timeout
-
设置连接的时限,单位为秒。
Note:
注意:如果你要对建立在套接字基础上的读写操作设置操作时间设置连接时限,请使用stream_set_timeout(),fsockopen()的连接时限(
timeout
)的参数仅仅在套接字连接的时候生效。
返回值
fsockopen()将返回一个文件句柄,之后可以被其他文件类函数调用(例如:fgets(),fgetss(),fwrite(),fclose()还有feof())。如果调用失败,将返回FALSE
。
<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
用fsockopen 以post方式获取数据
<?php
function HTTP_Post($URL,$data,$cookie, $referrer="")
{
// parsing the given URL
$URL_Info=parse_url($URL);
// Building referrer
if($referrer=="") // if not given use this script as referrer
$referrer="111";
// making string from $data
foreach($data as $key=>$value)
$values[]="$key=".urlencode($value);
$data_string=implode("&",$values);
// Find out which port is needed - if not given use standard (=80)
if(!isset($URL_Info["port"]))
$URL_Info["port"]=80;
// building POST-request:
$request.="POST ".$URL_Info["path"]." HTTP/1.1\n";
$request.="Host: ".$URL_Info["host"]."\n";
$request.="Referer: $referer\n";
$request.="Content-type: application/x-www-form-urlencoded\n";
$request.="Content-length: ".strlen($data_string)."\n";
$request.="Connection: close\n";
$request.="Cookie: $cookie\n";
$request.="\n";
$request.=$data_string."\n";
$fp = fsockopen($URL_Info["host"],$URL_Info["port"]);
fputs($fp, $request);
while(!feof($fp)) {
$result .= fgets($fp, 1024);
}
fclose($fp);
return $result;
}
?>
用fsockopen函数打开url,以get方式获取完整的数据,包括header和body,fsockopen需要 PHP.ini 中
allow_url_fopen 选项开启
<?php
function get_url ($url,$cookie=false)
{
$url = parse_url($url);
$query = $url[path]."?".$url[query];
echo "Query:".$query;
$fp = fsockopen( $url[host], $url[port]?$url[port]:80 , $errno, $errstr, 30);
if (!$fp) {
return false;
} else {
$request = "GET $query HTTP/1.1\r\n";
$request .= "Host: $url[host]\r\n";
$request .= "Connection: Close\r\n";
if($cookie) $request.="Cookie: $cookie\n";
$request.="\r\n";
fwrite($fp,$request);
while()) {
$result .= @fgets($fp, 1024);
}
fclose($fp);
return $result;
}
}
//获取url的html部分,去掉header
function GetUrlHTML($url,$cookie=false)
{
$rowdata = get_url($url,$cookie);
if($rowdata)
{
$body= stristr($rowdata,"\r\n\r\n");
$body=substr($body,4,strlen($body));
return $body;
}
return false;
}
?>
PHP的3种发送HTTP请求的方式的更多相关文章
- java 常见几种发送http请求案例
import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java ...
- iOS中4种判断网络请求的方式(系统状态栏、AFNetworking、Reachability、自定义)
iOS 实时判断网络状态 方法一:利用系统状态栏判断网络状态 // 状态栏是由当前app控制的,首先获取当前app UIApplication *app = [UIApplication shared ...
- (转) c/c++调用libcurl库发送http请求的两种基本用法
libcurl主要提供了两种发送http请求的方式,分别是Easy interface方式和multi interface方式,前者是采用阻塞的方式发送单条数据,后者采用组合的方式可以一次性发送多条数 ...
- PHP发送HTTP请求的几种方式
转发:https://blog.tanteng.me/2017/07/php-curl-guzzlehttp/ 1)PHP开发中我们常用CURL 方式封装 HTTP请求,什么是CURL? CURL 是 ...
- Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- (一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
(一)----使用HttpClient发送HTTP请求(通过get方法获取数据) 一.HTTP协议初探: HTTP(Hypertext Transfer Protocol)中文 “超文本传输协议”,是 ...
- 发送http请求的方法
在http/1.1 协议中,定义了8种发送http请求的方法 get post options head put delete trace connect patch. 根据http协议的设计初衷,不 ...
- Android之网络----使用HttpClient发送HTTP请求(通过get方法获取数据)
[正文] 一.HTTP协议初探: HTTP(Hypertext Transfer Protocol)中文 "超文本传输协议",是一种为分布式,合作式,多媒体信息系统服务,面向应用层 ...
- 网络相关系列之中的一个:Android中使用HttpClient发送HTTP请求
一.HTTP协议初探: HTTP(Hypertext Transfer Protocol)中文 "超文本传输协议",是一种为分布式,合作式,多媒体信息系统服务,面向应用层的协议,是 ...
随机推荐
- asp.net mvc 使用bootstrap的模态框插件modal
编译器:vs2012 jquery版本:jquery-1.10.2.js bootstrap:bootstrap.js v3.0.0,包含modal插件 我们要实现一个使用模态框展示从服务器获取的数据 ...
- IdentityServer4:发布环境的数字签名证书
一,jwt的三个组成部件 先来看一个由IdentityServer颁发的一个标准令牌 eyJhbGciOiJSUzI1NiIsImtpZCI6IjBiNTE3ZjIzYWY0OGM4ZjkyZjExM ...
- ②将SVN迁移到GitLab-多分支多标签迁移
之前我们介绍了<①将SVN迁移到GitLab-单分支迁移>,文中研究了svn迁移到git单分支的操作过程,本文针对实际开发过程中svn使用到的trunk.branches.tags情况进行 ...
- flutter apk 打包
https://blog.csdn.net/weixin_33738578/article/details/87998565 http://www.cnblogs.com/sangwl/p/10400 ...
- tp框架防止表单重复提交
转载 框架官方 http://www.thinkphp.cn/topic/9090.html 第三方 https://my.oschina.net/caomenglong/blog/728908
- 为什么Java中一个char能存下一个汉字
在Java中,char的长度是2字节,即16位,2的16次方是65536. 1.如果采用utf-8编码,一个汉字占3个字节,char为什么还能存下一个汉字呢? 参考:https://developer ...
- Coldfusion Sql查询分组输出
<cfoutput query="myQry" group="date"> #date# <cfoutput> #detail# < ...
- TweenMax—ScrambleText插件 实现类似电脑破译密码的特效
首先贴一下TweenMax的中文网:https://www.tweenmax.com.cn/ 首先先展示一下最后的效果,需要的就继续看下去: 那团乱码是会一直变的 那么如何实现上图的效果呢??? 其实 ...
- 常见SVN图标的含义
转自:https://www.cnblogs.com/genhaosan/articles/5129791.html 灰色向右箭头:本地修改过 蓝色向左箭头:SVN上修改过 灰色向右且中间有个加号的箭 ...
- MySQL DataType--隐式类型转换
隐式类型转换 在官方文档中对隐式类型转换规则有如下描述: 1. If one or both arguments are NULL, the result of the comparison is N ...