<?php
namespace imcat;

// Output
class basOut
{
    static 
$options = array(
        
// 输出参数-jsonp
        
'jsonp_callback' => 'callback',
        
'jsonp_return' => 'callback',
        
// 输出参数-xml
        
'root_node' => 'root'// 根节点名
        
'root_attr' => ''// 根节点属性
        
'item_node' => 'item'//数字索引的子节点名
        
'item_key'  => 'id'// 数字索引子节点key转换的属性名
        
'encoding'  => 'utf-8'// 数据编码
    
);

    static 
$contentType ''// application/json, application/javascript, text/xml

    // 格式化输出
    
static function fmt($data$type='json')
    {
        
$type in_array($type,array('jsonp','xml')) ? $type 'json';
        
$method 'out'.ucfirst($type);
        
$re self::$method($data);
        return 
$re;
    }

    static function 
outJson($data)
    {
        try {
            
// 返回JSON数据格式到客户端 包含状态信息
            
$data comParse::jsonEncode($data);
            return 
$data;
        } catch (
Exception $e) {
            if (
$e->getPrevious()) {
                throw 
$e->getPrevious();
            }
            throw 
$e;
        }
    }

    static function 
outJsonp($data)
    {
        
$opt self::$options;
        try {
            
// 返回JSON数据格式到客户端
            
$callback basReq::val('callback',$opt['jsonp_callback']); 
            
$handler = !empty($callback) ? $callback $opt['jsonp_return'];
            
$data comParse::jsonEncode($data);
            
$data $handler '(' $data ');';
            return 
$data;
        } catch (
Exception $e) {
            if (
$e->getPrevious()) {
                throw 
$e->getPrevious();
            }
            throw 
$e;
        }
    }

    static function 
outXml($data$uopt=array())
    {
        
$opt self::$options;
        if(!empty(
$uopt)) $opt = array($opt$uopt);
        
$attr $opt['root_attr'];
        if(
is_array($attr)) {
            
$arr = array();
            foreach (
$attr as $key => $value) {
                
$arr[] = "{$key}=\"{$value}\"";
            }
            
$attr implode(' '$arr);
        }
        
$attr trim($attr);
        
$attr = empty($attr) ? '' {$attr}";
        
$xml  "<?xml version=\"1.0\" encoding=\"{$opt['encoding']}\"?>\n";
        
$xml .= "<{$opt['root_node']}{$attr}>\n";
        
$xml .= self::xmlRow($data$opt['item_node'], $opt['item_key']);
        
$xml .= "</{$opt['root_node']}>\n";
        return 
$xml;
    }

    
/**
     * 数据XML编码
     * @param mixed  $data 数据
     * @param string $item 数字索引时的节点名称
     * @param string $id   数字索引key转换为的属性名
     * @return string
     */
    
static function xmlRow($data$item$id)
    {
        
$xml $attr '';
        
$a1 = array("&""<"">");
        
$a2 = array("&amp;""&lt;""&gt;");
        foreach (
$data as $key => $val) {
            if (
is_numeric($key)) {
                
$id && $attr {$id}=\"{$key}\"";
                
$key         $item;
            }
            
$val = (is_array($val)||is_object($val)) ? self::xmlRow($val,$item,$id) : str_replace($a1,$a2,$val);
            
$xml .= "<{$key}{$attr}>$val</{$key}>\n";
        }
        return 
$xml;
    }
}

/*
$res = array(
    'errno' => 0,
    'state' => 'success',
    'msg' => 'msg',
    'data' => array(
        'uid' => 1234,
        'uname' => 'peace',
    ),
);
*/