用PHP编写一个APP的API

作者: 代号027 | 来源:发表于2015-10-06 11:13 被阅读20022次

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

标签(空格分隔): 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');
}

相关文章

网友评论

  • 刘泽旻:用不了啊大哥
  • daac383a9088:返回结果数据中,有没有修正数据的插件?类似https://github.com/goosman-lei/php-ckcr这样的完整版?
  • daac383a9088:能不能将code的定义说明下,具体多少代表多少?
    阳光男孩刚哥哥:@金一山 这个一般可以参考 http 状态码来设置,当然,可以自定义自己的 code,更详细的标注每一种错误类型
    02c227bf8942:@金一山 这个是自定义的 兄弟
  • linfree:感觉如果是科普的话。讲得有点复杂了。。
    如果是讲实际应用的话,又有些简单了。
    标题和我之前写的一篇有点类似,所以进来了。。😄😄😄
    787e79ddbd52: @linfree 能否把你的给大家看看
  • WordPress陌陌:方法名都写错了。。好好检查下吧
    8ff2b66e3237:@WordPress陌陌 什么是我还也为,是 以为吧,好好学好母语先吧
    WordPress陌陌:@一点简单 我知道啊,太不严谨,写反了:sweat:我还也为你的这种严谨是参数检查呢。没事了。。
    代号027:@WordPress陌陌 很遗憾,因为自己的不严谨给你造成了困扰。不过请留意,/*本段代码没有经过实际环境测试,也没有严谨的参数检查*/ ,这意味着代码并没有经过编译或者解释
  • 卖狗的苦瓜:正在找的文章
    卖狗的苦瓜: @一点简单 谢谢啦,很有帮助呢
    代号027:@卖狗的苦瓜 很高兴能够帮到你
  • 779b68e64744:如果整体写一个app的后台api应该如何写呢, 能否提供一些建议或例子了, 谢谢博主了 :smile:
  • 3bcc49f17179:哈哈,最好的,没有之一。
    另外,请教一个问题: 请问如何保证apie的安全,使其不会被非法的调用 ,谢谢。
  • 胡子长:坐看楼主的崛(mie)起(wang)~
    代号027:@胡子长 :sweat:
  • 5d8e2a600f79:你涉嫌违反广告法,使用了“最”😂
    代号027:@Captain_曹 :smiley: :smiley: :smiley:
  • codeGlider:建议作者加上“之一”,否则就有火药味了,出啥人身意外我不管~ :joy:
    代号027:@codeGlider python也是世界上最好的语言!
    codeGlider:@一点简单 好吧!swift是世界上最好的语言! :stuck_out_tongue_winking_eye:
    代号027:@codeGlider :stuck_out_tongue_winking_eye: 哈哈 好久不见! 对于无聊到非要特别在意这句话的人,我只说一句,这是夸张修辞,不是陈述句!
  • 31358cf6f976:就是一个比较通用简单的接口啊,又不是只有php可以写,这种接口web也经常用。为什么说php是最好的语音,求解释
    代号027:@杭州Tim 这是一个夸张的修辞而已 不是陈述句
  • 关山楼不二:XXX是最好的语言――一个长期存在于程序员之间的老梗。看到第一句我也就知道作者绝对是个会玩儿的小伙儿……
    代号027:@寂灭金蝉 :joy: 什么叫会玩的小伙啊?
  • e9a44a336dfe:我特别反感 拿任何语言来挑衅,容易引发争论,而偏离文章的本意。
    enomine:@煜_ 看作者明显是开玩笑咯
    代号027:@煜_ 说了 仅仅是一个玩笑而已 不必care 这个东西本身没有意义
  • 陌路千里:马克一下,
  • 775454c902e9:第一句话就带着强烈的挑衅的味道!
    42f0e2119b78:@strawluffy php是最好的语言!
    775454c902e9: @一点简单 哈哈
    代号027:@strawluffy 我用过好多语言,这句话仅仅是娱乐一下,不必care
  • 032b04ff2880:不明觉厉
    032b04ff2880:@一点简单 我看着都眼晕
    代号027:@032b04ff2880 也不是很难的东西啦!

本文标题:用PHP编写一个APP的API

本文链接:https://www.haomeiwen.com/subject/iqagcttx.html