「PHP开发APP接口实战005」基础示例接口的实现一

前一章,我们对接口参数基本定义做了一个简要说明。里面提到了几个示例接口,接下来,我们就来讲解这个几点个示例接口的具体实现。
「PHP开发APP接口实战004」基础响应参数说明

前言

由于我们的接口返回数据类型包含 JSON 和 H5,所以我们选用的是 Phalcon 框架中MVC模式。

知识点及参考资料

Output类的实现

Output 类主要用于将结果转换成对应接口数据,并输出到页面上。
Output 类采用了单例设计模式。什么是单例模式,这里我就不展开讲了,有兴趣的同学可以点开前面的参考资料,进行进一步的了解。

  1. 我们在 /app/library 目录下创建 Output.php 类文件。插入下面代码:
<?php

class Output
{

    // 存放实例
    public static $instance;

    /**
     * 私有化构造方法
     */
    private function __construct()
    {
    }

    /**
     * 公有化获取实例方法
     * @return Output 返回当前实例
     */
    public static function instance()
    {
        if (!self::$instance) self::$instance = new self();
        return self::$instance;
    }
}

这就是用PHP单例设计模式定义类最基本的代码。 调用方法 Output::instance()。这里只是返回了Output的实例对象。

  1. 定义私有变量$response,用于接收页面响应对象。再给构造方法 __construct 和获取实例方法 instance 分别添加参数$response,并将参数赋值给私有变量$response。调用方法变成 Output::instance($response)
class Output
{

    // 存放实例
    public static $instance;

    // 页面响应对象
    private $response = null;

    /**
     * 私有化构造方法
     * @param \Phalcon\Http\Response|null $response 传入控制器页面响应对象
     */
    private function __construct(Phalcon\Http\Response $response)
    {
        $this->response = $response;
    }

    /**
     * 公有化获取实例方法
     * @param \Phalcon\Http\Response $response 传入控制器页面响应对象
     * @return Output 返回当前实例
     */
    public static function instance(Phalcon\Http\Response $response)
    {
        if (!self::$instance) self::$instance = new self($response);
        return self::$instance;
    }
}
  1. 定义私有变量$view,用于接收页面视图对象。 再添加一个方法 setView 用于设置视图对象。
    // 页面视图对象(用于返回H5页面)
    private $view = null;

    /**
     * 设置页面视图对象
     * @param \Phalcon\Mvc\View $view 传入控制器页面视图对象
     * @return $this 返回实例化对象
     */
    public function setView(Phalcon\Mvc\View $view)
    {
        $this->view = $view;
        return $this;
    }

视图对象只有在返回H5页面的接口才会用到,所以非H5接口,不需要调用 setView 方法。调用方法 Output::instance($response)->setView($view)

  1. 添加以下代码,实现输出JSON数据。
    /**
     * 重写JSON格式的字符串进行编码
     * @param $data
     * @param null $options
     * @return string
     */
    private function JsonEncode($data, $options = null)
    {
        return json_encode($this->DataAsString($data), $options);
    }

    /**
     * 数据值强转字符串
     * @param $data
     * @return mixed
     */
    private function DataAsString($data)
    {
        $data = is_object($data) ? (array)$data : $data;
        if (is_array($data)) {
            foreach ($data as $key => $value) {
                if (is_array($value) || is_object($value)) {
                    $data[$key] = $this->DataAsString($value);
                } else {
                    $data[$key] = (string)$value;
                }
            }
        }
        return $data;
    }

    /**
     * 输出JSON数据
     * @param $body
     */
    public function json($body)
    {
        // 设置响应内容类型 Content-Type 为 JSON类型,UTF-8编码。
        $this->response->setHeader('Content-Type', 'text/json;charset=utf-8;');
        $options = NULL;
        // 读取是否开启调试配置
        // 如果开启调试,输出JSON数据中的中文不进行 unicode 编码操作
        if (Config::instance()->get('debug')) {
            $options = $options | JSON_UNESCAPED_UNICODE; // 中文不进行 unicode 编码
        }
        // 输出JSON数据,并退出当前脚本。
        die(self::JsonEncode($body, $options));
    }

上述代码主要实现:

  • 设置响应内容类型 Content-Type 为 JSON类型,UTF-8编码。
  • 读取是否开启调试配置,如果开启调试,返回输出JSON数据中的中文不进行 unicode 编码操作。如:经过编码的数据 {"status":"1","value":"\u672a\u7f16\u7801\u4e2d\u6587"},未编码的数据:{"status":"1","value":"未编码中文"}。 在开发和调试代码时,使用未编码的数据更为直观,方便审阅输出结果。为了更好的传输中文,在正式运行环境下,需要对中文进行 unicode 编码操作。
  • 将输出JSON数据中值强制转换为字符串,如: {"status":1} 换转成{"status":"1"}。 这样做的目的是为了,让在开发APP,调用接口进行JSON数据解析时,更为方便的进行数据类型转换。
  1. 根据状态可分为成功和失败两种接口。所以,我们添加 success 和 fail 两个方法,分别来实现两种状态接口的输出。
    /**
     * 输出成功数据
     * @param $data
     */
    public function success($data = '')
    {
        $body = [
            'status' => '1',
        ];

        if (is_object($data)) {  // 对像数据
            $body['item'] = $data;
        } elseif (is_array($data)) { // 列表数据
            $body['list'] = $data;
        } else {
            $body['value'] = $data;  // 消息(字符串)数据
        }
        $this->json($body);
    }

