1、什么是PhalApi框架?
PhalApi是一个PHP轻量级开源接口框架,致力于快速开发接口服务。支持HTTP/SOAP/RPC等协议,可用于搭建接口/微服务/RESTful接口/Web Services。
PhalApi现存有两大系列版本。分别是经典的第一代版本,即1.x系列版本,主要是使用了较为古老传统的做法;以及全新的第二代版本,即2.x系列版本,主要区别是:
1)、使用了composer统一管理依赖包。
2)、引入了命名空间
3)、遵循PSR-4规范
PhalApi框架目前的最新版本是PhalApi 2.1.2,支持PHP 5.3及以上版本,并支持PHP 7。
2、PhalApi框架的特色
1)、轻量
PhalApi框架由于是一个致力于快速开发接口服务的框架,因此,相对于ThinkPHP、Laravel、Yii……等框架,它更量。没有太多无关紧要的内容。
2)、自动生成在线接口文档
按框架指定的格式完成接口代码编写后,PhalApi会自动生成在线接口列表文档和在线接口详情文档,以方便客户端实时查看最新的接口签名和返回字段。我觉得这是该框架最大的特色,我之所以喜欢这个框架,很大程度上也在于这一点。我写这篇文章的唯一目的,也是想介绍下接口文档自动生成功能。
自动生成的在线文档主要有两类:
在线接口列表文档
在线接口详情文档
3)、众多可重用的扩展类库
PhalApi框架扩展类库,是各自独立,可重用的组件或类库,可以直接集成到PhalApi开发项目,从而让项目开发人员感受搭建积木般的编程乐趣,降低开发成本。
目前,已经提供的扩展类库有40+个,包括:微信公众号开发扩展、微信小程序开发扩展、支付扩展、上传扩展、Excel表格和Word文档扩展等。
3、适用场景与范围
PhalApi适用的场景,包括但不限于:
①、为移动App(包括iOS、iPad、Android、Windowns Phone等终端)提供接口服务
②、用于搭建接口平台系统,提供聚合类接口服务,供其他后端系统接入使用
③、为前后端分离的H5混合页面应用,提供Ajax异步接口
正如其他负责任的开源框架一样,PhlaApi也有其不适宜使用的时机。包括但不限于:
①、开发CLI项目(但已提供支持命令行项目开发的CLI扩展类库)
②、开发网站项目,即有界面展示和视图渲染(但已提供支持视图渲染的View扩展类库)
③、对数据严谨性要求高,如金融行业的相关项目,毕竟PHP是弱类型语言
4、自动生成在线接口文档原理
PhalApi框架自动生成在线文档的原理大致这样:
①、编写接口时,根据注释规则,使用文档注释,对每个接口类和及其方法进行注释说明
②、通过PHP反射机制,获取接口类文件及其方法文档注释。
③、根据注释规则,对获取的文档注释,进行操作,提取内容,并显示出来
5、使用PhalApi 开发 api接口文档:
1)、使用composer下载 、安装
composer create-project phalapi/phalapi
温馨提示:推荐将访问根路径指向/path/to/phalapi/public。可以搭建一个虚拟域名,方便后续操作。因为我使用的是wamp集成环境,如果还不懂怎么配置虚拟域名的同学,可以点此传送门。
在这里,我就不配置了,上述下载完成后,访问此链接 http://localhost/phalapi/public/ ,看到下图,即安装成功
2)、运行一个hello world
①编写一个接口
在PhalApi 2.x 版本中,项目源代码放置在/path/to/PhalApi2/src目录中。里面各个命名空间对应一个子目录,默认命名空间是app,里面主要有Api、Domain、Model这三个目录以及存放函数的functions.php文件。例如像是这样的目录结构:
./src/ └── app ├── Api ├── Domain ├── functions.php └── Model
当需要新增一个接口时,先要在Api层添加一个新的接口文件。例如对于Hello World示例,可以使用你喜欢的编辑器创建一个./src/app/Api/Hello.php文件,并在里面放置以下代码。
// 文件 ./src/app/Api/Hello.php /** * Created by PhpStorm. * User: ck * Date: 2018/4/2 * Time: 23:29 */ namespace App\Api; use PhalApi\Api; class Hello extends Api { public function world() { return array('title' => 'Hello World!'); } }
编写接口时,需要特别注意:
1、默认所在命名空间必须为App\Api。
2、具体实现的接口类必须是PhalApi\Api的子类。
②访问一个接口
通常情况下,建议可访问的根路径设为/path/to/PhalApi2/public。若未设置,此时接口访问的URL格式为:接口域名/public/?s=Namespace.Class.Action。 s参数为service参数的缩写,即使用?s=Class.Action等效于?service=Class.Action,两者都存在时优先使用service参数。
例如,上面新增的Hello World接口的访问链接为:
http://localhost/phalapi/public/?s=Hello.World ( http://localhost/phalapi/public/index.php?s=Hello.World )
或者可以使用完整的写法,带上命名空间App:
http://localhost/phalapi/public/?s=App.Hello.World
③接口返回
默认情况下,接口的结果以JSON格式返回,并且返回的顶级字段有状态码ret、业务数据data,和错误提示信息msg。其中data字段对应接口类方法返回的结果。如Hello Wolrd示例中,返回的结果是:
{"ret":200,"data":{"title":"Hello World!"},"msg":""}
3)、接口响应与在线测试
①、接口响应
业务数据主要是在Api层返回,即对应接口类的方法的返回结果。
实际上,具体的业务数据需要一段复杂的处理,以满足特定业务场景下的需要。Api层需要与Domain层和Model层共同协作,完成指定的功能。这里暂且知道接口结果是在Api层返回,对应接口类成员方法返回的结果即可。
值得注意的是,抛出的异常应该继承于PhalApi\Exception类,并且构造函数的第一个参数,是返回给客户端的错误提示信息,对应下面将讲到的msg字段。第二个参数是返回状态码的叠加值,也就是说最终的ret状态码都会在400的基数上加上这个叠加值,即:401 = 400 + 1。
<?php namespace App\Api; use PhalApi\Api; use PhalApi\Exception\BadRequestException; class Hello extends Api { public function fail() { throw new BadRequestException('签名失败', 1); } }
输出结果:
{"ret":401,"data":[],"msg":"\u975e\u6cd5\u8bf7\u6c42\uff1a\u7b7e\u540d\u5931\u8d25"}
②如何设置JSON中文输出?
默认情况下,输出的中文会被转换成Unicode,形如\uXXXX,如:
"msg":"\u975e\u6cd5\u8bf7\u6c42\uff1a\u7b7e\u540d\u5931\u8d25"
虽然不影响使用,但不便于查看。如果需要不被转码,可以使用JSON_UNESCAPED_UNICODE选项进行配置。重新注册DI()->response并指定配置选项。例如可以:
//文件 phalapi/config/di.php $di->response = new \PhalApi\Response\JsonResponse(JSON_UNESCAPED_UNICODE); // 中文显示
设置后,重新请求 http://localhost/phalapi/public/?s=App.hello.fail ,将会看到:
{"ret":401,"data":[],"msg":"非法请求:签名失败"}
③返回JSONP、XML等其他格式
④在线调试
a)、开启调试调试
开启调试模式很简单,主要有两种方式:
单次请求开启调试:默认添加请求参数&__debug__=1
全部请求开启调试:把配置文件./Config/sys.php文件中的配置改成'debug' => true,
b)、调试信息有哪些?
正常响应的情况下,当开启调试模式后,会返回多一个debug字段,里面有相关的调试信息。如下所示:
{ "ret":401, "data":[], "msg":"非法请求:签名失败", "debug":{ "stack":["[#0 - 0ms]D:\\wamp\\www\\phalapi\\public\\index.php(6)"], // 自定义埋点信息 "sqls":[], // 全部执行的SQL语句 "version":"2.2.2" } }
a、查看全部执行的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。
b、查看自定义埋点信息 (debug.stack中埋点信息)
c、查看异常堆栈信息 (debug.exception中体现)
d、添加自定义调试信息
注意:b、c、d详细使用,请查看http://docs.phalapi.net/#/v2.0/response-and-debug 文档
4)、api接口文档编写
哈哈,终于到 使用phalapi框架 具体编写api接口文档啦啦啦啦啦啦~~
①PhalApi框架参数规则:
参数规则是针对各个接口服务而配置的多维规则数组,由接口类的getRules()方法返回。其中,
a、一维下标是接口类的方法名,对应接口服务的Action;
b、二维下标是类属性名称,对应在服务端获取通过验证和转换化的最终客户端参数;
c、三维下标name是接口参数名称,对应外部客户端请求时需要提供的参数名称。
②PhalApi框架注释规则:
a、接口服务名称是指用于请求时的名称,对应s参数(或service参数)。接口服务的中文名称,为不带任何注解的注释,通常为接口类成员函数的第一行注释。
b、接口说明对应接口类成员函数的@desc注释。
c、接口参数是根据接口类配置的参数规则自动生成,即对应当前接口类getRules()方法中的返回。其中最后的“说明” 字段对应参数规则中的desc选项。可以配置多个参数规则。此外,配置文件./config/app.php中的公共参数规则也会显示在此接口参数里。
d、返回结果对应接口类成员函数的@return注释,可以有多组,格式为:@return 返回类型 返回字段 说明。
e、异常情况对应@exception注释,可以有多组,格式为:@exception 错误码 错误描述信息。
f、公告注释
对于当前类的全部函数成员的公共@exception异常情况注释和@return返回结果注释,可在类注释中统一放置。而对于多个类公共的@exception和@return```注释,则可以在父类的类注释中统一放置。
也就是说,通过把@exception注解和@return注解移到类注释,可以添加全部函数成员都适用的注解。例如,Api\User类的全部接口都返回code字段,且都返回400和500异常
<?php namespace App\Api; use PhalApi\Api; use PhalApi\Exception\BadRequestException; /** * 用户接口服务类 * * @author: ck <961900490@qq.com> 2018-04-03 */ class User extends Api { public function getRules() { return array( 'login' => array( 'username' => array('name' => 'username','require' => true,'min' => 4, 'max' => 4), 'password' => array('name' => 'password','require' => true,'default' => '123456'), ), ); } /** * 默认接口服务 * @desc 默认接口服务,当未指定接口服务时执行此接口服务 */ public function index() { } /** * 登录接口服务 * @desc 指用户使用登录时,调用的登录接口服务 * @return string username 登录名 * @return string password 登录密码 * @return string content 返回消息内容 * @return int time 当前时间戳 * @exception 400 非法请求,参数传递错误 * @exception 500 服务器内部错误 */ public function login() { if($this->username != '') { return array( 'username' => $this->username, 'password' => $this->password, 'content' =>'登录成功!', 'time' => time() ); } else { return array( 'username' => $this->username, 'password' => $this->password, 'content' =>'用户名不能为空!', 'time' => time() ); } } /** * 异常接口服务 * @desc 指用户使用登录时,调用的异常接口服务 * @return string [] * @exception 401 服务器内部错误 */ public function fail() { throw new BadRequestException('签名失败', 1); } }
登录接口的调用方式:http://localhost/phalapi/public/?s=App.user.login&username=dogstar&password=123456
5)、如何查看在线接口文档:
按框架指定的格式完成接口代码编写后,PhalApi会自动生成在线接口列表文档和在线接口详情文档,以方便客户端实时查看最新的接口签名和返回字段。
当项目搭建成功后,直接访问如下链接,即可查看 在线接口列表文档,如图所示:
http://localhost/phalapi/public/docs.php
展开,即可看到在线接口详情文档:
此在线文档是实时生成的,可根据接口源代码以及注释自动生成。当有新增接口服务时,刷新后便可立即看到效果。通过在接口列表文档,可点击进入相应的接口详情文档页面。
温馨提示:如果打开在线文档,未显示任何接口服务,请确保服务环境是否已关闭PHP的opcache缓存。
6)、如何生成离线文档?
在线的接口文档,也可以一键生成离线版的HTML文档,方便传阅,离线查看
当需要生成离线文档时,可以在终端,执行以下命令:
phalapi$ php ./public/docs.php Usage: 生成展开版: php ./public/docs.php expand 生成折叠版: php ./public/docs.php fold 脚本执行完毕!离线文档保存路径为:/phalapi/public/docs
执行后,可以看到类似上面的提示和结果输出。再查看生成的离线文档,可以看到类似有:
phalapi$ tree ./public/docs ./public/docs ├── App.Examples_CURD.Delete.html ├── App.Examples_CURD.Get.html ├── App.Examples_CURD.GetList.html ├── App.Examples_CURD.Insert.html ├── App.Examples_CURD.Update.html ├── App.Examples_Upload.Go.html ├── App.Site.Index.html ├── App.User.Fail.html ├── App.User.Index.html ├── App.User.Login.html └── index.html
最后,可以在页面访问此离线版文档,如访问链接:
http://localhost/phalapi/public/docs/index.html
文末最后附上代码实例:链接:https://pan.baidu.com/s/1Ukz0o9gVCSormslJh48uLg 密码:rzbi
本文为崔凯原创文章,转载无需和我联系,但请注明来自冷暖自知一抹茶ckhttp://www.cksite.cn