用PHP编写一个APP的API

第一部分,通信接口的实现

标签(空格分隔): PHP 手机后台 api 通信接口 Andy


PHP是世界上最强大的语言。

PHP开发手机API时,一般返回XML或JSON数据类型的数据,除了要返回从源数据(程序本身需要的数据)外还应附上状态码,以下是一段封装后的数据,它使用JSON格式展现:

{
    code: 200,
    message: "Success",
    data: [
        {
            username: "安明哲",
            password: "123456",
            level: "1",
            gold: "0",
            id: "6",
            create_time: "2015-09-26 08:25:31",
            is_active: "1",
            is_admin: "0"
        },
        {
            username: "张三",
            password: "12345",
            level: "1",
            gold: "0",
            id: "8",
            create_time: "0000-00-00 00:00:00",
            is_active: "1",
            is_admin: "0"
        }
    ]
}

以下是XML格式数据的实例:

<root>
    <code>200</code>
    <message>Success</message>
    <data>
        <item id="0">
        <username>安明哲</username>
        <password>123456</password>
        <level>1</level>
        <gold>0</gold>
        <id>6</id>
        <create_time>2015-09-26 08:25:31</create_time>
        <is_active>1</is_active>
        <is_admin>0</is_admin>
        </item>
        <item id="1">
        <username>张三</username>
        <password>12345</password>
        <level>1</level>
        <gold>0</gold>
        <id>8</id>
        <create_time>0000-00-00 00:00:00</create_time>
        <is_active>1</is_active>
        <is_admin>0</is_admin>
        </item>
    </data>
</root>

此外,为了方便手机端开发人员的调试,还可直接返回带数据类型的数据:

array(3) {
  ["code"]=>
  int(200)
  ["message"]=>
  string(7) "Success"
  ["data"]=>
  array(2) {
    [0]=>
    array(8) {
      ["username"]=>
      string(9) "安明哲"
      ["password"]=>
      string(6) "123456"
      ["level"]=>
      string(1) "1"
      ["gold"]=>
      string(1) "0"
      ["id"]=>
      string(1) "6"
      ["create_time"]=>
      string(19) "2015-09-26 08:25:31"
      ["is_active"]=>
      string(1) "1"
      ["is_admin"]=>
      string(1) "0"
    }
    [1]=>
    array(8) {
      ["username"]=>
      string(6) "张三"
      ["password"]=>
      string(5) "12345"
      ["level"]=>
      string(1) "1"
      ["gold"]=>
      string(1) "0"
      ["id"]=>
      string(1) "8"
      ["create_time"]=>
      string(19) "0000-00-00 00:00:00"
      ["is_active"]=>
      string(1) "1"
      ["is_admin"]=>
      string(1) "0"
    }
  }
}

如何实现

当手机客户端通过API获取数据时,PHP脚本会Response一个数组,并对这个数组进行encode,他们分别是json,xmlarray;该数组,定义如下:

$result = [
    "code" => 200,
    "message" => "数据返回成功",
    "data" => ["key"=>"value", "key"=>"value"]
]

其中,code代表状态码,message代表状态信息,data是程序逻辑中需要的数据。

如何去设计

当手机端调用API,程序业务逻辑处理完成之后,需要返回数据,此时需要对通信数据进行封装,封装的三种类型由可由REQUEST里的format参数指定,当formart=json时执行response_json方法,同理,还有response_xmlresponse_array方法;

为了方便调用,编写一个Response类来封装数据并完成response工作:

/*本段代码没有经过实际环境测试,也没有严谨的参数检查*/
class Response{
    public static function response_api($code, $message='', $data=array()){
        //根据formart返回适当的数据
        $type = isset($_REQUEST['format'])?$_REQUEST['format']:'';
        switch ($type) {
            case 'json':
                self::response_json($code, $message, $data);
                break;
            case 'xml':
                self::response_xml($code, $message, $data);
                break;
            case 'array':
                echo var_dump(self::grant_array($code, $message, $data));
                break;
            default:
                self::response_json($code, $message, $data);
                
                break;
        }
    }
    
    public static function response_json($code, $message='', $data=array()){
        //返回JSON数据
        $result = self::gramt_array($code,$message,$data);
        echo json_encode($result);
        exit();
    }
    
    public static function response_xml($code, $message='', $data=array()){
        //返回XML数据
        $result = self::gramt_array($code,$message,$data);
        $xml = "<?xml version='1.0' encoding='UTF-8'?>";
        $xml .= "<root>";
        $xml .= self::xml_encode($result);
        $xml .= "</root>"
        echo $xml;
        exit();
    }
    
