打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
PHP的Annotations

Annotation是什么?
好吧,名字确实有点陌生,但是直白一点Annotation就是每天与我们经常打交道的注释。 何为注释?一种独特的有说明性的注解,在代码中就是注释咯。Annotation是相关代码的元数据(metadata:用来描述数据的数据)。有些编程语言中它仅仅是一种描述性的东西,并不会直接影响我们的代码运行情况,比如PHP;而在另外一些编程语言中,则会产生影响,比如Java、C#等。 但是说白了,今天讨论的Annotation没什么高大上的,它还是注释。但我想今天讨论了Annotation之后,你心中的注释的范围或者注释的功能将会变得不同。

先预个热,假如我们之前谈到的注释叫Comment的话,那么Annotation将是Comment的超集,也就是说Annotation = {Comment, DocBlock, …}。 你可能发现了DocBlock这样的概念。

DocBlock是什么,和传统的Comment有什么区别?
Comment:

// this is a comment/* this is a multiline comment  */

Docblock:

/***   this is a docblock*/

还有一个区别:Comment将会被Opcache忽略,而Docblock将会被Opcache缓存。

Annotation有什么好处?
姑且说我们已经可以写得一屏好注释(Comment)了,所以我们今天将只讨论Annotation的DocBlock部分。

先来一个Annotation的例子,前面说到Comment本身无法为我们的代码带来什么好处,而是会带来一些提高可读性的好处,如下:

class Foo{  /**   * @var integer   * @range(0, 100)   */  public $bar;}
  • 告诉我们$bar期望是一个整数
  • 告诉我们$bar期望的范围是0-100
  • 除了告诉我们之外,也告诉IDE Foo实例的$bar属性是整数

基本的Annotation例子就是这样,而且我敢保证这样的例子你也并不陌生,标准的Annotation就是类似于以 @ 开头的,比如@var @param等,它们的语法格式为:

@var {type} {description}@param {type} {$name} {description}

如果是PHP程序员的话,对@var会比较陌生,因为IDE经常会为我们自动生成@param这样的Annotation。

PHPDocument?
看到这样的语法,如果接触过PHPDocument或者Javadoc的同学可能会相对会熟悉一些,比如我们可以通过PHPDocument生成代码的文档,而且可以在线浏览。而如果我们今天只讨论这种文档级别的内容或许就没什么意思了,看一下下面这个例子。

public class Customer{    [Required]    [StringLength(50)]    public string Prename(String name){}

看到上面的代码,我们猜猜Prename()函数上面的[Required]和[StringLength(50)]有什么作用?实际上这个可以理解为C#的Annotation,而这两行就是用于控制name参数一定要存在并且长度不超过50个字符。那么是否真的可以控制?或者说如果真的超过50个字符后程序会有什么表现呢?难道还能抛出异常还是什么呢?

把上面的代码翻译成PHP版本的,大概是下面这个样子:

class Customer{    /**    *  required    *  NameLength(50)    */    public function Prename($name){}

然而,然而,然而,这Annotation是写在/** */里面的,从学任何一门编程语言的第一天起就知道,这是不会执行的,对吧?那Annotation貌似好像并没有什么卵用。

PHP官方对Annotation的支持程度?
2000:PHPDocument创立
2005:PHP5.1的Reflection支持getDoccomments()

<?php/** * * A test class * * * * @param  foo bar * * @return baz * */class TestClass { }$rc = new ReflectionClass('TestClass');var_dump($rc->getDocComment());?>

2008:Doctrine2 也是PHP的Annotation引擎
2010:PHP Rfc讨论了关于Annotations内容rfc/annotations,But没有通过投票。
2011:PHP Rfc讨论了DocBlockrfc/annotations-in-docblock
2013:再一次讨论

没下文了。。。


是的,实际上真的没有下文了,不过如果今天的讨论到此为止,那我猜你得想打死我~然而PHP官方确实没有对此进行过强有力的支持,但即便如此,有许多优秀的框架/库还是花费了不懈的努力去实现并享受着Annotation带来的好处。

Annotation的实际项目

  • Symfony
  • Doctrine
  • PHPUnit
  • ZendFramework

Annotation可以用来做什么?

测试
PHPUnit的一个例子,通过为测试方法定义一些Annotation,比如此例子中定义InvalidArgumentException参数指定异常实例。

class DataTest extends PHPUnit_Framework_TestCase{/*** @dataProvider provider** @expectedException InvalidArgumentException* @expectedExceptionMessage Right Message*/public function testAdd($a, $b, $c){    /* Test code */}

钩子/回调/参数验证

/*** @Route("/myaction/{id}", name="myaction")* @Method("POST")** @Template("MyBundle:MyController:my.html.twig") ** @param int $id * * @return array */public function myAction($id){    /* Controller Logic */    return array('data' => $data);}

看上面这个Symfony的例子,通过定义为myAction定义了@Route @Method @Template等Annotation,不仅对myAction()一目了然,并且Symfony通过解析@Template则可以做一些类似于回调的东西,可以在框架层次将内容解析到模板中,此过程大概类似于如下

index.php路由到myAction -> $rc->getDocComment()得到myAction()的Annotation -> 解析Annotation得到myAction()的模板 -> 框架得到myAction()返回的数据 -> 将数据渲染到模板

过程其实还是很清晰的,同时在此过程中也可以很容易的做一些参数验证的工作,比如$id的类型啊,大小啊什么的。

filter

class Foo{    /**    * @My\Annotation("name", nullable=true)    */    public funciton myAction($name)    {

从上面的例子上看,实现参数过滤当然也是可能的啦,而在Symfony2中还存在了这样一个bundle以达到通过Annotatios功能的rdohms/DMS。

综上
PHP对Annotation的支持一直表现的很拘谨,不过好在在反射中还对此做出了点贡献,不然今天的PHP届Annotation真心不太好玩。不过感谢那么多大牛和前辈将Annotation吸收到了非常有名的框架中,让更多的PHPer知道。
当然Annotation也不是一个特别流行的语言特性,目前貌似只有c#和Java存在,虽然Annotation有比较多的用途,但是具体使用还是要综合考量。

延伸阅读
如果读者感兴趣,可以研究下Doctrine的Annotation Parser

参考
PHP Annotations: They exist! by Rafael Dohms at the PHP Benelux Conference 2013

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
PHP Document 代码注释规范
yaml语法
ComplexHeatmap|根据excel表绘制突变景观图(oncoplot)
PHP开发框架流行度排名:Laravel居首
有关PHP文档生成工具---PHPDocumentor
给你的PHP函数和类添加标准的注释说明
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服