今天看到php注解的介绍文章很感兴趣,动手实际试了试挺好玩,写这篇文章记录下php从8开始支持原生注解功能了,我们可以写个小的例子看看注解怎么玩 。 先确定我们的任务目标1、编写一个注解类route处理根据注解反射将使用注解的方法加入到路由列表2、定义入口文件初始化项目自动完成路由列表的更新3、根据URL请求从路由列表获取路由信息找到对应类实例化并执行对应方法 先做个约定:1、约定路由格式为:http://localhost/8/index.php?c=index&a=index这里c 表示控制器controller,a 表示动作 action 也就是类方法2、约定目录结构root|---index.php|---config.php|---route.php---|controller|---index.php|---work.php config.php配置文件,route.php注解路由类文件和index.php 入口文件平级controller/indexController.php,controller/workController.php两个使用注解的测试控制器位于下一级目录controller中 前期准备先准备两个类用来测试<?phpclass indexController{#[route('/controller/index','get')]public function index():void{echo "This is attribute index controller \r\n";}#[route('/controller/test','get')]public function test():void{echo "This is attribute test controller \r\n";}}indexController控制器类,有两个方法index和test<?phpclass workController{#[route('/controller/work','post')]public function work():void{echo "This is attribute work controller \r\n";}}workController控制器类,有一个方法work 前期工作完成,开始实际编写注解路由类【php注解使用示例】<?php#[Attribute(Attribute::IS_REPEATABLE|Attribute::TARGET_METHOD)]class route{public static $all = [];public static $path = '';public static $method = 'GET';public static $function = '';public static $controller = '';public function __construct(){}public function setPath(string $path):self{$this->path = $path;return $this;}public function setMethod(string $method):self{$this->method = $method;return $this;}public function setFunction(string $function):self{$this->function = $function;return $this;}public function setController(string $controller):self{$this->controller = $controller;return $this;}public function addRoute():void{self::$all[str_replace("Controller","",$this->controller)][$this->function] = $this;} 先定义路由的相关类属性,这里不考虑访问范围问题都用public修饰符在这个类中定义了设置path、method、function、controller属性的方法,返回值用$this表示可以链式调用addRoute() 方法将当前对应按 [‘控制器’][‘方法’] 的二维数组存起来备用这里要说明下#[Attribute(Attribute::IS_REPEATABLE|Attribute::TARGET_METHOD)]这就是注解的定义,有这个表示这个类是注解类Attribute是注解关键词,后面小括号里的是注解属性配置IS_REPEATABLE 表示这个注解可以重复使用TARGET_METHOD 表示这个注解只能用来修饰类内的方法 注意:这里定义的TARGET_METHOD在php语法检查时不会进行验证,即用这个注解修饰属性或类代码也不会报错,但执行会抛出异常有了注解类我们就可以开始实际使用了<?phppublic static function setRoute($controllerClass){$ref = new ReflectionClass($controllerClass);$controller = $ref->getName();$methods = $ref->getMethods();foreach($methods as $method){$function = $method->getName();$attributes = $method->getAttributes(route::class);foreach($attributes as $attribute){$route = $attribute->newInstance();// 拿到注解上的参数$params = $attribute->getArguments();$route->setController($controller)->setFunction($function)->setPath($params[0])->setMethod($params[1])->addRoute();}}}}在route类定义新的方法,根据注解反射路由列表setRoute()方法接收一个被route注解修饰的类作为参数 。通过反射获取控制器名称,方法列表将其调用route一系列方法设置属性并加入路由列表 现在我们可以使用注解生成路由列表了indexController类的两个方法都使用route注解进行修饰,并指定path和method两个参数此时我们打印route::$all路由列表
文章插图
可以看到当前的路由列表确实是按照['控制器']['方法']的二维数组组装起来了,并且保存了每个路由的对象到这里核心的使用注解生成路由列表其实已结束了,但如果不能看看效果谁知道你是不是胡说的呢?因此下面我们完善这个例子实现通过localhost/8/index.php?c=index&a=index格式的URL访问对应控制器的功能 <?phpclass app{public function appInit():self{if(glob("./controller/*.php")){foreach(glob("./controller/*.php") as $fileName){require_once($fileName);$className = str_replace("./controller/","",str_replace(".php","",$fileName));route::setRoute($className);//route::$all;exit();}}return $this;}public function run($config){$controller = $_GET['c']??$config['default_controller'];$action = $_GET['a']??$config['default_function'];if(isset(route::$all[$controller][$action])){$route = route::$all[$controller][$action];$className = $route->controller;$function = $route->function;(new $className)->$function();}else{exit("404 Not Found!");}}}
推荐阅读
- netty系列之: 在netty中使用 tls 协议请求 DNS 服务器
- 使用LabVIEW实现基于pytorch的DeepLabv3图像语义分割
- 天猫精灵cc7怎么使用_天猫精灵cc7使用方法
- iPadmini6使用体验_iPadmini6使用感受
- Nginx 使用自签名证书实现 https 反代 Spring Boot 中碰到的页面跳转问题
- 真我v15开箱_真我x50实际使用测评
- 如何使用微信截图(微信怎么截图发给别人)
- 华为mate40手机怎么截屏_华为mate40截图功能怎么使用
- 当贝智慧盒子Z1 Pro值得买吗_当贝智慧盒子Z1 Pro使用评价
- disk磁盘分区软件使用教程,磁盘扩容无损备份