    private function xml_encode($arr=array()){
        //对于XML,需要自己实现一个XML的encode方法
        $xml = $attr = '';
        foreach($arr as $key=>$value){
            if(is_numberic($key)){
                $key = 'item';
                $attr = " id='{$key}'";
            }
            $xml .= "<{$key}{$attr}>";
            $xml .= (is_array($value))?self::xml_encode($value):$value;
            $xml .= "</{$key}>";
        }
        return $xml;
    }
    
    private function grant_array($code, $message='', $data=array()){
        //在所有操作之前,需要生成符合API规范的数组
        $result = {
            "code" => $code,
            "message" => $message,
            "data" => $data
        };
        return $result;
    }
    
}

Response类实现了通信接口的数据封装,可根据response内指定的format灵活的写入不同格式的数据到Response。
付:完整代码及调用实例:

<?php 
class Response{ 
    /*
    * 封通信接口数据
    * @param integer $code 状态码
    * @param string $message 状态信息
    * @param array $data 数据
    * return string 
    */
    public static function api_response($code, $message='',
            $data=array()){
        $type = isset($_REQUEST['format'])?$_REQUEST['format']:'';
        switch ($type) {
            case 'json':
                self::response_json($code, $message, $data);
                break;
            case 'xml':
                self::response_xml($code, $message, $data);
                break;
            case 'array':
                echo var_dump(self::grant_array($code, $message, $data));
                break;
            default:
                self::response_json($code, $message, $data);
                break;
        }
    }

    /*
    * 封装数为为json数据类型
    * @param integer $code 状态码
    * @param string $message 状态信息
    * @param array $data 数据
    * return string 
    */
    public static function json_response($code, 
        $message='', $data=array()){
        $result = self::grant_array($code, $message, $data);
        echo json_encode($result);
        exit;
    }

    /*
    * 封装数为为xml数据类型
    * @param integer $code 状态码
    * @param string $message 状态信息
    * @param array $data 数据
    * return string 
    */
    public static function xml_response($code, 
        $message='', $data=array()){
        
        $result = self::grant_array($code, $message, $data);
        
        header("Content-Type:text/xml");
        $xml = "<?xml version='1.0' encoding='UTF-8'?>\n";
        $xml .= "<root>\n";
        $xml .= self::xml_encode($result);
        $xml .= "</root>";
        echo $xml;
        exit();
    }

    /*
    * 将数组转换为XML格式
    * @param array $array 数组
    * return string 
    */
    private function xml_encode($array=array()){
        $xml = $attr = "";

        if(!empty($array)){
            foreach ($array as $key => $value) {
                if(is_numeric($key)){
                    $attr = " id='{$key}'";
                    $key = "item";
                }
                $xml .= "<{$key}{$attr}>" ;
                $xml .= is_array($value) ? self::xml_encode($value) : $value;
                $xml .="</{$key}>\n";
            }
        }
        return $xml;
    }

    /*
    * 按照接口格式生成原数据数组
    * @param integer $code 状态码
    * @param string $message 状态信息
    * @param array $data 数据
    * return array 
    */
    private function grant_array($code, $message='', $data=array()){
        if(!is_numeric($code)){
            return '';
        }

        $result = array(
            'code' => $code,
            'message' => $message,
            'data' => $data
        );

        return $result;
    }
}

调用实例:

<?php 

require_once "./DataBaseUtil.class.php";
require_once "./Response.class.php";
    
$connect = DataBaseUtil::getInstance()->connect();


/*
* 首页接口 
* http://domain/hotgirl/callback.php?format=xml/json
*/
$page = isset($_REQUEST['page'])?$_REQUEST['page']:1;
$page_number = isset($_REQUEST['page_number'])?$_REQUEST['page_number']:2;
$lim_start = ($page-1) * $page_number;
$sql = "SELECT * FROM user WHERE is_active=1 LIMIT ".$lim_start.",".$page_number;
$result = mysql_query($sql, $connect);
if($result && mysql_num_rows($result)>0) {
    while ($row = mysql_fetch_assoc($result)) {
        $rows[] = $row;
    }
}
if(!empty($rows)){
    return Response::api_response(200, 'Success', $rows);
}
else{
    return Response::api_response(403, 'No result from database');
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,808评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,066评论 4 62
  • 有趣文叔阅读 345评论 5 4
  • 随着塞尔比一杆解球失误白球落袋,上海大师赛也就此落下帷幕,我们终于等到了最好的结局,丁俊晖梦圆上海滩,霸气夺冠!这...
    小二郎i阅读 330评论 0 0