diff --git a/helper.php b/helper.php index 0c8e590b..e57e6555 100644 --- a/helper.php +++ b/helper.php @@ -387,7 +387,7 @@ function view($template = '', $vars = [], $code = 200) * 获取\think\response\Json对象实例 * @param mixed $data 返回的数据 * @param integer $code 状态码 - * @param array $options 参数状 + * @param array $options 参数 * @return \think\response\Json */ function json($data = [], $code = 200, $options = []) @@ -396,6 +396,19 @@ function json($data = [], $code = 200, $options = []) return $response->data($data)->code($code); } +/** + * 获取\think\response\Xml对象实例 + * @param mixed $data 返回的数据 + * @param integer $code 状态码 + * @param array $options 参数 + * @return \think\response\Xml + */ +function xml($data = [], $code = 200, $options = []) +{ + $response = new \think\response\Xml($options); + return $response->data($data)->code($code); +} + /** * 获取\think\response\Redirect对象实例 * @param mixed $url 重定向地址 支持Url::build方法的地址 diff --git a/library/think/App.php b/library/think/App.php index 35184fb5..84d69872 100644 --- a/library/think/App.php +++ b/library/think/App.php @@ -13,8 +13,6 @@ namespace think; use think\exception\HttpResponseException; use think\Response; -use think\response\Json; -use think\response\Jsonp; /** * App 应用管理 @@ -119,20 +117,12 @@ class App // 监听app_end APP_HOOK && Hook::listen('app_end', $data); $type = IS_AJAX ? Config::get('default_ajax_return') : Config::get('default_return_type'); - switch ($type) { - case 'json': - $response = new Json($data); - break; - case 'jsonp': - $response = new Jsonp($data); - break; - case 'html': - default: - $response = new Response($data, $type); - break; + if (in_array(strtolower($type), ['json', 'jsonp', 'xml'])) { + $class = '\\think\\response\\' . ucfirst($type); + } else { + $class = '\\think\\Response'; } - // 自动响应输出 - return $response->send(); + return (new $class($data, $type))->send(); } } } diff --git a/library/think/response/Xml.php b/library/think/response/Xml.php new file mode 100644 index 00000000..3a2c59bd --- /dev/null +++ b/library/think/response/Xml.php @@ -0,0 +1,95 @@ + +// +---------------------------------------------------------------------- + +namespace think\response; + +use think\Response; + +class Xml extends Response +{ + // 输出参数 + protected $options = [ + // 根节点名 + 'root_node' => 'think', + // 根节点属性 + 'root_attr' => '', + //数字索引的子节点名 + 'item_node' => 'item', + // 数字索引子节点key转换的属性名 + 'item_key' => 'id', + // 数据编码 + 'encoding' => 'utf-8', + ]; + + protected $contentType = 'text/xml'; + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + */ + protected function output($data) + { + // XML数据转换 + return $this->xmlEncode($data, $this->options['root_node'], $this->options['item_node'], $this->options['root_attr'], $this->options['item_key'], $this->options['encoding']); + } + + /** + * XML编码 + * @param mixed $data 数据 + * @param string $root 根节点名 + * @param string $item 数字索引的子节点名 + * @param string $attr 根节点属性 + * @param string $id 数字索引子节点key转换的属性名 + * @param string $encoding 数据编码 + * @return string + */ + protected function xmlEncode($data, $root, $item, $attr, $id, $encoding) + { + if (is_array($attr)) { + $array = []; + foreach ($attr as $key => $value) { + $array[] = "{$key}=\"{$value}\""; + } + $attr = implode(' ', $array); + } + $attr = trim($attr); + $attr = empty($attr) ? '' : " {$attr}"; + $xml = ""; + $xml .= "<{$root}{$attr}>"; + $xml .= $this->dataToXml($data, $item, $id); + $xml .= ""; + return $xml; + } + + /** + * 数据XML编码 + * @param mixed $data 数据 + * @param string $item 数字索引时的节点名称 + * @param string $id 数字索引key转换为的属性名 + * @return string + */ + protected function dataToXml($data, $item, $id) + { + $xml = $attr = ''; + foreach ($data as $key => $val) { + if (is_numeric($key)) { + $id && $attr = " {$id}=\"{$key}\""; + $key = $item; + } + $xml .= "<{$key}{$attr}>"; + $xml .= (is_array($val) || is_object($val)) ? $this->dataToXml($val, $item, $id) : $val; + $xml .= ""; + } + return $xml; + } +}