PHP 使用 file_get_contents 接收 POST 的資料
一般接收 POST 资料都是使用 $_POST 这个变量,
但 $_POST 只能取得 Content-type 為 application/x-www-form-urlencoded 或 multipart/form-data 的資料。當 Content-type 為 text/xml 等其他類型的資料,$_POST便無法取得。
若有接收其他類型 Content-type 的需求,可以使用 php://input,
php://input 可以讀取 request body 的資料,所以可以取得 HTTP POST 的資料,
但有一個限制,就是當 Content-type 為 multipart/form-data ,php://input 會取得空值,無法使用。
下面範例 php://input 搭配 file_get_contents 使用,和 $_POST 比較在 Content-type 分別為 multipart/form-data、application/x-www-form-urlencoded、text/xml 時,兩者接收資料的情況
接收資料的程式:
後面範例用來 request 的網址:http://127.0.0.1/test/test.php
123 | $postdata = file_get_contents ( "php://input" , "r" ); var_dump( $postdata ); // php://input var_dump( $_POST ); |
範例 1:(multipart/form-data)
使用 curl 模擬 HTTP POST,Content-type 為 multipart/form-data
(CURLOPT_POSTFIELDS 資料為陣列時,會以 multipart/form-data 方式傳送)
12345678 | $ch = curl_init(); $data = array ( "aa" => "123" , "bb" => "456" ); curl_setopt( $ch , CURLOPT_URL, "http://127.0.0.1/test/test.php" ); curl_setopt( $ch , CURLOPT_POST, 1); curl_setopt( $ch , CURLOPT_POSTFIELDS, $data ); curl_setopt( $ch , CURLOPT_HEADER,0); curl_exec( $ch ); curl_close( $ch ); |
$postdata:string(0) ""
$_POST (OK):array(2) { ["aa"]=> string(3) "123" ["bb"]=> string(3) "456" }
範例 2:(application/x-www-form-urlencoded)
使用 curl 模擬 HTTP POST,Content-type 為 application/x-www-form-urlencoded
123456789 | $ch = curl_init(); $data = "aa=123&bb=456" ; curl_setopt( $ch , CURLOPT_URL, "http://127.0.0.1/test/test.php" ); curl_setopt( $ch , CURLOPT_HTTPHEADER, array ( "Content-type: application/x-www-form-urlencoded" )); curl_setopt( $ch , CURLOPT_POST, 1); curl_setopt( $ch , CURLOPT_POSTFIELDS, $data ); curl_setopt( $ch , CURLOPT_HEADER,0); curl_exec( $ch ); curl_close( $ch ); |
$postdata (OK):string(13) "aa=123&bb=456"
$_POST (OK):array(2) { ["aa"]=> string(3) "123" ["bb"]=> string(3) "456" }
範例 3:(text/xml)
使用 curl 模擬 HTTP POST,Content-type 為 text/xml
123456789 | $ch = curl_init(); $data = "<?xml version="1.0" encoding="utf-8"?><root><aa>123</aa><bb>456</bb></root>" ; curl_setopt( $ch , CURLOPT_URL, "http://127.0.0.1/test/test.php" ); curl_setopt( $ch , CURLOPT_HTTPHEADER, array ( "Content-type: text/xml;charset="utf-8"" )); curl_setopt( $ch , CURLOPT_POST, 1); curl_setopt( $ch , CURLOPT_POSTFIELDS, $data ); curl_setopt( $ch , CURLOPT_HEADER,0); curl_exec( $ch ); curl_close( $ch ); |
$postdata (OK):string(36) "<?xml version="1.0" encoding="utf-8"?><root><aa>123</aa><bb>456</bb></root>"
$_POST:array(0) {}
結論:
所以如果有一 PHP 程式,用來接收其它地方 POST 過來的資料,例如是 XML 的資料,應該就可以利用 file_get_contents("php://input","r") 來取得 POST 過來的內容。
PHP将XML转换成数组
做接口开发的时候经常会碰到别人提交给你的是xml格式的数据,常见的微信接口、支付宝接口等,他们的接口如发送消息通信都是xml格式的,那么我们先想办法拿到这个xml数据,然后再将其转化成数组。
假设我们获取到一个这样的XML:
<root>
<user>月光光abcd</user>
<pvs>13002</pvs>
<ips>
<baidu_ip>1200</baidu_ip>
<google_ip>1829</google_ip>
</ips>
<date>2016-06-01</date>
</root>
通过simplexml_load_string()解析读取xml数据,然后先转成json格式,再转换成数组。function xmlToArray($xml){
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$xmlstring = simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA);
$val = json_decode(json_encode($xmlstring),true);
return $val;
}
也可以
调用xmlToArray()可得到以下结果:
得到数组后,我们就可以对数据进行各种处理了。
语法
PHP的语法simplexml_load_string()函数具有以下语法。
simplexml_load_string(data,classname,options,ns,is_prefix);
参数
参数 | 是必须的 | 描述 |
---|---|---|
数据 | 需要。 | 一个格式正确的XML字符串 |
班级名称 | 可选的。 | 新对象的类 |
选项 | 可选的。 | 额外的Libxml参数。通过指定选项和1或0(TRUE或FALSE,例如LIBXML_NOBLANKS(1))来设置 |
ns | 可选的。 | 命名空间前缀或URI |
is_prefix | 可选的。 | 如果ns是前缀,则为TRUE。如果ns是URI,则为FALSE。默认值为FALSE |
选项的可能值:
- LIBXML_COMPACT - 激活节点分配优化(可加速应用程序)
- LIBXML_DTDATTR - 设置默认DTD属性
- LIBXML_DTDLOAD - 加载外部子集
- LIBXML_DTDVALID - 使用DTD进行验证
- LIBXML_NOBLANKS - 删除空白节点
- LIBXML_NOCDATA - 将CDATA合并为文本节点
- LIBXML_NOEMPTYTAG - 展开空标记(例如对<br> </ br>),仅在DOMDocument-> save()和DOMDocument-> saveXML()函数中可用
- LIBXML_NOENT - 替代实体
- LIBXML_NOERROR - 不显示错误报告
- LIBXML_NONET - 加载文档时禁用网络访问
- LIBXML_NOWARNING - 不显示警告报告
- LIBXML_NOXMLDECL - 保存文档时删除XML声明
- LIBXML_NSCLEAN - 删除多余的命名空间声明
- LIBXML_PARSEHUGE - 设置XML_PARSE_HUGE标志,放宽解析器的任何硬编码限制。这会影响极限,如文档的最大深度和文本节点大小的限制
- LIBXML_XINCLUDE - 实现XInclude替换
- LIBXML_ERR_ERROR - 获取可恢复的错误
- LIBXML_ERR_FATAL - 获取致命错误
- LIBXML_ERR_NONE - 获取无错误
- LIBXML_ERR_WARNING - 获取简单的警告
- LIBXML_VERSION - 获取libxml版本
- LIBXML_DOTTED_VERSION - 获取点分的libxml版本
返回值
成功时返回SimpleXMLElement对象。失败时为FALSE。
实例1
将格式良好的XML字符串转换为SimpleXMLElement对象,然后输出该对象的键和元素:
<?php
// http://www.manongjc.com/article/1630.html
$note=<<<XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<book>
<name>PHP</name>
<name>Java</name>
</book>
XML;
$xml=simplexml_load_string($note);
print_r($xml);
?>
上面的代码生成以下结果。
SimpleXMLElement Object
(
[name] => Array
(
[0] => PHP
[1] => Java
)
)
实例2
输出XML字符串中每个元素的数据:
<?php
// http://www.manongjc.com/article/1630.html
$note=<<<XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<book>
<name>PHP</name>
<name>Java</name>
</book>
XML;
$xml=simplexml_load_string($note);
echo $xml->to . "
";
echo $xml->from . "
";
echo $xml->heading . "
";
echo $xml->body;
?>
实例3
在XML字符串中为每个子节点输出元素的名称和数据:
<?php
// http://www.manongjc.com/article/1630.html
$note=<<<XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<book>
<name>PHP</name>
<name>Java</name>
</book>
XML;
$xml=simplexml_load_string($note);
echo $xml->getName() . "
";
foreach($xml->children() as $child){
echo $child->getName() . ": " . $child . "
";
}
?>
上面的代码生成以下结果。
book
name: PHP
name: Java
对象转成数组:
可以直接array()来转,但是有些情况不适用,数据结构会变。(未验证)
- 1.
- //PHP stdClass Object转array
- function object_array($array) {
- if(is_object($array)) {
- $array = (array)$array;
- }
- if(is_array($array)) {
- foreach($array as $key=>$value) {
- $array[$key] = object_array($value);
- }
- }
- return $array;
- }
- 2.
- $array = json_decode(json_encode(simplexml_load_string($xmlString)),TRUE);
- 3.
- function object2array_pre(&$object) {
- if (is_object($object)) {
- $arr = (array)($object);
- } else {
- $arr = &$object;
- }
- if (is_array($arr)) {
- foreach($arr as $varName => $varValue){
- $arr[$varName] = $this->object2array($varValue);
- }
- }
- return $arr;
- }
- 4.如果是10W的数据量的话,执行要进1s,结构再复杂些,可以达到3s,性能太差了,可以用以下替换:
- function object2array(&$object) {
- $object = json_decode( json_encode( $object),true);
- return $object;
- }
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇: php.ini配置的完全解读
- 下一篇:没有了