-
Notifications
You must be signed in to change notification settings - Fork 175
Home
phprs通过@注释定义类的路由、绑定输入输出、管理依赖
在类头部的注释中声明
-
@path
必选
形式:
@path("/myapi")
指定此类下所有接口都在/myapi路径下(这里指url路径, 而不是文件在磁盘上的路径)
-
@route
必选
声明方法对应的路由
如果有多个路由匹配, 则命中最严格的规则
同一个方法可以声明多个@route
形式:
@route("GET", "func1")
匹配 GET /myapi/func1@route("*", "func1")
匹配 所有方法 /myapi/func1@route("GET", "func1?param=1")
匹配GET /myapi/func1?param=1, 其中query_string参数的先后顺序无关(如/myapi/func1?param2=x¶m=1也匹配)@route("GET", "patha/*")
匹配GET /myapi/patha/下所有子路径,如/myapi/patha/123, 但不匹配/myapi/patha@route("GET", "patha/*\/pathb")
匹配GET /myapi/patha/下所有子路径中存在pathb的@route("GET", "resources/type1") @route("GET", "resources/type2") @route("GET", "resources/type3")
匹配其中任意一条规则, 就调用接口
-
@param
必选(如果方法有参数)
声明方法的参数, 如果被声明的参数不存在, 且此参数没有默认值, 请求调用时,将抛出异常.
如果参数是引用方式传递, 则参数的来源可以在方法内部修改, 这在实现hook时很有用.
形式:
@param({"arg0","$._GET.param0"})
指定方法被调用时,"$._GET.param0"对应的值将被作为参数$arg0,"$._GET.param0"是jsonpath表达式, 可以搜索$GLOBALS数组中的数据, 除此之外还有一些特殊的变量: $.path 获取当前请求的路径(相对于Router中指定的root_path, 默认是相对于"/" )@param({"arg1","123"})
指定方法被调用时,字符串常量"123"将被作为参数$arg1 -
@return
可选
声明方法的返回
如果不声明@return, 将把方法的返回值作为http的body输出,输出时,数组将被json_encode成字符串
输出可以支持变量(
$开头)和常量(不以$ 开头)形式:
@return({"output_func", "$arg1","$arg2"...})
将通过output_func输出,output_func的两个参数分别是方法的参数$arg1,$arg2.$arg1,$arg2必须是引用参数@return({"body"})
输出body, 将方法的返回值作为http的body输出@return({"body", "$arg0"})
输出body, 取方法的$arg0参数(必须是引用参数)作为http的body输出@return({"cookie", "$name", "$value", "$expire" })
输出cookie, 参数形式参考setcookie ( string $name [, string $value [, int $expire = 0 [, string $path [, string $domain [, bool $secure = false [, bool $httponly = false ]]]]]] )
@return({"header", "$name", "$value", "$expire" })
输出header,参数形式参考void header ( string $string [, bool $replace = true [, int $http_response_code ]] )
@return({"status", "200 OK" })
输出http status code@return({"res", "200 OK", {"res":"ok"} })
输出http status code + body -
@throws
声明方法的异常, 声明后的, 方法如果抛出异常, 将被捕获
不要去尝试捕获所有异常, 原则上内部错误的异常都不要捕获, 只有如验证失败, 参数错误等外部异常, 需要根据异常指定不同的http status, 如"400 Bad Request"
形式:
@throws({"MyException","output_fun", "arg0", "arg1"})
如果捕获MyException异常, 则通过output_fun输出,output_fun的参数是arg0, arg1. 支持的输出方式与@return一致. 匹配异常的规则是,如果有完全匹配的异常(异常类一样), 则只执行完全匹配的异常, 否则匹配异常的父类@throws({"NotFoundException", "status", "404 Not Found"})
如果匹配异常NotFoundException, 则status输出404 Not Found -
@cache
可选
声明方法的结果是否缓存, 下次收到同样的输入参数时, 不执行此方法, 而是直接返回
形式:
@cache({"ttl", 3600}))
使用缓存, 且缓存的有效期是3600秒@cache({"check", "$check"}))
使用缓存, $check是方法的变量(通过引用返回),缓存的过期通过调用$check($data, $create_time)判断, 返回false表示过期, 如$check = newFileExpiredChecker('file.tmp'); 通过判断file.tmp是否修改, 判断缓存是否过期.框架默认使用apc缓存,可以通过配置文件指定其他缓存方式如:
{ ... "tinyESB\\rsapi\\Invoker": { "properties": { "cache":"invokeCache"// 1.指定接口调用使用的缓存实例 } }, //缓存实例的配置 "invokeCache":{ "class":"utils\\RedisCache", "singleton":true, "properties":{ "serialize":true, "host":"127.0.0.1", "port":"6379" } }, ... }
在方法的属性中声明的注释
-
@property
可选
注入属性, 在创建类时(构造函数调用之前), 由IoCFactory从配置文件中读取, 注入实例.
属性会在__construct之前被注入,所以可以在__construct中访问被注入的属性。 形式:
/** @property */ private $name;
$name是一个属性, 且是必须被注入的
/** @property */ private $name='value';
$name是一个属性, 可选, 有默认值
/** @property({"optional":true}) */ private $name;
$name是一个属性, 可选, 没有默认值
-
@inject
可选
注入外部依赖
形式:
/** @inject("$.path[0]") */ private $app_name; /** @inject("$.factory") 注入创建该实例的工厂实例*/ private $factory;
与方法的参数注入类似, 但不同的是, 属性会在类实例化的时候就注入
- 典型的配置文件
{
"key":
{
"class":"class_name", //可选, 指定真正的类名,如果不指定, 则使用key作为类名
"singleton":true,// 可选,是否是单例, 默认是false
"pass_by_construct":true,//可选, 属性是否以构造方法参数的形式传递, 默认是false
"properties":
{ //注入的属性
"name1": "{tpl}/apis/", //{tpl}模板变量,加载配置文件时被替换
"name2": "value",
"name3":"@key1" //@表示引用, 即取key1的实例作为值
}
},
"key1":{
...
}
- 示例
{
"caoym\\phprs\\RouterWithCache":
{ //下面是针对RouterWithCache的配置
"properties":
{
"api_path": "{app_root}/apis/", //扫描api类的目录
"cache":"@caoym\\util\\Cache" //缓存的实现类
}
},
"caoym\\phprs\\Router":
{ // 针对Router的配置
"properties":
{
"hooks": ["Hook1","Hook2"] //指定hook执行顺序
}
},
//接口类配置
"MyApi1":
{
"properties":
{
"conf1": "conf value 1",
"conf2": "conf value 2"
}
}
}
hook实现与接口实现完全一致, 不同的是hook要放在api目录下的hooks中, 同时在配置文件中指定caoym\phprs\Router的hooks
hook会在api被调用前, 按配置的顺序执行, 只有匹配路由规则的hook会被执行.
hook中即可以修改请求, 也可以修改响应.
如果要中途结束hook的执行链路(不再执行后续hook和api), 可以指定
@return({"break", 1})
或者
@return({"break", $is_break})
-
示例
/** * @path("/hw") * @author caoym */ class HookApiName { /** * uri中提取app名,并把app从uri中去掉 * @route({"GET","/"}) * @param({"app", "$.app_name"}) * @param({"ori_path", "$.path"}) * @param({"dest_path", "$._SERVER.REQUEST_URI"}) */ function fetchAppName($ori_path, &$dest_path, &$app){ $app = $ori_path[0]; array_shift($ori_path); $dest_path = '/hw/'.implode('/', $ori_path); } }
此功能默认关闭, 开启后将允许通过接口("http://your-domain.com/apis/")获取接口本身的文档,形式如下:
<?php
/**
* doc class
* @path("doc_sample")
*/
class DocSample
{
/**
* doc func
* @route({"POST", "path1"}) doc path1
* @route({"POST", "path2"})
* doc path2
* @param({"arg0", "$._GET.arg0"}) doc arg0
* @param({"arg1", "$._POST.arg1"}) doc arg1
* @return({"body"}) doc return body
* @return({"status", "200 OK"}) doc return status
* @return({"header", "$header0"}) doc return $header0
* @return({"cookie", "token", "$cookie0"}) doc return $cookie0
* @throws({"Exception", "status", "500 Internal Server Error"}) doc Exception
*/
public function func($arg0, $arg1, &$header0, &$cookie0){
}
/**
* @inject("$.path[2]")
* doc common
*/
private $common;
}
生成的文档如下:
开启方式为设置" caoym\phprs\Router"的属性"export_apis"为true 目前支持文档化的注释有:
@route
@path
@return: status,header,cookie, body,res
@throws:status,header,cookie, body
@param: $.path[?], $._SERVER.HTTP_X_???, $._GET.?, $._POST.?