对于将 xml 格式数据转换成 array 数据, 很多初学者应该都不知道, 那么今天就来为大家分析解答一下吧.
PHP 中的 $_POST 和 file_get_content('php://input')
$_POST
老规矩, 查看官方文档, 全世界都会骗你, 但是文档不会骗你.
$HTTP_POST_VARS [已弃用]$_POST -- $HTTP_POST_VARS [已弃用] - HTTP POST 变量当 HTTP POST 请求的 Content-Type 是 application/x-www-form-urlencoded 或 multipart/form-data 时, 会将变量以关联数组形式传入当前脚本.$HTTP_POST_VARS 包含相同的信息, 但它不是一个超全局变量. (注意 $HTTP_POST_VARS 和 $_POST 是不同的变量, PHP 处理它们的方式不同)
一看文档就知道全部信息了,$_POST 支持的 request 中的 header 中的 content-type 的类型只有 application/x-www-form-urlencoded 或 multipart/form-data .
当我们使用 guzzle 的时候它会根据你传入的 params 是否是数组进行判断, 如果不是数组会在 body 中. 但是如果是数组它就会按照 json 方式进行传递, content-type 会 application/json 的方式当然不会被 $_POST 进行处理. 所以, 这边是没有毛病的. 但是, 难道因为用了这个组件就不进行这个类型处理了吗? 显然不行.
- php://input
- php:// - 访问各个输入 / 输出流 (I/O streams)PHP 提供了一些杂项输入 / 输出(IO) 流, 允许访问 PHP 的输入输出流, 标准输入输出和错误描述符, 内存中, 磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器. php://input 是个可以访问请求的原始数据的只读流. POST 请求的情况下, 最好使用 php://input 来代替 $HTTP_RAW_POST_DATA, 因为它不依赖于特定的 php.ini 指令. 而且, 这样的情况下 $HTTP_RAW_POST_DATA 默认没有填充, 比激活 always_populate_raw_post_data 潜在需要更少的内存. enctype="multipart/form-data" 的时候 php://input 是无效的. Note: 在 PHP 5.6 之前 php://input 打开的数据流只能读取一次; 数据流不支持 seek 操作. 不过, 依赖于 SAPI 的实现, 请求体数据被保存的时候, 它可以打开另一个 php://input 数据流并重新读取. 通常情况下, 这种情况只是针对 POST 请求, 而不是其他请求方式, 比如 PUT 或者 PROPFIND.
这个东西说实话, 就是 $_POST 基于这个进行封装处理了一层. 它能够获取到最原始的数据, 不管你是什么 content-type, 它都能够获取到数据. 所以, 当我们的 post 的过来的数据是原始数据的时候, 比如说是 application/json 或者' application/x-json,text/xml, application/xml,application/x-xml 这些时候,$_POST 都是无法获取到数据的. 此刻, 我们就需要通过 php://input 进行获取原始数据了. 但是, 原始数据并不是我们想要的最终格式. 因此, 我们需要进行封装一层.
parseRequest
request 类其实是很好写的, 但是一般的类中对 post 方式传递参数还是老方式. 因此, 我改写了一般的类中获取 post 的参数, 对于所有 post 请求方式的方法, 针对不同的 content-type 进行数据获取和原始数据的解析, 弄成我们想要的最终数组.
核心代码:
public static function post($key = NULL, $default = NULL) { $data = [];if(in_array($_SERVER['CONTENT_TYPE'],self::$formats['json'])){ $data = file_get_contents('php://input'); $data = json_decode($data,true); } if(in_array($_SERVER['CONTENT_TYPE'],self::$formats['xml'])){ $data = file_get_contents('php://input'); $data = DataParser::toArray($data); } if($key==null && !empty($data)){ return $data; }if(!empty($data)){ return isset($data[$key]) ? $data[$key] : $default; } return static::lookup($_POST, $key, $default); }
在类中我们会定义几个 conten-type 的 format 数组, 通过 $_SERVER['CONTENT_TYPE']来进行判断处理, 针对性的进行数据获取和转换.
protected static $formats = array( 'html' => array('text/html', 'application/xhtml+xml'), 'txt' => array('text/plain'),'js' => array('application/javascript', 'application/x-javascript', 'text/javascript'), 'CSS' => array('text/css'), 'json'=> array('application/json', 'application/x-json'), 'xml' => array('text/xml', 'application/xml', 'application/x-xml'),'rdf' => array('application/rdf+xml'), 'atom' => array('application/atom+xml'), 'rss' => array('application/rss+xml'), );
针对 xml 格式的数据, 同时封装了数据处理类
public static function toArray($xml) { if (!$xml) { return false; } // 检查 xml 是否合法 $xml_parser = xml_parser_create();if (!xml_parse($xml_parser, $xml, true)) { xml_parser_free($xml_parser); return false; } libxml_disable_entity_loader(true); $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $data; }
就是简单的将 xml 格式数据转换成 array 数据. 如果大家还存在疑问的话, 可以留言咨询. 本文由专业的郑州 app 开发公司燚轩科技整理发布, 原创不易, 如需转载请注明出处!
来源: http://www.bubuko.com/infodetail-2745975.html