成功接口{"status":"1"},又按数据类型分为:对像数据 ( item ) 、列表数据 ( list )、消息(字符串)数据 ( value )。
调用方法:Output::instance($response)->success('Hello World.')

    /**
     * 输出失败数据
     * @param $message   错误消息
     * @param int $code 错误代码: 300 验证错误, 500 系统错误
     * @param string $track 错误跟踪信息: 错误代码文件路径,错误所在行等。
     */
    public function fail($message, $code = 300, $track = null)
    {
        $body = [
            'status' => '0',
            'error_code' => $code,
            'error_message' => $message,
        ];

        if ($track && Config::instance()->get('debug')) {
            $body['track'] = $track;
        }
        $this->json($body);
    }

失败接口{"status":"0"},有固定的必填参数:error_code 错误代码、 error_message 错误消息。如果开启了调试并接收到错误跟踪信息,还会输出 track 错误跟踪信息参数。
调用方法:Output::instance($response)->fail('登录失败')

  1. 还有一个特殊的输出方法, h5。用于输出H5页面数据。
    /**
     * 输出H5页面数据
     * @param null $data
     */
    public function h5($data = null)
    {
        // 设置响应内容类型 Content-Type 为 HTML类型,UTF-8编码。
        $this->response->setHeader('Content-Type', 'text/html;charset=utf-8;');

        // 将数据注册到 View, 便于在模板中读取
        $this->view->data = $data;
    }

上述代码主要实现:

  • 设置响应内容类型 Content-Type 为 HTML类型,UTF-8编码。
  • 将数据注册到 View, 便于在模板中读取

调用此方法之前必须先调用 setView 方法, 如:Output::instance($response)->setView($view)->h5('测试')

Output.php 完整代码

<?php

/**
 * 输出数据
 */
class Output
{

    // 存放实例
    public static $instance;

    // 页面响应对象
    private $response = null;

    // 页面视图对象(用于返回H5页面)
    private $view = null;

    /**
     * 私有化构造方法
     * @param \Phalcon\Http\Response|null $response 传入控制器页面响应对象
     */
    private function __construct(Phalcon\Http\Response $response)
    {
        $this->response = $response;
    }

    /**
     * 公有化获取实例方法
     * @param \Phalcon\Http\Response $response 传入控制器页面响应对象
     * @return Output 返回当前实例
     */
    public static function instance(Phalcon\Http\Response $response)
    {
        if (!self::$instance) self::$instance = new self($response);
        return self::$instance;
    }

    /**
     * 设置页面视图对象
     * @param \Phalcon\Mvc\View $view 传入控制器页面视图对象
     * @return $this
     */
    public function setView(Phalcon\Mvc\View $view)
    {
        $this->view = $view;
        return $this;
    }

    /**
     * 重写JSON格式的字符串进行编码
     * @param $data
     * @param null $options
     * @return string
     */
    private function JsonEncode($data, $options = null)
    {
        return json_encode($this->DataAsString($data), $options);
    }

    /**
     * 数据值强转字符串
     * @param $data
     * @return mixed
     */
    private function DataAsString($data)
    {
        $data = is_object($data) ? (array)$data : $data;
        if (is_array($data)) {
            foreach ($data as $key => $value) {
                if (is_array($value) || is_object($value)) {
                    $data[$key] = $this->DataAsString($value);
                } else {
                    $data[$key] = (string)$value;
                }
            }
        }
        return $data;
    }

    /**
     * 输出JSON数据
     * @param $body
     */
    public function json($body)
    {
        // 设置响应内容类型 Content-Type 为 JSON类型,UTF-8编码。
        $this->response->setHeader('Content-Type', 'text/json;charset=utf-8;');
        $options = NULL;
        // 读取是否开启调试配置
        // 如果开启调试,输出JSON数据中的中文不进行 unicode 编码操作
        if (Config::instance()->get('debug')) {
            $options = $options | JSON_UNESCAPED_UNICODE; // 中文不进行 unicode 编码
        }
        // 输出JSON数据,并退出当前脚本。
        die(self::JsonEncode($body, $options));
    }

    /**
     * 输出成功数据
     * @param $data
     */
    public function success($data = '')
    {
        $body = [
            'status' => '1',
        ];

        if (is_object($data)) {  // 对像数据
            $body['item'] = $data;
        } elseif (is_array($data)) { // 列表数据
            $body['list'] = $data;
        } else {
            $body['value'] = $data;  // 消息(字符串)数据
        }
        $this->json($body);
    }

    /**
     * 输出失败数据
     * @param $message   错误消息
     * @param int $code 错误代码: 300 验证错误, 500 系统错误
     * @param string $track 错误跟踪信息: 错误代码文件路径,错误所在行等。
     */
    public function fail($message, $code = 300, $track = null)
    {
        $body = [
            'status' => '0',
            'error_code' => $code,
            'error_message' => $message,
        ];

        if ($track && Config::instance()->get('debug')) {
            $body['track'] = $track;
        }
        $this->json($body);
    }

    /**
     * 输出H5页面数据
     * @param null $data
     */
    public function h5($data = null)
    {
        // 设置响应内容类型 Content-Type 为 HTML类型,UTF-8编码。
        $this->response->setHeader('Content-Type', 'text/html;charset=utf-8;');

        // 将数据注册到 View, 便于在模板中读取
        $this->view->data = $data;
    }
}

示例代码下载
链接:https://pan.baidu.com/s/1ht4xA7a 密码:zjfj

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容