PSR 5 PHP 注释 「被拒绝」

1. 简介

此 PSR 的主要目的是提供一份标准的完整的正式的 PHP 文档注释的 ( PHPDoc ) 规范。 此 PSR 基于它的前身,一个事实上的 PHPDoc 标准, phpDocumentor 1.x,在解决了其前身的一些缺点的同时又为 PHP 语言中的新特性提供支持

此规范 不应该也不会

  • 为 PHP 文档注释 ( PHPDoc ) 定义一个标准的注释实现,虽然它提供的大量的功能说明足以让它成为此规范的一个子规范

    关于这个主题的更多信息,可以访问 chapter 5.3 章节

  • 定义一个使用 PHP 文档注释 ( PHPDoc ) 的最佳实战或推荐编码标准

    此文档仅限于语法和意图的一个正式规范

2. 此规范使用的约定

本篇规范中的 必须,不得,需要,应,不应,应该,不应该,推荐,可能 和 可选 等词按照 RFC 2119 中的描述进行解释

3. 术语

  • 「 PHP 文档注释 」 是提供 「结构元素」各方面资料的文档中的一部分

    「 PHP 文档注释 」 和 「 块注释 」 是两个独立的实体,能正确区分它们是非常重要的一件事。

    1. 「 块注释 」 是由多个 「 文档注释 」 组合而成的。它注释中的一种格式
    2. 「 PHP 文档注释 」,一个 「 PHP 文档注释 」实体是一个包含本规范中定义的语法的实体,如描述和标记

    直白的说, 「 块注释 」 是一种注释的语法格式,「 PHP 文档注释 」则是注释的实际内容

    两者结合在一起则组成了一个完整的注释

  • 「 结构元素 」是由一序列编程结构的集合。它的前面可以有一个 「 块注释 」

    该编程集合包括以下结构

    • 文件 ( file )
    • 载入文件语句 ( require(_once) )
    • 包含文件语句 ( include(_once) )
    • 类 ( class )
    • 接口 ( interface )
    • 特性 ( trait )
    • 函数和方法 ( function (including methods) )
    • 属性 ( property )
    • 常量 ( constant )
    • 变量,包括局部变量和全局变量 ( variables, both local and global scope )

    建议 在 「 结构元素 」之前添加一个 「 块注释 」,用于描述它的每种用途。通常的做法是将 「 结构元素 」 紧跟在 「 块注释 」 之后,两者之间也 可以 添加任意数量的空行来分隔

    例如:

    /** @var int $int 这是一个计数器. */
    $int = 0;
    
    // 此出不因该有块注释
    $int++;
    

    /**
     * 这个类用于演示块注释的位置
     */
    class Foo
    {
        /** @var string|null $title Foot 的标题,最大字符数量为 24 */
        protected $title = null;
    
        /**
         * 设置单行标题
         *
         * @param string $title 最大字符数为 24 的文本
         *
         * @return void
         */
        public function setTitle($title)
        {
            // 此处不应有块注释
            $this->title = $title;
        }
    }
    

    超出此标准范围之外的使用范例是明确的标识 foreach 循环中的变量, 很多 IDE 都使用这些信息来帮助完成自动提示。

    此标准不包括下面这个特定的范例,因为 foreach 语句被认为是流程控制语句而非 「 结构元素 」

      /** @var \Sqlite3 $sqlite */
      foreach($connections as $sqlite) {
          // 此处不应有块注释
          $sqlite->open('/my/database/path');
          <...>
      }
    
  • 「 文档注释 」( DocComment ) 是一个 必须 符合以下规范的注释

    • /** 开始的,其后紧跟一个空格

    • */ 结束

    • 包含零行或多行

    说的直白一点,就是类似编程语言中的块注释,只不过开始的是 /** 是不是 /*

    如果一个文档注释跨越多行,那么每一行 必须 以星号 ( * ) 开头,且该星号必须和开始的 /** 中的第一个星号对齐

    单行文档注释范例:

    /** <...> */
    

    多行文档注释范例:

    /**
     * <...>
     */
    
  • 「 块注释 」 ( DocBlock ) 是源代码文件内的包含单个 「 PHP 文档注释 」 结构的 「 文档注释」

  • 「 标记 」是关于 「 结构元素 」 或其组件的元数据的单个组成部分

  • 「 内联 PHP 文档注释 」 是与「 标记 」关联的 「 PHP 文档注释 」,而不是与 「 结构元素 」关联的,它用于取代 「 标记 」的说明部分

  • 「 类型 」 ( Type ) 是确定关联元素的数据的类型,通常用于确定参数、常量、属性的精确值

    更多类型的信息,可以阅读附录 A

  • 「 语义版本 」 采用的是 语义版本规范 2.0.0 中的定义

  • 「 FQSEN 」 是 Fully Qualified Structural Element Name 的缩写,该符号会展开全限定类名,并添加一个符号来标识类/接口/特征 ( trait ) 的成员,并将 FQCN 的原则重新应用于接口,特性,函数和全局常量

    每一种 「 结构元素 」 都可以使用下列符号

    符号 范例
    Namespace \My\Space
    Function \My\Space\myFunction()
    Constant \My\Space\MY_CONSTANT
    Class \My\Space\MyClass
    Interface \My\Space\MyInterface
    Trait \My\Space\MyTrait
    Method \My\Space\MyClass::myMethod()
    Property \My\Space\MyClass::$my_property
    Class Constant \My\Space\MyClass::MY_CONSTANT

    一个 FQSEN 具有以下 ABNF 定义:

    FQSEN    = fqnn / fqcn / constant / method / property  / function
    fqnn     = "\" [name] *("\" [name])
    fqcn     = fqnn "\" name
    constant = (fqnn "\" / fqcn "::") name
    method   = fqcn "::" name "()"
    property = fqcn "::$" name
    function = fqnn "\" name "()"
    name     = (ALPHA / "_") *(ALPHA / DIGIT / "_")
    

4. 基本原则

  • 一个 PHP 文档注释 必须 始终包含在 「 文档注释 」 中,两者的组合称之为 「 块注释 」

  • 一个块注释后面 必须 直接后直接跟着一个 「 结构元素 」

    此原则的一个例外是文件级别的块注释,它必须作为文件中的第一个块注释放在 PHP 源代码文件的顶部

    为了防止一个结构元素直接位于文件级别的块注释后面时出现歧义,在文件级别的块注释之外,每个结构元素都 必须 有自己的块注释

    下面的范例是一个合法的文件级别的块注释

    <?php    
    /**    
    * 这是一个文件级别的块注释  
    */
    
    /**   
    * 这是一个类级别的块注释
    */  
    class MyClass {
    }
    

    下面的范例是一个非法的文件级别的块注释

    <?php
    /**
    * 这是一个类级别的块注释
    */
    class MyClass {
    }
    

5. PHP 文档注释说明

PHP 文档注释的 ABNF 定义如下:

PHPDoc             = [summary] [description] [tags]
inline-phpdoc      = "{" *SP PHPDoc *SP "}"
summary            = *CHAR ("." 1*CRLF / 2*CRLF)
description        = 1*(CHAR / inline-tag) 1*CRLF ; any amount of characters
                                                 ; with inline tags inside
tags               = *(tag 1*CRLF)
inline-tag         = "{" tag "}"
tag                = "@" tag-name [":" tag-specialization] [tag-details]
tag-name           = (ALPHA / "\") *(ALPHA / DIGIT / "\" / "-" / "_")
tag-specialization = 1*(ALPHA / DIGIT / "-")
tag-details        = *SP (SP tag-description / tag-signature / inline-phpdoc)
tag-description    = 1*(CHAR / CRLF)
tag-signature      = "(" *tag-argument ")"
tag-argument       = *SP 1*CHAR [","] *SP

相关的使用范例可以阅读 5.4 章节

5.1. 摘要 [ summary ]

摘要 必须 包含关联的 「 结构元素 」 的目的的抽象说明。 建议 摘要信息最多不能超过两行。

摘要信息 必须 以下面的方式结尾:

  • 一个句点符 ( . ,中文为 ),后面跟一个空行
  • 或两个连续的换行符 ( \n\n )

如果提供了描述,那么描述信息必须位于摘要之后,否则,描述信息就会被视为摘要,直到遇到摘要的结尾

摘要类似于章节的标题,使用尽可能少的格式是有益的。 因此,与描述信息 ( 参见下一章节 ) 不同,不建议使用标记语言,例如 Markdown ,当然了,是否想要支持标记语言由实现应用程序自由决定。

5.2. 描述信息

描述信息是 可选的。但如果当前所在的块注释关联的 「 结构元素 」 包含更多的操作或更复杂的操作时, 应该 包含描述信息,而不是在摘要信息中详尽描述

建议 任何可以解析描述信息的应用程序都为该字段提供Markdown 标记语言支持 ,这样作者就可以提供格式化的和清晰的演示代码范例

描述信息的常见用途包括 ( 但不限于 ) :

  • 为当前方法能做什么提供比摘要提供更多的更详细的信息

  • 指示一个输入或输出的数组或对象包含哪些组成元素

  • 为关联的 「 结构元素 」 提供一组通用的用例或场景

5.3. 标记 [ Tag ]

标记为其后的 「结构元素」 提供了简洁的元数据。每个标记都开始于一个新行,后跟一个 @ 和一个标记名称,之后是空格和元数据 ( 包括描述 ) 或内联的 PHP 文档注释

如果提供给了元数据,元数据 可以 跨越多行,可以 采用严格的模式,可以提供参数,就像标记类型所指示的那样,标记的类型可以从它的名称中派生而来

例如:

@param string $argument1 这是一个参数。

上面的标记由一个关键字 ( param ) 和元数据 ( string $argument1 这是一个参数。 ) 组成。其中元数据可以分隔为 「 类型 」( string ) 、变量名 ( $argument ) 和 描述信息 这是一个参数。

标记的描述信息 必须 支持 Markdown 作为格式化语言。由于 Markdown 的特性,描述信息放在标记的同一行或和下一行都是合法的,因为它们的解析结果都一样

所以下面的标记从语义上来说都是相同的

/**
 * @var string 这是一个描述信息。
 * @var string 这是一个
 *    描述信息。
 * @var string
 *    这是一个描述信息。
 */

其中的一个变种是使用标记签名而不是描述信息,大多数情况下,标记实际上是一个 「 注释 」。标记签名可以为注释提供有关操作的参数

如果标记签名存在,那么同一个标记中 绝对不能 再出现注释

标记的元数据的结果可能会在关联的 「 结构元素 」 实际的运行时行为中发生改变,在这种情况下,通常使用术语 「注解」而不是「标记」

此文档中不会再详细描述注解,因为这超出了此文档的范畴,此文档只会提供哪个注释可以被实现的基础信息

5.3.1. 标记名称

标记名称用户表示该标记代表什么类型的信息,或者在使用注解的情况下,哪种行为 必须 被注入到关联的 「 结构元素 」中

为了支持注解,允许引入专门为个别应用程序或应用程序子集设计的一组标记 ( 此文档并未涵盖这些标记 )

这些标记,或注解, 必须 提供一个命名空间:

  • 在标记名称前加上一个 PHP 风格的命名空间
  • 在标记名称前加上一个组织名称,组织名称和标记名称使用连字符号 ( - ) 拼接

Example of a tag name prefixed with a php-style namespace (the prefixing slash is OPTIONAL):

以 PHP 风格名称空间为前缀的标签名称的范例 ( 前缀斜杠是可选的 )

@\Doctrine\Orm\Mapping\Entity()

注意

PHP 文档注释标注 并不会 对标记的含义作出任何假设,除非在本文档或后续新增或补充文档中特别规定

这意味着只要提供了前缀名称空间元素,就 可以 使用名称空间别名。因此,以下内容也是合法的:

@Mapping\Entity()

您自己的类库或应用程序 可能会检查命名空间别名并从中创建 FQCN ,这对这个标准没有影响

重要说明:

使用 PHP 文档注释标准的工具 可以 解析它们自己应用程序中注册的名称空间并应用自定义行为

以供应商名称和连字符为前缀的标记的范例:

@phpdoc-event transformer.transform.pre

没有以组织名或命名空间开始的标记 必须 在此规范 ( 参见章节 7 ) 和/或任何其它官方附录中被定义

5.3.2. 标记限定语

为了在不扩展基础集的情况下显示本标准中定义的标记的细微差别, 可以在标记名后添加一个冒号,后跟一个字符串来提供更细致的标记描述。 因为可能随时改变,所以本规范并没有提供一个支持的标记限定语的列表。 此规范的说明文档可能包含一系列关于每个标记名称的建议,但项目可以自由选择它们自己的标记限定

重要信息:

使用 PHP 文档注释标准的工具 可以 解析它们自己应用程序中注册的/理解的标记限定语和应用些自定义行为。 当仍然期待只实现本标准中定义的上述标记的名称

例如:

@see:unit-test \Mapping\EntityTest::testGetId

上面的标记由名称 ( see ) 和标记限定语 ( unit-test ) 组成。该标记为当前的方法定义了一个单元测试

5.3.3. 标记签名

标记签名常用于注解中以提供特定于当前标记的额外元数据。

标记签名提供的元数据可以影响拥有注解的行为,并因此影响其后的「结构元素」的行为

签名的内容由标记的类型决定 ( 正如标记名称中所述的那样 ),而且也超出了本规范的范畴。但是,标记签名后面 绝对不可以 再有描述信息或其它形式的元数据

5.4. 内联 PHP 文档注释

特殊的几个标记 可能 在标记定义的末尾会有一个 「 内联 PHP 文档注释 」部分。 「 内联 PHP 文档注释 」 是一个 「 大括号 」中包含 「 PHP 文档注释 」的元素, 「内联 PHP 文档注释」 只存在于 「 标记 」序列的末尾,除非在 「 标记 」 中另有规定。 「内联 PHP 文档注释」 必须 替换提供的任何可能的描述

典型的范例是 @method 标记,这个标记可以使用 「 内联 PHP 文档注释 」来提供关于参数、返回值或函数和方法治虫的任何其它标记的附加信息

范例:

<?php
/**
 * @method int MyMagicMethod(string $argument1) {
 *     这是 MyMagicMethod 的简介
 *
 *     @param string $argument1 argument 1 参数的说明
 *
 *     @return int
 * }
 */
class MyMagicClass
{
    ...
}

这个范例演示了魔术方法 MyMagicMethod@method 标记是如何包含完整的 PHP 文档注释的定义的。在这个定义中,适用于 PHP 文档注释的所有约束,构造和标签也适用于 「 内联 PHP 文档注释 」

「内联 PHP 文档注释」 的含义因提供的上下文不同而不同,上面的范例中,「内联 PHP 文档注释」 提供了一个类似常规的 PHP 文档注释的定义

因此,为避免混淆使用 「内联 PHP 文档注释」 的功能, 必须 将它们的范围限制在它们标识的标记和位置内

5.5. 范例

下面的范例演示了 块注释的基本用法,建议你先通读第 7 章的标记列表。

一个完整的范例看起来就是下面这个样子:

<?php 
/**
 * 这是一个摘要
 *
 * 这是一个说明。它可以跨越多行,
 * 也可以使用 *Markdown* 语法来包含 'code' 实例代码
 *
 * @see Markdown
 *
 * @param int        $parameter1 A parameter description.
 * @param \Exception $e          Another parameter description.
 *
 * @\Doctrine\Orm\Mapper\Entity()
 *
 * @return string
 */
function test($parameter1, $e)
{
    ...
}

还可以忽略描述 ( 说明 ) :

<?php 
/**
 * 这是一个摘要
 *
 * @see Markdown
 *
 * @param int        $parameter1 参数说明
 * @param \Exception $parameter2 另一个参数说明
 *
 * @\Doctrine\Orm\Mapper\Entity()
 *
 * @return string
 */
function test($parameter1, $parameter2)
{
}

还可以忽略部分标记 ( 不推荐下面范例中的使用方式,因为缺少有关参数和返回值的信息)

<?php 
/**
 * 这是一个摘要
 */
function test($parameter1, $parameter2)
{
}

块注释可以跨越多行,如下所示

<?php
/** @var \ArrayObject $array */
public $array = null;

一些标记甚至可能具有 「内联 PHP 文档注释」的使用方式,如以下范例所示

<?php
/**
 * @method int MyMagicMethod(string $argument1) {
 *     这是 MyMagicMethod 的简介
 *
 *     @param string $argument1 argument 1 的描述
 *
 *     @return int
 * }
 */
class MyMagicClass
{
    ...
}

6. 继承

一个 「 结构元素 」 的 PHP 文档注释的任何部分都可以从它们实现、扩展、重写的另一个「 结构元素 」的块注释中继承

每种类型的 「结构元素」 的块注释 必须 继承下表列出的部分,如果该部分缺失

每种类型的 「结构元素」 的 PHP 文档注释必须 同时继承一个跟此「结构元素」关联的 特殊的标记子集

如果一个 PHP 文档注释没有特别说明父元素中存在的某部分,比如摘要或者说明,那么该部分总是隐式的从父元素中继承

下面列出的是能从父元素继承块注释的所有元素和继承规则

  1. 类或接口的块注释可以从它们继承或实现的类或接口中继承

  2. 类的属性的块注释可以从类的父类中的同名属性中继承

  3. 类的方法的块注释可以类的父类的同名方法中继承

  4. 类的方法的块注释可以从它们实现的类或接口的同名方法中继承

例如:

假设存在一个方法 \SubClass::myMethod() ,它的所在的类 \SubClass 继承自类 \SuperClass ,并且 \SuperClass 存在一个名字相同的方法 (例如 \SuperClass::myMethod )

根据上面的规则,\SubClass::myMethod() 的注释文档将会继承自 \SuperClass::myMethod. 因此,如果 \SubClass::myMethod() 注释中没有重新定义 @version 标记,那么 \SubClass::myMethod()@version\SuperClass::myMethod 的相同

因为继承是从类层次结构图的根到它的叶子,树的叶子继承的任何东西都 必须 「 冒泡 」到顶部,除非被覆盖

6.1. 使用 @inheritDoc 标记来显示继承

由于继承是隐式的,因此一个「 结构元素 」可能并不需要添加 PHP 文档注释。 但这可能会导致 「 结构元素 」 的注释是不明确的,因为注释是故意被忽略的,或者代码的作者忘记添加文档

为了消除这个歧义,可以使用 @inheritDoc 标记来标识当前元素将继承它的父元素的注释

范例:

<?php
/**
 * 这是简介
 */
class SuperClass
{
}

/**
 * @inheritDoc
 */
class SubClass extends SuperClass
{
}

上面的范例中,SubClass 的注释可以视为和父类元素 ( SuperClass ) 一样,都是 「 这是简介 」

6.2. 使用内联标记 {@inheritDoc} 来扩充说明

如果 「 结构元素 」需要继承父元素的说明并添加自己的描述文本,则 必须 使用 {@inheritDoc} 内联标记

{@inheritDoc} 内联标记用户指示必须在当前位置注入或插入当前元素的父元素的描述

范例

<?php
/**
 * 这是当前元素的简介
 *
 * {@inheritDoc}
 *
 * 此外,此说明可以包含附加的信息,这些信息是对关联的元素的详细信息。
 */

上面的范例中,注释的内容由 {@inheritDoc} 内联标记指示的父元素的描述和后面的正文文本的组成

6.3. 类或接口

除了此规范顶部定义的可继承的描述和标记外,类或接口 必须 继承下列标记

  • @package

    如果下列的废弃的标记存在,类或接口 应该 继承它们

  • @subpackage

    如果父类或接口的 @package 的名字和子类或子接口的@package 的名字名字不同,则 绝对不能 继承 @subpackage

    什么意思呢 ?以 PHP 为例,如果子类的命名空间和父类的不同,那么就不该继承 @subpackage

范例:

<?php
/**
 * @package    Framework
 * @subpackage Controllers
 */
class Framework_ActionController
{
    <...>
}

/**
 * @package My
 */
class My_ActionController extends Framework_ActionController
{
    <...>
}

上面的范例中,My_ActionController 绝对不能 继承子包 Controllers

6.4. 方法

除了此规范顶部定义的可继承的描述和标记外,类或接口中的方法或函数 必须 继承下列标记

6.5. 常量或属性

除了此规范顶部定义的可继承的描述和标记外,类中的常量或属性 必须 继承下列标记

7. 标记 ( 标签 )

除非特别说明,下文提到的每个标记都可以在每个 「 注释块 ( DocBlock ) 」中出现零次或多次

7.1.. @api

@api 标记用于标识关联的 「 结构元素 」 可以被第三方使用

语法

@api

说明

@api 标记用于标识那些公开的可见的 「 结构元素 」。它们会成为库或者框架的公开的 API 组件。

剩下的那些公开的可见的 「 结构元素 」则用在内部结构中且不建议被消费者 ( 使用服务的用户 ) 使用

使用 @api 标记的 「结构元素」的确切含义可能因项目而异。不管怎样,建议 所有带有此标记的「结构元素」在发布后 不得 更改,除非新版本打破了向前的兼容性

范例

<?php
/**
 * 除非发布主要版本,否则不会变更此函数
 *
 * @api
 *
 * @return void
 */
function showVersion()
{
   <...>
}

7.2. @author

@author 标记用于标识关联的 「 结构元素 」 的作者

语法

@author [name] [<email address>]

说明

@author 标记用于标识谁创建了关联的 「 结构元素 」 或谁对它作出了重大的修改。

此标记 可以 包含一个电子邮件地址,如果提供了电子邮件地址,则它 必须 紧跟在作者的名字之后,必须遵循 RFC 2822 规范,用一对尖括号 ( <> ) 括起来

范例

<?php
/**
 * @author 我的名字
 * @author 我的名字 <my.name@example.com>
 */

7.3. @category [已废弃]

@category 标记已经被弃用,不 建议 使用。可以使用文件级别的 @package 标记来代替

@category 用于将包组织到一起。

语法

@category [description]

说明

在原来的事实标准里, @category 标记用于将几个 @package 分组到一个类别中,然后就可以使用这些类别帮助生成 API 文档。

这是必要的,因为原来的标准中, @package 标记被限制不能包含多于一个的结构层次。

随着 @package 的限制被取消了,@category 就 不应该 被使用了

你可以阅读 @package 标记的文档来获得更多相关的内容

同一个 注释块 中,此标记 绝对不可以 出现两次及以上

范例

<?php
/**
 * 文件级别的块注释
 *
 * @category MyCategory
 * @package  MyPackage
 */

7.4. @copyright

@copyright 标记用于标识关联的「 结构元素 」的版权信息

语法

@copyright <description>

说明

@copyright 标记用于标识谁拥有 「 结构元素 」的版权。除非另行说明,此标记指示的版权适用于 关联的 「 结构元素 」 及其所有的子元素

描述的格式由每个项目的编码标准自由决定。 但 建议 添加年份,或版权和相关组织所覆盖的年份

范例

<?php 
/**
 * @copyright 1997-2005 PHP 组
 */

7.5. @deprecated

@deprecated 标记用于标识相关联的 「 结构元素 」 已废弃且会在将来的某个版本中移除

语法

@deprecated [<"Semantic Version">][:<"Semantic Version">] [<description>]

说明

@deprecated 标记用于标识相关联的 「 结构元素 」 会在将来的某个版本中移除,因此它是过时的,且不建议再使用

此标记 可以 最多指定两个版本号来表示一个版本号范围

第一个版本号为 「 起始版本 」 ,表示关联元素被弃用的版本

第二个版本号为 「 结束版本 」, 表示关联元素安排删除的版本,也就是关联元素会在这个版本中删除

如果指定了 「 结束版本 」,那么关联的 「 结构元素 」 可以 不再存在于 「 结束版本 」 中,并且 可能 会在该版本或更高版本中被删除而不必另行通知。但 必须 存在于该版本之前的所有版本中

如果指定了“结束版本”,则相关的“结构元素”可能不再存在于“结束版本”中,并且可能会在该版本或更高版本中被删除,恕不另行通知,但必须存在于所有先前版本中

建议 同时指定 「 起始版本 」和 「 结束版本 」,两个版本 必须 使用冒号 ( : ) 分隔而不是使用空格

「 起始版本 」 可以忽略,但如果忽略,结束版本则 必须 以冒号 ( : ) 开头,也就是说不能省略冒号

此标记还 可以 提供一个附加的描述用于解释关联的元素为什么会被弃用

如果关联的元素被另一个取代,则 建议 在同一个注释块中添加 @see 标记指向新的元素

范例

<?php
/**
 * @deprecated
 *
 * @deprecated 1.0.0:2.0.0
 * @see \New\Recommended::method()
 *
 * @deprecated 1.0.0
 *
 * @deprecated :2.0.0
 *
 * @deprecated 不推荐也请不要在内联代码中使用
 *
 * @deprecated 1.0.0 不推荐也请不要在内联代码中使用
 */

7.6. @example

@example 用于创建一个到外部源代码文件的链接,该源代码文件包含当前的「 结构元素 」 的使用示例。它还有一个内联的使用方式,通过该内联的使用方式,可以将实例文件中的代码与该元素内容一起显示

语法

@example [URI] [<description>]

或内联语法:

{@example [URI] [:<start>..<end>]}

说明

@example 范例标记指向一个包含了用于演示了当前 「 结构元素 」 的目的和用途的范例代码的文件。 对于注释块描述中的多个使用场景,每个 「 结构元素 」 都可以有一个独立的 @example 标记

@example 标记中的 URL 根据以下规则进行解析:

  1. 如果 URL 以协议或者根目录说明符开头,例如 phar://, http://, / or C:\ ,那么应该将该 URL 视为绝对 URL

  2. 如果 URL 是一个相对 URl 并且提供了范例文件的位置,那么就可以解析出相对于给定位置的路径

  3. 如果前面的路径不可读或用户没有提供路径,则应用程序应该尝试在与 @example 标记相关的源文件所在的文件夹中搜索文件夹 「 example 」。 如果找到,则应尝试通过组合 @example 标记中给出的相对路径和找到的文件夹来解析路径

  4. 如果应用程序无法根据上面的规则解析路径 ,则应该检查关联的 「 结构元素 」所在的源文件的项目的根文件夹中是否找到可读文件夹 「 example 」

    项目的根文件夹是应用程序的所有文件共有的最高文件夹

显示注释文档时,如果计划显示范例文件的内容,那么 建议 添加语法高亮来改善阅读的体验

上面的规则也适用于此标记的内联使用方式,内联使用方式还有两个附加的参数,用于限制范例文件中需要显示的代码行,当使用内联方式时,应用程序 必须 显示范例代码

上述规则也适用于内联标签。 内联标签有两个附加参数,用于限制描述中显示的代码行。 因此,消费应用程序必须显示示例代码,以防使用内联示例标签

开始和结束参数可以省略,但省略号应保留,以便提供一个清晰的视觉提示,开始和结束参数的限制,与 PHP 的 substr 函数所指定的规则相同

项目类应用程序仍然可以选择支持此 PSR 已弃用的,旧的标准中使用的有限的格式。 旧格式的语法是:{@example [URI] [] []} 并且不支持 substr 函数的相同的规则。

范例

<?php
/**
 * 统计包含的元素的数量
 * {@example http://example.com/foo-inline.https:2..8}
 *
 * @example http://example.com/foo.phps
 *
 * @return int Indicates the number of items.
 */
function count()
{
    <...>
}

7.7. @global

TODO: 应该继续讨论此标记的定义以及此标记的部分或者全部是否可以使用 @var 来代替

@global 标记用于标识一个全局变量或其使用方法

语法

@global ["Type"] [name]
@global ["Type"] [description]

说明

因为缺少一种标准的用于标识全局变量的方法,我们定义了 @global 标记 可以 用在注释块中标识一个全局变量的定义。

为了兼容旧的 @global 的使用方式,可以在函数之前的块注释中使用另一种替代语法,用于标识全局变量的使用情况。也就是说,@global 有两种用法: 标识一个全局变量的定义和标识一个全局变量的使用

标识一个全局变量定义的语法

一个注释块中,对于每个全局变量,只允许使用 @global 标识一次。一个全局变量的注释块后面 必须 紧跟着相关联的全局变量的定义,而且必须位于任何其它的元素或者文档之前

名字 必须 是源代码中声明的全局变量的确切名称

标识一个全局变量的使用的语法

出现在函数/方法注释块中的 @global 语法可以用来标识相关联的函数/方法中全局变量的使用情况。而且注释中的全局变量名 绝对不能 不能有前导的 $ 符号。如果函数中使用的全局变量使用 @global 标识过,则 可以 省略注释中的 「 类型 ( Type ) 」

范例

TODO: 应该为此标记添加范例

7.8. @internal

@internal 标记用于标识关联的 「 结构元素 」 是当前应用程序或库的内部结构。

它还有一个内联版本,可以在注释的描述文本中插入一段只针对软件开发者适用的简短文本

语法

@internal

或内联语法:

{@internal [description]}}

与其它内联标记相反,此标记的内联版本除了可以包含文本,还可以包含其它内联标记

为了提高可读性并简化解析,标记应该用一个双闭合大括号来终止,而不是单个大括号

说明

@internal 标记可以作为 @api 标记的对应标记使用,用于标识相关联的 「 结构元素 」纯粹用于软件的当前部分的内部工作

从 PHP 文档注释中生成文档时,建议 默认隐藏关联元素,除非用户明确指出应该包含内部元素

@internal 的另一种用途是为注释描述内嵌内部注释或者额外的其它的说明文字。例如,也许你已经这么做了,在生成这个软件源代码的文档时,使用 @internal 保留关键业务或混乱信息的

范例

为计数函数添加一个只适合函数开发者的简短文本

<?php
/**
 * @internal
 *
 * @return int 统计元素的数量
 */
function count()
{
    <...>
}

/**
 * 统计 Foo 中的元素数量
 *
 * {@internal  默认添加一个额外的 Foo 来弥补 Foo 数量的不足  }}
 *
 * @return int 返回元素的个数
 */
function count()
{
    <...>
}

7.9. @license

@license 标记用来标识关联的「 结构元素 」使用那个许可证

语法

@license [<SPDX identifier>|URI] [name]

说明

@license 标记用于向使用者提供提供许可信息,该信息适用于 「 结构元素 」 及其所有的子元素

第一个参数 必须SPDX 开源许可证注册机构 定义的「 SPDX 标识符 」 或 包含完整许可证文本的 URL 链接

第二个参数 可以 是当前许可证的官方名称

建议 仅指定 「 SPDX 标识符 」 并仅将 「 许可 」 标记应用于文件级别的 「 PHP 文档注释 」中,因为单个文件中的多个不同许可能会导致很容易混淆哪个许可证适用

如果要使用多个许可证,每个的许可证 必须 独立使用一个 @license 标记

范例

<?php
/**
 * @license MIT
 *
 * @license GPL-2.0+
 *
 * @license http://www.spdx.org/licenses/MIT MIT License
 */

7.10. @link [已废弃]

此标记已废弃,请使用 @see 标记代替。

@link 标记使用绝对 URI 来标识关联的 「 结构元素 」 和网站之间的自定义关系

语法

@link [URI] [description]

或内联

@link [URI] [description]

说明

@link 标记可以为 「 结构元素 」 或在内联使用时的描述创建到另一个 URI 的关系或者链接

URI 必须 是遵循 RFC 2396 规范的绝对 URI

@link 标记可以有一个附加的用于说明链接内容的描述

范例

<?php
/**
 * @link http://example.com/my/bar Foo 的说明文档
 *
 * @return int 返回元素的个数
 */
function count()
{
    <...>
}

/**
 * 此方法用于计算 Foo 的出现次数
 *
 * 如果没有更多 Foo ({@link http://example.com/my/bar}) ,此函数将添加一个,因为始终必须有一个 Foo 
 * 
 * @return int 元素的个数
 */
function count()
{
    <...>
}

7.11. @method

@method 标记允许一个类知道哪些 '魔术' 方法是可调用的

语法

@method [return type] [name]([type] [parameter], [...]) [description]

说明

@method 标记用于在一个类含有 __call() 方法时定义一些确定的功能

例如,如果一个子类的父类定义了一个用于动态获取或设置预定义属性的 __call() 方法,那么子类就可以通过父类的 __call() 方法调用获取或设置方法。这种情况下,子类可以使用 @method 来标记每一个魔术设置方法或获取方法

@method 标记允许作者通过签名中包含的这些类型交流传递参数的类型和返回值

当标识的方法没有返回值时,可以 省略返回值类型,也就是暗指返回值类型为 void

@method 标记 绝对不可 用于与类或接口无关联的 PHP 文档注释中

范例

<?php 
class Parent
{
    public function __call()
    {
        <...>
    }
}

/**
 * @method string getString()
 * @method void setInteger(int $integer)
 * @method setString(int $integer)
 */
class Child extends Parent
{
    <...>
}

7.12. @package

@package 标记用于分类「 结构元素 」 到子逻辑中

语法

@package [level 1]\[level 2]\[etc.]

说明

@package 标记 可以 看成是命名空间的镜像或补充。 命名空间根据功能细分了 「 结构元素 」 ,而 @package 标记可以提供一个更细粒度的划分,用于按照不同的层级结构分组各个细分

一个项目中,如果每个子部分的逻辑和功能都相等,那么 不建议 使用 @package 标记,因为会带来额外的维护开销

逻辑层次结构中的每个级别都 必须 用反斜杠 ( \ ) 分隔,以便为命名空间所熟悉。层次结构 可能 具有无穷的深度,但 建议 将深度保持在小于或等于六个层次

请注意: @package 会根据它们被定义的位置而应用不同的「 结构元素 」

  1. 如果 @package 出现在 文件级别 的块注释中,那么只有相应文件中的下列的元素处在这个包内:

    • 全局函数 ( global functions )
    • 全局常量 ( global constants )
    • 全局变量 ( global variables )
    • 载入和包含 ( requires and includes )

    译者注:文件级别的不是应该包含文件里的全部信息吗?类和接口都不算了?

  2. 如果 @package 出现在 命名空间级别类级别 的块注释中,那么那个命名空间、类或接口还有它们包含的所有元素都处于这个包中。也就是说,包含了 @package 注释的命名空间中的函数也是在相同的包内

在一个 「 块注释中 」,此标记 绝对不能 出现两次或以上

范例

<?php
/**
 * @package PSR\Documentation\API
 */

7.13. @param

@param 标记用来标识方法或函数中的单个参数

语法

@param ["Type"] [name] [<description>]

说明

@param 标记可以用来标识函数或方法的单个参数的类型和功能。使用时 必须 包含 「 类型 」 以指示参数的类型。另一方面,描述信息是可选的虽然并不推荐这么做。对于诸如选项数组等复杂的结构,建议 使用 「 内联文档注释 」 来标识每一个参数成员

@param 可以 占用多行而不必有明显的分隔标识

建议 每一个函数或方法都添加此标记

此标记标识的参数 绝对不能 在 「 PHP 文档注释 」中出现两次或以上 ,且只能在标识的方法或函数的 「 结构元素 」 中使用

Examples

<?php 
/**
 * 统计给定数组中元素的个数
 *
 * @param mixed[] $items 需要统计的数组
 *
 * @return int 返回数组中元素的个数
 */
function count(array $items)
{
    <...>
}

下面的范例演示了如何使用 「 内联文档注释 」 来标识含有两个元素的选项数组: 'required''label'

<?php 
/**
 * 使用给定的 $options 参数初始化当前类
 *
 * @param array $options {
 *     @var bool   $required 当前元素是否必须的
 *     @var string $label    当前元素的显示名称
 * }
 */
public function __construct(array $options = array())
{
    <...>
}

7.14. @property

@property 标记可以让一个类知道自己有哪些「 魔术 」属性

语法

@property ["Type"] [name] [<description>]

说明

@property 标记用于在一个类包含 __get()__set() 魔术方法的情况下定义一些具体的名字

例如,存在一个子类,它的父类定义了 __get() 方法,那么子类需要的属性可以依赖父类的 __get() 方法来提供,这种情况下,子类可以使用 @property 来标记每一个魔术属性

@property 标记 绝对不能 用在与类或接口的 「 块注释」 无关的地方

范例

<?php
class Parent
{
    public function __get()
    {
        <...>
    }
}

/**
 * @property string $myProperty
 */
class Child extends Parent
{
    <...>
}

7.15. @return

@return 标记可以用来标识函数或方法的返回值类型

语法

@return <"Type"> [description]

说明

@return 标记可以用来标识函数或方法的返回值类型。使用它时,必须 包含一个 「 类型 」 ( 见附录 A ) 来指示返回的是什么。另一方面,如果返回的类型比较复杂,比如关联数组,建议 使用 OPTIONAL 作为描述语句

@return 标记的描述可以占用多行而不用明确的分隔

建议 为每一个函数或方法都添加该标记。但也有一个例外,就像很多项目的编码标准一样:

没有使用 return 返回值的函数和方法

这种情况下,可以 忽略 @return 标记,解释器 必须 将此解释为 @return void

在这种情况下,解释器必须将此解释为@return void提供

此标记 绝对不能 在一个 「 块注释 」 中出现两次或以上, 并且只能用在方法或函数的 「 结构元素 」的 「 块注释 」 中

Examples

<?php
/**
 * @return int 返回数组中元素的个数
 */
function count()
{
    <...>
}

/**
 * @return string|null label 的文本,如果不存在则返回 null 
 */
function getLabel()
{
    <...>
}

7.16. @see

@see 标记为关联的 「 结构元素 」创建指向一个网站或另一个 「 结构元素 」 的参考

语法

@see [URI | "FQSEN"] [<description>]

说明

@see 标记可以用来创建到一个 URI 或其它的 「 结构元素 」的引用

当创建到另一个 「 结构元素 」 的引用时,可以通过追加一个双冒号并提供该元素的名称 (「 FQSEN 」 语法 ) 来引用特定的元素

URI 必须 遵循 RFC 2396 规范

@see 标记 应该 为元素与其目标之间的关系添加一个简短的描述

另外,@see 标记 可以 有一个特有的额外的标记来为这个关系添加更多的定义

范例

<?php
/**
 * @see number_of() :alias:
 * @see MyClass::$items           要统计的 $item 的详细信息
 * @see MyClass::setItems()       为此集合设置元素
 * @see http://example.com/my/bar Foo 的详细信息
 *
 * @return int 返回包含的元素的个数
 */
function count()
{
    <...>
}

7.17. @since

@since 编辑用于标识添加或修改元素的时间,给该元素添加一些 「 版本化 」 的描述

语法

@since [<"Semantic Version">] [<description>]

说明

记录任何元素被引入或修改的 「 版本」

建议 版本号采用语义版本号 ( x.x.x ),并且添加一个附加的描述信息

可以用这些信息生成一组 API 文档,使用者就可以从中查阅特定元素必须使用的应用程序版本

The @since tag SHOULD NOT be used to show the current version of an element, the @version tag MAY be used for that purpose.

@since 标记 绝对不应该 用于标识元素的当前版本,这是 @version 标记应该做的事

Examples

<?php 
/**
 * This is Foo
 * @version 2.1.7 MyApp
 * @since 2.0.0 加入
 */
class Foo
{
    /**
     * 生成一个 bar
     *
     * @since 2.1.5 bar($arg1 = '', $arg2 = null)
     *        加入可选参数 $arg2
     * @since 2.1.0 bar($arg1 = '')
     *        加入可选参数 $arg1
     * @since 2.0.0 bar()
     *        创建一个新的方法 bar()
     */
    public function bar($arg1 = '', $arg2 = null)
    {
        <...>
    }
}

7.18. @subpackage [已废弃]

@subpackage 标记用于将 「 结构元素 」 归类到子逻辑中

语法

@subpackage [name]

说明

@subpackage 标记 可以 看成是命名空间的镜像或补充。 命名空间根据功能细分了 「 结构元素 」 ,而 @subpackage 标记可以提供一个更细粒度的划分,用于按照不同的层级结构分组各个细分

一个项目中,如果每个子部分的逻辑和功能都相等,那么 不建议 使用 @subpackage 标记,因为会带来额外的维护开销

@subpackage 标记 必须 仅用在如 @package 标签的文档中所述的特定系列的 DocBlocks 中

此标记 必须 出现在 @package 标记之后,并且在每个 DocBlock 中 绝对不能 出现两次或以上

范例

<?php
/**
 * @package PSR
 * @subpackage Documentation\API
 */

7.19. @throws

@todo 标记用于标识关联的 「 结构元素 」是否会抛出特定类型的异常

语法

@throws ["Type"] [<description>]

说明

@todo 标记 可以 用于标识关联的 「 结构元素 」会抛出特定类型的错误

提供给此标记的类型 必须 是类 Exception 或其任意子类的一个实例

可以在文档中使用此标记来标识哪些错误 可能 会发生以及在哪些情况下发生。

建议 提供一个简短的引发异常的原因

同时 建议 为每个可能的异常都提供一个 @throw 标记,这样,通过记录和罗列每一个异常生成的详细原因,使用者就知道要检查哪些可能错误

范例

<?php
/**
 * 统计给定数组的元素个数
 *
 * @param mixed[] $array 要统计的数组
 *
 * @throws InvalidArgumentException 如果参数的类型不是 'array' 则抛出此异常
 *
 * @return int 返回数组元素的个数
 */
function count($items)
{
    <...>
}

7.20. @todo

@todo 标记用于标识是否需要在关联的 「 结构元素 」上继续进行任何开发活动

译者注: todo 向来有两个意思,一个是待办,一个是继续。其实,我们更倾向于继续。继续的意思是原本的功能已经能用,可以或需要添加新功能。 但是很坑的是,我见过太多的 @todo ,都是说,这个接口还没完成.. 这明显违背了今日事今日毕 --- 语飞

语法

@todo [description]

说明

@todo 标记用于标识围绕相关的 「 结构元素 」 的活动仍然必须进行。

每个 @todo 标签 必须 附有简短的描述,以传达原作者的意图。描述可以使用问题编号 ( issue )

范例

<?php
/**
 * 统计数组中的元素个数
 *
 * @todo 添加一个数组参数
 *
 * @return int 返回数组中元素的数量
 */
function count()
{
    <...>
}

7.21. @uses

标识当前的 「 结构元素 」是否使用了作为目标提供的另一「 结构元素 」或项目文件

语法

@uses [file | "FQSEN"] [<description>]

说明

@uses 标记用于标识相关的 「 结构元素 」 的任何部分是否使用或调用了当前项目中的另一个文件或 「 结构元素 」

声明对另一个「 结构元素 」的引用时,可以通过追加一个双冒号并提供该元素的名称 ( 也称为 「 FQSEN 」 ) 来引用特定的元素

项目的所有文件都可以被这个标记应用,可以用来标识控制器和模板文件 ( 视图 ) 之间的关系

包含在这个项目中的文件可以被这个标签引用。例如,可以使用 @uses 标识控制器和模板文件(视图)之间的关系。

@uses 标记 绝对不能 用来标识与当前系统之外的元素或 URL 的关系。为了标识与系统外部元素的关系,可以使用 @see 标记

消费此标记的应用程序 ( 如生成器 ),推荐 在目标元素上添加 @used-by 标记,不仅提供了双向体验还允许进行静态分析

范例

<?php
/**
 * @uses \SimpleXMLElement::__construct()
 */
function initializeXml()
{
    <...>
}
<?php
/**
 * @uses MyView.php
 */
function executeMyView()
{
    <...>
}

7.22. @var

@var 标记用来标识以下 「 结构元素 」 的 「 类型 」

  • 常量,包括类常量和全局常量
  • 属性
  • 变量,包括全局变量和局部变量

语法

@var ["Type"] [element_name] [<description>]

说明

@var 标记用于标识常量、属性或变量的值的类型

他@var标签定义哪些类型的数据由一个Constant,Property或Variable的值表示。

每个类型不明确或未知的常量或属性定义或变量前应该 应该 有一个包含 @var 标记的块注释。任何其它变量则 可以 选择包含 @var 标记的块注释开头

@var 标记 必须 包含它所标识的元素的名称。但也有一个例外的情况:如果属性声明中只有一个属性,那么 可以 忽略属性名

@var 关键字常用在定义一系列常量或属性的复合语句中,这种复合语句只能有一个块注释,却有多个项目需要被注释

范例

<?php 
/** @var int $int 这是一个计数器 */
$int = 0;

// 此处不应由块注释
$int++;

或者

<?php
class Foo
{
  /** @var string|null 此处应有描述 */
  protected $description = null;

  public function setDescription($description)
  {
      // 此处不应有块描述
      $this->description = $description;
  }
}

另一个例子是明确地在 foreach 标识变量

许多 IDE 使用这些信息来帮助完成自动提示

<?php 

/** @var \Sqlite3 $sqlite */
foreach($connections as $sqlite) {
    // 此处不应有块注释
    $sqlite->open('/my/database/path');
    <...>
}

甚至可以用在复合语句中

<?php
class Foo
{
  protected
      /**
       * @var string 此处应有一个注释
       */
      $name,
      /**
       * @var string 此处应有一个注释
       */
      $description;

}

或常量

<?php
class Foo
{
  const
      /**
       * @var string 此处应有一个注释
       */
      MY_CONST1 = "1",
      /**
       * @var string 此处应有一个注释
       */
      MY_CONST2 = "2";

}

7.23. @version

@version 标记用于标识某个元素的 「 版本控制 」

语法

@version ["Semantic Version"] [<description>]

说明

标记任何元素的当前 「 版本 」

这些版本信息可以用于生成一组 API 文档,方便使用者根据版本来了解特定的元素

建议 版本号采用 语义版本标准 2.0 中规范的语义版本号

同时也支持版本控制系统中的版本向量,但 必须 遵循以下形式

name-of-vcs: $vector$

可以 添加一简短的描述用于额外传递指定版本的特定信息

@version 标记 不应该 用于显示元素的最后修改版本或创建版本,@since 标记才是

范例

<?php
/**
 * Foo 类文件
 * @version 2.1.7 我的应用
 *          (this string denotes the application's overall version number)
 * @version @package_version@
 *          ( PEAR 替换关键字,会在安装的时候展开为安装的版本)
 * @version $Id$
 *          ( CVS 关键字,提交后展开,用于显示 CVS 文件修订号)
 */

/**
 * Foo 类
 */
class Foo
{
  <...>
}

附录 A. 类型

ABNF

「 type 」 类型的 ABNF 定义如下:

type-expression  = type *("|" type)
type             = class-name / keyword / array
array            = (type / array-expression) "[]" / generic
array-expression = "(" type-expression ")"
generic          = collection-type "<" [type-expression "," *SP] type-expression ">"
collection-type  = class-name / "array"
class-name       = ["\"] label *("\" label)
label            = (ALPHA / %x7F-FF) *(ALPHA / DIGIT / %x7F-FF)
keyword          = "array" / "bool" / "callable" / "false" / "float" / "int" / "mixed" / "null" / "object" /
keyword          = "resource" / "self" / "static" / "string" / "true" / "void" / "$this"

详细说明

当使用 「 type 」 时,用户可以认为其类型是下列所述的一个值或一组值

当 「 type 」 由多个类型组成时,它们必须使用竖线符 ( | ) 分隔。任何支持本规范的解释器都必须注意到这一点,并在执行前拆分 「 type 」

例如:@return int|null

数组

「 type 」 关键字所应用的元素可以是一个数组。

数组类型必须是下列定义的格式之一:

  1. 未指定。没有定义给定的数组的内容,例如: @return array

  2. 指定包含单个类型。对于给定数组中的每个值,只有一种类型,Type 定义会告诉调用者每个值的类型

    例如: @return int[]

    注意: 「 mixed 」 也是单一类型,这个关键字用于表示数组的每个值可以是任意类型

  3. 指定可以是多个类型中的一个,也就是说数组值的类型可以是任何给定的类型,Type 定义会告诉调用者每个值的类型,例如: @return (int|string)[]

  4. 指定使用泛型注释。请继续阅读下一节的 「 集合 」来获取更多关于此注释的描述

集合

「 type 」 关键字所应用的元素也可以是一个 集合 类型

集合类型是一个包含多个键/值对的类,可以使用 Java 泛型派生出来的格式来表示集合,也就是使用泛型风格的注释

泛型风格的注释 要求 指定类名或者数组关键字,后跟使用尖括号括起来的值的类型

例如:下面的注释表示一个元素返回仅包含一系列字符串的 ArrayObject 类的实例

@return \ArrayObject<string>

集合中的值的类型 可以 是另一个数组或者结合

@return \ArrayObject<\ArrayObject<int>>

集合 可以 通过在尖括号之内,在表示值类型的标识符之前,添加可选的额外的类型来定义所述集合的键的类型。键和值应该使用逗号分隔

例如:声明一个包含整数键和字符串值的键值对 ArrayObject 集合

@return \ArrayObject<int, string>

键或值 可以 由几种不同的类型组成,可以使用在尖角括号之间用垂直条形符号 ( | ) 分隔每个单独类型

@return \ArrayObject<string|bool>

合法的类名

此规范中提到的所有合法的类名,可以是一个全限定类名 ( FQCN ),也可以是命名空间下的一个本地类名

因为 as 关键词可以将类名定义为别名,本地类名统称类名或者别名

类类型所应用的元素可以是该类的实例,也可以是该类的子类的实例

由于上述特性,建议 应用程序收集和整理这些信息,显示每个类的子类的列表,这样用户就能明白就能哪些类可以是被接受的类型

关键词

关键字定义了此种类型的用途

虽然并非每个元素都由一个类决定,但仍然值得分类,以帮助开发人员理解 DocBlock 范围内的代码

注意:

此规范提到的大多数关键词都可以用作 PHP 中的类名,很难区分是一个类还是一个关键词。 因此,关键词 必须 是小写的,因为大多数类名以大写字母开头,并且 不应该 在你的代码中使用这些关键词命名一个类

有很多的理由不使用这些关键词命名一个类,但这超出了本规范的范围

此 PSR 认可以下关键词

  1. 「 string 」

    此类型所应用的元素是一串二进制字符,也就是字符串

  2. 「 int 」

    此类型所应用的元素是全部都是数字或整型

  3. 「 bool 」

    此类型所应用的元素是一个 boolean 类型,只有 TRUEFALSE 两个值

  4. 「 float 」

    此类型所应用的元素是一个符点类型

  5. 「 object 」

    此类型所应用的元素可以是任何类的一个实例

  6. 「 mixed 」

    此类型所应用的元素是可以是这里提到的任意类型,从另一方面说,就是只有在运行时才知道是什么类型

  7. 「 array 」

    此类型所应用的元素是一个数组

  8. 「 resource 」

    此类型所应用的元素是一个在 PHP 中的 Resource 资源类型 中定义的资源

  9. 「 void 」

    这种类型通常出现在定义方法或函数的返回值类型中

    这种类型表示的元素不包含值,用户不应该依赖任何检索值

    范例:

    /**
     * @return void
     */
    function outputHello()
    {
        echo 'Hello world';
    }
    

    上面的范例中,因为没有 return 语句,所以返回值是不明确的

    范例 2:

    /**
     * @param bool $hi 如果为 true 则输出 'Hello world' 
     *
     * @return void
     */
    function outputHello($quiet)
    {
        if ($quiet} {
            return;
        }
        echo 'Hello world';
    }
    

    在这个范例中,函数包含一个没有给定返回值的语句。因为没有指定实际的返回值,所以也可以使用 void 类型

  10. 「 null 」

    此类型所应用的元素的值是 NULL ,或者从技术上来说,不存在的值

    与 [ void ] 相比,最大的不同之处是:任何环境任何时间,只要所描述的元素可以明确包含 NULL 值 ,都会使用此类型

    范例 1:

    /**
     * @return null
     */
    function foo()
    {
        echo 'Hello world';
        return null;
    }
    

    这种类型通常与另一种类型结合使用,用来表示可能不会返回任何内容

    范例 2:

    /**
     * @param bool $create_new 如果为 true 则返回一个 stdClass 的实例
     *
     * @return stdClass|null
     */
    function foo($create_new)
    {
        if ($create_new) {
            return new stdClass();
        }
        return null;
    }
    
  11. 「 callable 」

    此类型所应用的元素是一个指向函数调用的指针,可以是 PHP 手册 伪类型可调用 中的任何可调用的类型

  12. 「 false 」 或 「 true 」

    此类型所应用的元素是一个 boolean 布尔类型,只有 TRUEFALSE 两个值

  13. 「 self 」

    此类型所应用的元素与包含文档元素的类相同

    范例:

    假设 cA 的一个方法, 如果在 c 的注释块中指示它的返回值是 self, 那么方法 c 返回的就是类 A 的实例

    当涉及继承时,非常容易被混淆

    范例 ( 前面的范例仍然适用 ) :

    B 继承自类 A 且没有重写方法 c,因此可以从 B 中调用 c 方法

    这种情况下,可能会出现歧义,因为 self 可以被解释为类 A 或类 B

    这种情况下,self 必须 解释为包含 self 类型所在块注释的类的实例

    上面的范例中,self 必须 总是引用类 A,因为 c 是在 A 中被定义的

    由于上述特性,建议 应用程序收集和整理这些信息,显示每个类的子类的列表,这样用户就明白就能哪些类可以是被接受的类型

  14. 「 static 」

    该类型所应用的元素与包含文档元素的类相同,子类中的类型则是该子类的类型而不是原始类

    此关键字的行为类似 PHP 中的 延时静态绑定 ( 不是静态方法,属性或变量修饰符 )

  15. 「 $this 」

    这种类型是一个更严格的 「 static 」

    此类型所应用的元素与给定上下文中的当前类相同,返回的实例不仅必须是相同的类,且必须是相同的实例

    这种类型通常作为实现了 链式调用接口 设计模式的方法的返回值

PHP 标准规范

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.