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框架中的实现原理【精细剖析】...相关推荐

  1. curl请求模拟post发送json

    示例:curl -X POST --header "Content-Type:application/json" --data '{"name":"s ...

  2. JSON数据格式----- JavaScript与JSON、JavaScript的JSON对象、构建JSON格式数据

    JavaScript与JSON JSON是一种语法,用来序列化对象.数组等的.它只是基于JavaScript语法 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zWMc ...

  3. HTML地址栏传数据和json区别,前端利用formData格式进行数据上传,前端formData 传值 和 json传值的区别?...

    contentType 常见的格式 text/plain :纯文本格式 application/json: JSON数据格式 application/x-www-form-urlencoded 中默认 ...

  4. 后台怎么接收处理从url 客户端传来的json数据格式

    最近做项目用到了 一个新的客户端传参的方式,主要采用的是客户端以json数据格式的方式想后台传递数据,所以,后台接收的参数也是json格式的,刚开始不知道怎么做, 到最后才找到了解决的办法就是利用go ...

  5. Ajax---使用json数据格式输出数据

    将Ajax得到的数据使用json数据格式输出 1.项目清单 2.代码 2.1.Procince类代码 2.2.ProvinceDao类代码 2.3.QueryJsonServlet类代码 2.4.Te ...

  6. java 蓝牙读取数据格式,单片机与安卓手机通过蓝牙串口模块利用JSON数据格式通信实例...

    原标题:单片机与安卓手机通过蓝牙串口模块利用JSON数据格式通信实例 JSON 指的是 Java 对象表示法(Java Object Notation),JSON 是轻量级的文本数据交换格式,JSON ...

  7. 使用Qt通过Post发送Json格式数据

    一.简介 1.任务目标 使用Qt通过post发送Json格式数据,或者以表单形式发送数据到服务器 2.环境简介 系统:Windows 10 Qt版本:5.7 二.内容准备 1.关于Qt 1.使用Pos ...

  8. android 解析json数据格式

    前面我有用到android发送json数据:这里我想总结一下我用到的解析json数据格式的方式 json数据格式解析我自己分为两种: 一种是普通的,一种是带有数组形式的: 普通形式的: 服务器端返回的 ...

  9. ajax 中json格式数据格式,AJAX中的dataType(数据格式)-text、json

    因为经常使用数据格式,所以将它封装成类,J这样就不会用到时就写了,直接调用写好的类就可以了 (1)dataType数据格式为:TEXT格式的数据是字符串的数据,在"ajax对数据进行删除和查 ...

最新文章

  1. python网盘提取码怎么用_Python 一键获取百度网盘提取码
  2. FilterDispatcher is deprecated! Please use
  3. document引用图片的src属性能干嘛_如何实现图片懒加载
  4. 旅行报告:JavaOne 2013 –重归荣耀
  5. 这份NLP研究进展汇总请收好,GitHub连续3天最火的都是它
  6. 2015-ResNet讲解
  7. IT项目管理之系统规划
  8. conda 安装本地包_export包本地安装以及R包被CRAN移除后如何继续安装
  9. Zune支持哪些格式?
  10. Java多线程编程模式实战指南一:Active Object模式
  11. Docker 入门教程
  12. 提示fxp不是一个目标文件
  13. Base64 在线编码解码
  14. 6s信号时有有时无服务器,苹果iPhone6s信号弱或无服务解决方法
  15. 论文工具大全+软件简介
  16. 在Docker 上完成对Springboot+Mysql+Redis的前后端分离项目的部署(全流程,全截图)
  17. RecyclerView添加头部
  18. 深入浅出pytorch
  19. explaining and harnessing adversarial examples(FGSM)
  20. 普通高中计算机装备标准,福建省普通高中信息技术装备标准.doc

热门文章

  1. 数据分析系列:绘制折线图(matplotlib)
  2. 【android-tips】如何在view中取得activity对象
  3. 认清楚服务器的真正身份--深入ARP工作原理
  4. 机器学习算法与Python实践之(二)支持向量机
  5. Java 编程的动态性,第 5 部分: 动态转换类--转载
  6. 李开复:职场人35岁以后,真诚比面子重要,均衡比魄力重要!
  7. JavaScript之Set与Map
  8. 区块链游戏为何只剩下“炒币”的价值?
  9. 金融风控--申请评分卡模型--特征工程(特征分箱,WOE编码) 标签: 金融特征分箱-WOE编码 2017-07-16 21:26 4086人阅读 评论(2) 收藏 举报 分类: 金融风
  10. 互联网金融2.0 这是最好的时代