×
PhalApi 2.x 前言

PhalApi 2.x 快速开发

1.1 下载与安装1.2 运行Hello World1.3 如何请求接口服务1.4 接口响应与在线调试1.5 Api接口层1.6 Domain领域层和ADM模式1.7 Model数据层与数据库操作1.8 单元测试1.9 自动加载和PSR-41.10 接口文档

PhalApi 2.x 数据库

2.1 数据库链接2.2 数据库与NotORM2.3 数据库使用和查询2.4 数据库分库分表策略2.5 连接多个数据库2.6 打印和保存SQL语句2.7 定制你的Model基类

PhalApi 2.x 高级专题

3.1 PhalApi 2.x 接口参数3.2 PhalApi 2.x 配置3.3 PhalApi 2.x 日志3.4 PhalApi 2.x 缓存3.5 PhalApi 2.x 过滤器3.6 PhalApi 2.x COOKIE3.7 PhalApi 2.x 加密3.8 PhalApi 2.x 国际化3.9 PhalApi 2.x CURL请求3.10 PhalApi 2.x 工具和杂项3.11 PhalApi 2.x DI服务汇总

PhalApi 2.x 发现更多

4.1 PhalApi 2.x 扩展类库4.2 PhalApi 2.x SDK包的使用4.3 PhalApi 2.x 脚本命令

关于PhalApi 2.x

5.1 PhalApi 2.x 版本完美诠释5.2 PhalApi 2.x 升级指南5.3 PhalApi 2.x VS PhalApi 1.x

1.4 PhalApi 2.x 接口响应与在线调试


对于接口响应,PhalApi默认使用了HTTP+JSON。通过HTTP/HTTPS协议进行通讯,返回的结果则使用JSON格式进行传递。正常情况下,当接口服务正常响应时,如前面的Hello World接口,可能看到以下这样的响应头部信息和返回内容。

HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8

... ...

{"ret":200,"data":{"title":"Hello World!"},"msg":""}

而当接口项目抛出了未捕捉的异常,或者因PHP语法问题而出现Error时,则没有内容返回,并且得到一个500的响应状态码。类似如下:

HTTP/1.1 500 Internal Server Error

响应结构

回顾一下默认接口服务返回的内容。类似如下:

{
    "ret": 200,
    "data": {
        "title": "Hello World!",
        "content": "PHPer您好,欢迎使用PhalApi!",
        "version": "2.0.0",
        "time": 1499477583
    },
    "msg": ""
}

ret字段是返回状态码,200表示成功;data字段是项目提供的业务数据,由接口开发人员定义;msg是异常情况下的错误提示信息。下面分别说之。

业务数据 data

业务数据data为接口和客户端主要沟通对接的数据部分,可以为任何类型,由接口开发人员定义定义。但为了更好地扩展、向后兼容,建议都使用可扩展的集合形式,而非原生类型。也就是说,应该返回一个数组,而不应返回整型、布尔值、字符串这些基本类型。

业务数据主要是在Api层返回,即对应接口类的方法的返回结果。如下面的默认接口服务?s=Site.Index的实现代码。

<?php
namespace AppApi;

use PhalApiApi;

class Site extends Api {

    public function index() {
        return array(
            'title' => 'Hello World!',
            'content' => PhalApiT('Hi {name}, welcome to use PhalApi!', array('name' => $this->username)),
            'version' => PHALAPI_VERSION,
            'time' => $_SERVER['REQUEST_TIME'],
        );
    }

实际上,具体的业务数据需要一段复杂的处理,以满足特定业务场景下的需要。Api层需要与Domain层和Model层共同协作,完成指定的功能。这里暂且知道接口结果是在Api层返回,对应接口类成员方法返回的结果即可。

返回状态码 ret

返回状态码ret,用于表示接口响应的情况。参照自HTTP的状态码,ret主要分为四大类:正常响应、重定向、非法请求、服务器错误。

分类 ret范围 基数 说明
正常响应 200~299 200 表示接口服务正常响应
重定向 300~399 300 表示重定向,对应异常类RedirectException的异常码
非法请求 400~499 400 表示客户端请求非法,对应异常类BadRequestException的异常码
服务器错误 500~599 500 表示服务器内容错误,对应异常类InternalServerErrorException的异常码

正常响应时,通常返回ret = 200,并且同时返回data部分的业务数据,以便客户端能实现所需要的业务功能。

值得注意的是,抛出的异常应该继承于PhalApiException类,并且构造函数的第一个参数,是返回给客户端的错误提示信息,对应下面将讲到的msg字段。第二个参数是返回状态码的叠加值,也就是说最终的ret状态码都会在400的基数上加上这个叠加值,即:401 = 400 + 1。

例如,常见地,当签名失败时可以返回一个401错误,并提示“签名失败”。

<?php
namespace AppApi;

use PhalApiApi;
use PhalApiExceptionBadRequestException;

class Hello extends Api {

