当数组是映射(又称哈希表)时,如何在PHPDoc中记录数组的类型


How to document the types of arrays in PHPDoc, when those arrays are maps (aka hash tables)?

PHPDoc是JavaDoc对PHP的改编。通过注释中的正确语法,您可以使用它来记录事物的类型。IDE之类的工具可以使用这些元数据。

下面是一个使用字符串"简单"数组的示例。

/**
  * @param string[] $strings  This parameter is blah blah blah.
  */
public function foo($strings) {
    // ...
}

但是PHP"数组"也可以用作映射(也就是哈希表,也就是字典)(http://php.net/manual/en/language.types.array.php):

$array = array(
    "foo" => "bar",
    "bar" => "foo",
);

现在假设我们修改函数foo,使其采用类似上面的$array的内容:字符串=>字符串的数组。

/**
  * @param ??????? entries  This parameter is blah blah blah.
  */
public function foo($entries) {
    // ...
}

应如何在PHPDoc中表示$entries的类型?

http://www.phpdoc.org/docs/latest/guides/types.html#arrays甚至没有提到语言中存在这样一个结构。

您至少可以记录$entries应该是string的数组:

/**
 * @param string[] entries
 */
public function foo($entries) 
{
    // ...
}

但是,您也可以修改方法签名以添加array:的类型声明

/**
 * @param string[] entries
 */
public function foo(array $entries) 
{
    // ...
}

此外,您可以通过编写自己的断言或使用(例如)beberlei/assert:来防止传入无效值

use Assert'Assertion;
/**
 * @param string[] entries
 * 
 * @throws InvalidArgumentException
 */
public function foo(array $entries) 
{
    Assertion::allString($entries);
    Assertion::allString(array_keys($entries));
    // ...
}

这对docblock没有太大帮助,但它在代码本身中记录了与参数有关的需求。

我建议避免在PHP代码中使用数组作为数据结构。具有明确定义属性的类更适合。

作为一种变通方法,您可以使用存根类来描述数组结构,不过您需要将数组强制转换为对象才能从中受益。

$array = array(
    "foo" => "bar",
    "bar" => "foo",
);
/**
 * @property $foo
 * @property $bar
 */
class MyStub {}
/** @var MyStub $object */
$object = (object)$array;
// IDE completion and inspections are now available
$object->foo .= $object->bar;
// optional casting back to array
$array = (array)$object;