PHP 8 新特性之 Attributes (注解)
PHP8 的 Alpha 版本,过几天就要发布了,其中包含了不少的新特性,当然我自己认为最重要的还是 JIT,这个我从 2013 年开始参与,中间挫折无数,失败无数后,终于要发布的东东。
不过,今天呢,我不打算谈 JIT,等 PHP8 发布了以后,我再单独写个类似《深入理解 PHP8 之 JIT》系列来说吧。
嘿嘿,今天呢,我想谈谈 Attributes,为啥呢, 是昨天我看到很多群在转发一个文章,叫做《理解 PHP8 中的 Attributes》,说实在的,这篇文章应该是直接从英文翻译过来的,写的晦涩难懂,很多同学看完以后表示,看的一头雾水,不知道在说啥。
于是我想,就用一篇文章来简单说说这是个啥。
说注解之前,先说说以前的注释,我们经常会在 PHP 的项目中,看到的一个东西,类似如下的 @param 和 @see :
1. /**
2. * @param Foo $argument
3. * @see https:/xxxxxxxx/xxxx/xxx.html
4. */
5. function dummy($Foo) {}
这个叫做注释,对于以前的 PHP 来说,注释中的 @param 和 @see 毫无意义,整个这一段会保存为一个函数 / 方法的一个叫做 doc_comment 的字符串。
如果我们要分析这段注释的含义,我们需要通过设计一些特定的语法,就比如栗子中的 @+name, 类似 @param 一样, 然后自己分析这段字符串,来提取对应的信息。
比如我们要获取 See 这个注释的信息,我们需要做类似:
1. $ref = new ReflectionFunction("dummy");
2. $doc = $ref->getDocComment();
3. $see = substr($doc, strpos($doc, "@see") + strlen("@see "));
这样的字符串处理,相对比较麻烦,也比较容易出错。
而 Attributes 呢,其实就是把 “注释” 升级为支持格式化内容的 “注解”
比如上面的例子:
1. <?php
2. <<Params("Foo", "argument")>>
3. <<See("https://xxxxxxxx/xxxx/xxx.html")>>
4. function dummy($argument) {}
大家不要纠结这么写的意义是啥,从功能上来说,现在你就可以通过 Reflection 来获取这段格式化的注解了,比如,我们现在要获取 See 这个注解:
1. $ref = new ReflectionFunction("dummy");
3. var_dump($ref->getAttributes("See")[0]->getName());
4. var_dump($ref->getAttributes("See")[0]->getArguments());
会输出:
1. string(3) "See"
2. array(1) {
3. [0]=>
4. string(30) "https://xxxxxxxx/xxxx/xxx.html"
5. }
当然,还有稍微高级一点的用法,就是你可以定义一个所谓的 “注解类”:
1. <?php
2. <<phpAttribute>>
3. class MyAttribute {
4. public function __construct($name, $value) {
5. var_dump($name);
6. var_dumP($value);
7. }
8. }
然后, 你就可以写类似, 注意其中的 newInstance 调用:
1. <<MyAttribute("See", "https://xxxxxxxx/xxxx/xxx.html")>>
2. function dummy($argument) {
3. }
4. $ref = new ReflectionFunction("dummy");
6. $ref->getAttributes("MyAttribute")[0]->newInstance();
如果你跑这段代码,你会看到 MyAttribute 的__construct 方法被调用了,调用传递的参数就是”See” 和”https://xxx”
明白了么, 就是你可以把一个注解 “实例化”, 然后,你就可以基于这个能力,来做自己的 “注释即配置” 的设计。总结下 Attributes 的写法就是如下的形式:
1. <<Name>>
2. <<Name(Arguments)>>
3. <<Name(Argunment1, Arguments2, ArgumentN)>>
然后你就可以通过 PHP 的 Reflection 系列的方法,根据 getAttributes (“Name”) 获取对应的注解, 进一步你可以通过调用返回的注解的 getName 方法获取名字,getArguments 方法获取括号中的 Arguments。
再进一步,如果 Name 是一个你自己定义的,带有 phpAttriubtes 注解的类, 你还可以调用 newInstance 方法,实现类似”new Name (Arguments)” 的调用。
也许很多人会问,这有什么卵用?
坦白说,我一直对新特性无感,但这个 Attributes,多少还是应该有那么一点点吧。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架