    public function fail() {
        throw new BadRequestException('签名失败', 1);
    }
}

会得到以下结果输出:

{
    "ret": 401,
    "data": [],
    "msg": "Bad Request: 签名失败"
}

错误提示信息 msg

当接口不是正常响应,即ret不在2XX系列内时,msg字段会返回相应的错误提示信息。即当有异常触发时,会自动将异常的错误信息作为错误信息msg返回。

扩展:如何使用其他返回格式?

除了使用JSON格式返回外,还可以使用其他格式返回结果。

例如在部分H5混合应用页面进行异步请求的情况下,客户端需要服务端返回JSONP格式的结果,则可以这样在DI配置文件./config/di.php中去掉以下注释。

// 支持JsonP的返回
if (!empty($_GET['callback'])) {
    $di->response = new PhalApiResponseJsonpResponse($_GET['callback']);
}

目前,PhalApi 2.x 已经支持的响应格式有:

响应格式 实现类
JSON格式 PhalApiResponseJsonResponse
JSONP格式 PhalApiResponseJsonResponse
XML格式 PhalApiResponseJsonResponse
控制台格式 PhalApiResponseJsonResponse

当需要返回一种当前PhalApi没提供的格式,需要返回其他格式时,可以:

在线调试

开启调试调试

开启调试模式很简单,主要有两种方式:

  • 单次请求开启调试:默认添加请求参数&__debug__=1
  • 全部请求开启调试:把配置文件./Config/sys.php文件中的配置改成'debug' => true,

调试信息有哪些?

正常响应的情况下,当开启调试模式后,会返回多一个debug字段,里面有相关的调试信息。如下所示:

{
    "ret": 200,
    "data": {
    },
    "msg": "",
    "debug": {
        "stack": [  // 自定义埋点信息
        ],
        "sqls": [  // 全部执行的SQL语句
        ]
    }
}

温馨提示:调试信息仅当在开启调试模式后,才会返回并显示。

在发生未能捕捉的异常时,并且开启调试模式后,会将发生的异常转换为对应的结果按结果格式返回,即其结构会变成以下这样:

{
    "ret": 0,  // 异常时的错误码
    "data": [],
    "msg": "", // 异常时的错误信息
    "debug": {
        "exception": [  // 异常时的详细堆栈信息
        ],
        "stack": [  // 自定义埋点信息
        ],
        "sqls": [  // 全部执行的SQL语句
        ]
    }
}
  • 查看全部执行的SQL语句

debug.sqls中会显示所执行的全部SQL语句,由框架自动搜集并统计。最后显示的信息格式是:

[序号 - 当前SQL的执行时间ms]所执行的SQL语句及参数列表

示例:

[1 - 0.32ms]SELECT * FROM tbl_user WHERE (id = ?); -- 1

表示是第一条执行的SQL语句,消耗了0.32毫秒,SQL语句是SELECT * FROM tbl_user WHERE (id = ?);,其中参数是1。

  • 查看自定义埋点信息

debug.stack中埋点信息的格式如下:

[#序号 - 距离最初节点的执行时间ms - 节点标识]代码文件路径(文件行号)

示例:

[#0 - 0ms]/path/to/phalapi/public/index.php(6)

表示,这是第一个埋点(由框架自行添加),执行时间为0毫秒,所在位置是文件/path/to/phalapi/public/index.php的第6行。即第一条的埋点发生在框架初始化时。

与SQL语句的调试信息不同的是,自定义埋点则需要开发人员根据需要自行纪录,可以使用全球追踪器PhalApiDI()->tracer进行纪录,其使用如下:

// 添加纪录埋点
PhalApiDI()->tracer->mark();

// 添加纪录埋点,并指定节点标识
PhalApiDI()->tracer->mark('DO_SOMETHING');

通过上面方法,可以对执行经过的路径作标记。你可以指定节点标识,也可以不指定。对一些复杂的接口,可以在业务代码中添加这样的埋点,追踪接口的响应时间,以便进一步优化性能。当然,更专业的性能分析工具推荐使用XHprof。

参考:用于性能分析的XHprof扩展类库

  • 查看异常堆栈信息

当有未能捕捉的接口异常时,开启调试模式后,框架会把对应的异常转换成对应的返回结果,并在debug.exception中体现。而不是像正常情况直接500,页面空白。这些都是由框架自动处理的。

例如,让我们故意制造一些麻烦,手动抛出一个异常。

class Hello extends Api {

    public function fail() {
        throw new Exception('这是一个演示异常调试的示例', 501);
    }
}

再次请求后,除了SQL语句和自定义埋点信息外,还会看到这样的异常堆栈信息。然后便可根据返回的异常信息进行排查定位问题。

  • 添加自定义调试信息

当需要添加其他调试信息时,可以使用PhalApiDI()->response->setDebug()进行添加。

如:

class Hello extends Api {

    public function fail() {
        $x = 'this is x';
        $y = array('this is y');
        PhalApiDI()->response->setDebug('x', $x);
        PhalApiDI()->response->setDebug('y', $y);
    }
}

请求后,可以看到:

    "debug": {
        "x": "this is x",
        "y": [
            "this is y"
        ]
    }

分类导航

关注微信下载离线手册

bootwiki移动版 bootwiki
(群号:472910771)