php 接收curl json数据格式,curl发送 JSON格式POST数据的接收,以及在yii2框架中的实现原理【精细剖析】...
1.通过curl发送json格式的数据,譬如代码:
function http_post_json($url, $jsonStr)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json; charset=utf-8',
'Content-Length: ' . strlen($jsonStr)
)
);
$response = curl_exec($ch);
//$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $response;
}
$api_url = 'http://fecshop.appapi.fancyecommerce.com/44.php';
$post_data = [
'username' => 'terry',
'password' => 'terry4321'
];
然后在接收端,使用$_POST接收,发现打印是空的
原因是,PHP默认只识别application/x-www.form-urlencoded标准的数据类型,因此接收不到,只能通过
//第一种方法
$post = $GLOBALS['HTTP_RAW_POST_DATA'];
//第二种方法
$post = file_get_contents("php://input");
来接收
2.如果我们在Yii2框架内,想通过
$username = Yii::$app->request->post('username');
$password = Yii::$app->request->post('password');
这种方式获取第一部分使用curl json方式传递的post参数,我们发现是不行的,我们需要设置yii2 request component
'request' => [
'class' => 'yii\web\Request',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
然后我们通过
$username = Yii::$app->request->post('username');
$password = Yii::$app->request->post('password');
发现是可以取值的了,然后如果你打印 $_POST,会发现这里依旧没有值,这是为什么呢?
下面我们通过代码顺藤摸瓜的查一下Yii2的源代码:
1.打开 yii\web\Request 找到post()方法:
public function post($name = null, $defaultValue = null)
{
if ($name === null) {
return $this->getBodyParams();
}
return $this->getBodyParam($name, $defaultValue);
}
发现值是由 $this->getBodyParam($name, $defaultValue) 给予
然后找到这个方法,代码如下:
/**
* Returns the request parameters given in the request body.
*
* Request parameters are determined using the parsers configured in [[parsers]] property.
* If no parsers are configured for the current [[contentType]] it uses the PHP function `mb_parse_str()`
* to parse the [[rawBody|request body]].
* @return array the request parameters given in the request body.
* @throws \yii\base\InvalidConfigException if a registered parser does not implement the [[RequestParserInterface]].
* @see getMethod()
* @see getBodyParam()
* @see setBodyParams()
*/
public function getBodyParams()
{
if ($this->_bodyParams === null) {
if (isset($_POST[$this->methodParam])) {
$this->_bodyParams = $_POST;
unset($this->_bodyParams[$this->methodParam]);
return $this->_bodyParams;
}
$rawContentType = $this->getContentType();
if (($pos = strpos($rawContentType, ';')) !== false) {
// e.g. application/json; charset=UTF-8
$contentType = substr($rawContentType, 0, $pos);
} else {
$contentType = $rawContentType;
}
if (isset($this->parsers[$contentType])) {
$parser = Yii::createObject($this->parsers[$contentType]);
if (!($parser instanceof RequestParserInterface)) {
throw new InvalidConfigException("The '$contentType' request parser is invalid. It must implement the yii\\web\\RequestParserInterface.");
}
$this->_bodyParams = $parser->parse($this->getRawBody(), $rawContentType);
} elseif (isset($this->parsers['*'])) {
$parser = Yii::createObject($this->parsers['*']);
if (!($parser instanceof RequestParserInterface)) {
throw new InvalidConfigException("The fallback request parser is invalid. It must implement the yii\\web\\RequestParserInterface.");
}
$this->_bodyParams = $parser->parse($this->getRawBody(), $rawContentType);
} elseif ($this->getMethod() === 'POST') {
// PHP has already parsed the body so we have all params in $_POST
$this->_bodyParams = $_POST;
} else {
$this->_bodyParams = [];
mb_parse_str($this->getRawBody(), $this->_bodyParams);
}
}
return $this->_bodyParams;
}
打印 $rawContentType = $this->getContentType(); 这个变量,发现他的值为:
application/json , 然后查看函数getContentType()
public function getContentType()
{
if (isset($_SERVER['CONTENT_TYPE'])) {
return $_SERVER['CONTENT_TYPE'];
}
if (isset($_SERVER['HTTP_CONTENT_TYPE'])) {
//fix bug https://bugs.php.net/bug.php?id=66606
return $_SERVER['HTTP_CONTENT_TYPE'];
}
return null;
}
也就是 当我们发送json格式的curl请求, $_SERVER['CONTENT_TYPE'] 的值为 application/json
2.重新回到上面的函数 getBodyParams(),他会继续执行下面的代码:
if (isset($this->parsers[$contentType])) {
$parser = Yii::createObject($this->parsers[$contentType]);
if (!($parser instanceof RequestParserInterface)) {
throw new InvalidConfigException("The '$contentType' request parser is invalid. It must implement the yii\\web\\RequestParserInterface.");
}
$this->_bodyParams = $parser->parse($this->getRawBody(), $rawContentType);
}
$parser 就是根据我们下面的request component配置中的 parsers中得到'yii\web\JsonParser',进而通过容器生成出来的
'request' => [
'class' => 'yii\web\Request',
'enableCookieValidation' => false,
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
因此返回值就是 $parser->parse($this->getRawBody(), $rawContentType); 返回的,
3.首先我们查看传递的第一个参数是函数 $this->getRawBody(),代码如下:
public function getRawBody()
{
if ($this->_rawBody === null) {
$this->_rawBody = file_get_contents('php://input');
}
return $this->_rawBody;
}
通过这个函数,回到前面我们说的,可以通过
//第一种方法
$post = $GLOBALS['HTTP_RAW_POST_DATA'];
//第二种方法
$post = file_get_contents("php://input");
这两种方式获取curl json传递的json数据,yii2使用的是第二种。
然后我们打开yii\web\JsonParser
/**
* Parses a HTTP request body.
* @param string $rawBody the raw HTTP request body.
* @param string $contentType the content type specified for the request body.
* @return array parameters parsed from the request body
* @throws BadRequestHttpException if the body contains invalid json and [[throwException]] is `true`.
*/
public function parse($rawBody, $contentType)
{
try {
$parameters = Json::decode($rawBody, $this->asArray);
return $parameters === null ? [] : $parameters;
} catch (InvalidParamException $e) {
if ($this->throwException) {
throw new BadRequestHttpException('Invalid JSON data in request body: ' . $e->getMessage());
}
return [];
}
}
可以看到这里是将传递的json转换成数组,然后Yii::request->post('username')就可以从返回的这个数组中取值了
总结:
1.在Yii2框架中要用封装的post() 和 get()方法, 而不要使用$_POST $_GET等方法,因为两者是不相等的。
2.Yii2做api的时候,如果是json格式传递数据,一定不要忘记在request component中加上配置:
'request' => [
'class' => 'yii\web\Request',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
本文由 Terry 创作,采用 知识共享署名 3.0 中国大陆许可协议 进行许可。
可自由转载、引用,但需署名作者且注明文章出处。
php 接收curl json数据格式,curl发送 JSON格式POST数据的接收,以及在yii2框架中的实现原理【精细剖析】...相关推荐
- curl请求模拟post发送json
示例:curl -X POST --header "Content-Type:application/json" --data '{"name":"s ...
- JSON数据格式----- JavaScript与JSON、JavaScript的JSON对象、构建JSON格式数据
JavaScript与JSON JSON是一种语法,用来序列化对象.数组等的.它只是基于JavaScript语法 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zWMc ...
- HTML地址栏传数据和json区别,前端利用formData格式进行数据上传,前端formData 传值 和 json传值的区别?...
contentType 常见的格式 text/plain :纯文本格式 application/json: JSON数据格式 application/x-www-form-urlencoded 中默认 ...
- 后台怎么接收处理从url 客户端传来的json数据格式
最近做项目用到了 一个新的客户端传参的方式,主要采用的是客户端以json数据格式的方式想后台传递数据,所以,后台接收的参数也是json格式的,刚开始不知道怎么做, 到最后才找到了解决的办法就是利用go ...
- Ajax---使用json数据格式输出数据
将Ajax得到的数据使用json数据格式输出 1.项目清单 2.代码 2.1.Procince类代码 2.2.ProvinceDao类代码 2.3.QueryJsonServlet类代码 2.4.Te ...
- java 蓝牙读取数据格式,单片机与安卓手机通过蓝牙串口模块利用JSON数据格式通信实例...
原标题:单片机与安卓手机通过蓝牙串口模块利用JSON数据格式通信实例 JSON 指的是 Java 对象表示法(Java Object Notation),JSON 是轻量级的文本数据交换格式,JSON ...
- 使用Qt通过Post发送Json格式数据
一.简介 1.任务目标 使用Qt通过post发送Json格式数据,或者以表单形式发送数据到服务器 2.环境简介 系统:Windows 10 Qt版本:5.7 二.内容准备 1.关于Qt 1.使用Pos ...
- android 解析json数据格式
前面我有用到android发送json数据:这里我想总结一下我用到的解析json数据格式的方式 json数据格式解析我自己分为两种: 一种是普通的,一种是带有数组形式的: 普通形式的: 服务器端返回的 ...
- ajax 中json格式数据格式,AJAX中的dataType(数据格式)-text、json
因为经常使用数据格式,所以将它封装成类,J这样就不会用到时就写了,直接调用写好的类就可以了 (1)dataType数据格式为:TEXT格式的数据是字符串的数据,在"ajax对数据进行删除和查 ...
最新文章
- python网盘提取码怎么用_Python 一键获取百度网盘提取码
- FilterDispatcher is deprecated! Please use
- document引用图片的src属性能干嘛_如何实现图片懒加载
- 旅行报告:JavaOne 2013 –重归荣耀
- 这份NLP研究进展汇总请收好,GitHub连续3天最火的都是它
- 2015-ResNet讲解
- IT项目管理之系统规划
- conda 安装本地包_export包本地安装以及R包被CRAN移除后如何继续安装
- Zune支持哪些格式?
- Java多线程编程模式实战指南一:Active Object模式
- Docker 入门教程
- 提示fxp不是一个目标文件
- Base64 在线编码解码
- 6s信号时有有时无服务器,苹果iPhone6s信号弱或无服务解决方法
- 论文工具大全+软件简介
- 在Docker 上完成对Springboot+Mysql+Redis的前后端分离项目的部署(全流程,全截图)
- RecyclerView添加头部
- 深入浅出pytorch
- explaining and harnessing adversarial examples(FGSM)
- 普通高中计算机装备标准,福建省普通高中信息技术装备标准.doc
热门文章
- 数据分析系列:绘制折线图(matplotlib)
- 【android-tips】如何在view中取得activity对象
- 认清楚服务器的真正身份--深入ARP工作原理
- 机器学习算法与Python实践之(二)支持向量机
- Java 编程的动态性,第 5 部分: 动态转换类--转载
- 李开复:职场人35岁以后,真诚比面子重要,均衡比魄力重要!
- JavaScript之Set与Map
- 区块链游戏为何只剩下“炒币”的价值?
- 金融风控--申请评分卡模型--特征工程(特征分箱,WOE编码) 标签: 金融特征分箱-WOE编码 2017-07-16 21:26 4086人阅读 评论(2) 收藏 举报 分类: 金融风
- 互联网金融2.0 这是最好的时代