未加注解导致无法访问
1、背景和目的
工作中重构DB时,需要将部分app(someClass:class)方式的仓库层、service层调用,替换为构造函数注入的方式来实现,从而让IDE更好的为我们工作(app方式其实也是依赖注入,参见关联资料3)
2、导致出错的做法
新建了questions/homepageController的默认构造函数,并保留了abstractController的构造函数
public function __construct(
CmsService $cmsService,
PracticeService $practiceService,
) {
$this->_cmsService = $cmsService;
$this->_practiceService = $practiceService;
parent::__construct();
}
看上去没有问题,但是遇到了一个报错:
"message": "您无权访问",
"file": "/path/to/CheckRole.php",
3、问题追查
按如上路径开始跟踪报错,发现是一个角色字段检查,比较神奇,这个字段并不是参数传入,又不是什么环境变量,如何传入并校验的呢?最终发现它是通过注解方式传入的:
@roles('student')
4、解决方案
在新建的构造函数注释中添加注解@roles('student')
至此问题解决,但是我们还需要了解下这个注解,深入研究下
Phalcon注解学习
1、注解解析器 Annotations Parser
这是第一个为PHP用C语言写的注解解析器。 Phalcon\Annotations是一个通用组件,为应用中的PHP类提供易于解析和缓存注解的功能。
- 注解位置:读自类,方法和属性的注解区域。一个注解单元可以放在注解区域的任何位置。
- 注解结构:@注解名称[(参数1, 参数2, ...)],注解单元可以有参数也可以没有。
- 注解类型:(Types of Annotations)注解的参数可以为简单的文字(strings, number, boolean, null),数组,哈希列表或者其他注解单元
2、读取注解 Reading Annotations
实现反射器(Reflector)可以轻松获取被定义在类中的注解,使用一个面向对象的接口即可:
<?php
$reader = new \Phalcon\Annotations\Adapter\Memory();
//获取 Example 类的注解
$reflector = $reader->get('Example');
//读取‘类注释’中的注解
$annotations = $reflector->getClassAnnotations();
//遍历注解
foreach ($annotations as $annotation) {
//打印注解名称
echo $annotation->getName(), PHP_EOL;
//打印参数个数
echo $annotation->numberArguments(), PHP_EOL;
//打印参数
print_r($annotation->getArguments());
}
虽然这个注解的读取过程是非常快速的,然而,出于性能原因,我们建议使用一个适配器储存解析后的注解内容。 适配器把处理后的注解内容缓存起来,避免每次读取都需要解析一遍注解。
Phalcon\Annotations\Adapter\Memory 被用在上面的例子中。这个适配器只在请求过程中缓存注解,请求完成后缓存将被清空,因为这个原因,这个适配器非常适合用于开发环境中。当应用跑在生产环境中还有其他适配器可以替换。
3、注解适配器Annotations Adapters
这些组件利用了适配器去缓存或者不缓存已经解析和处理过的注解内容,从而提升了性能或者为开发环境提供了开发/测试的适配器:
Name | Description | API |
---|---|---|
Memory | 请求结束时候,这个缓存就会清除,因为此特性,这个适配器适合开发环境 | Phalcon\Annotations\Adapter\Memory |
Files | 解析出来的注解会缓存在PHP文件当中,这个适配器需要配合一个字节码缓存使用 | Phalcon\Annotations\Adapter\Files |
APC | 解析出来的注解会缓存在APC cache中,相比Files更快 | Phalcon\Annotations\Adapter\Apc |
XCache | 解析出来的注解会缓存在XCache cache中,同样相比Files更快 | Phalcon\Annotations\Adapter\Xcache |
拓展
PHP并没有内置的注解功能,现有很多注解的解析、存储、注入等功能,其原理其实是使用的反射类来实现的IOC和AOP,下面是一些拓展资料:
暂时至此
phalcon注解底层实现尚未深挖,欢迎大佬们补充
关联资料
1、注解解析器Annotations Parser
https://phalcon-doc-cn.readthedocs.io/zh_CN/latest/reference/annotations.html#annotations-parser
2、Class Phalcon\Annotations\Adapter\Memory
3、Phalcon app(someClass:class) 实现方式
if (!function_exists('app')) {
/**
* Get the available container instance.
*
* @param string $make
* @param array $parameters
* @return mixed|Application
*/
function app($make = null, $parameters = [])
{
if (is_null($make)) {
return \Phalcon\Di::getDefault();
}
return \Phalcon\Di::getDefault()['maker']->make($make, $parameters);
}
}
4、三款免费的PHP加速器:APC、eAccelerator、XCache比较
欢迎大佬们指点
以上,共勉
欢迎大家关注我的公众号
网友评论