PHP: 如何在方法参数中记录数组文档

4

当数组作为方法的参数时,最好的文档化方法是什么?例如,使用PHPDoc标题,我可能会写出以下内容:

@param array $data

这并没有告诉我数组中哪些元素是必填的,哪些元素是可选的。我想这应该在方法的解释中说明。例如:

array: $data
============ 
int     $id      Required 
name    $string  Required 
town    $string  Optional

4
在这种情况下,您是否希望使用一个经过良好记录和定义明确的对象,而不是匿名数组呢?在该对象中,您可以记录所有方法并指示它们是否必需。 - stef77
3个回答

4
/**
 * @param array $data
 * 
 * @var $data[id] int, required
 * @var $data[name] string, required
 * @var $data[town] string, required
 */

这是一个使用doctrine和zf2的示例:

/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
* @Form\Attributes({"type":"hidden"})
*/
protected $id;

/**
* @ORM\Column(type="string")
* @Form\Type("Zend\Form\Element\Text")
* @Form\Required({"required":"true"})
* @Form\Filter({"name":"StripTags"})
* @Form\Filter({"name":"StringTrim"})
* @Form\Validator({"name":"StringLength", "options":{"min":"5"}})
* @Form\Options({"label":"First name"})
*/
protected $firstName;

2

回答这个问题没有正式的方法,尝试使用你认为最直观的方式。我做类似的事情:

/**
 * @param array $data [ int $id, string $name, string $town ]
 */

然而我不会使用这种符号来表示参数,而是用来表示返回值。在你的情况下,我会将方法参数提取到一个对象中,然后将该对象传递给方法:

/**
 * @param User $user
 */
public function myMethod( User $user )
{ 
    //... 
}

这是因为User对象将其属性公开为API,以便其他开发人员使用,自我记录代码!

另一种方法是将数组元素分离成参数,如下所示:

/**
 * @param int $id
 * @param string $name
 * @param string $town
 */
public function myMethod( $id, $name, $town )
{
    //...
}

三个参数勉强可以接受,但你应该开始寻找重构的方法,就像我的第一个建议。四个参数普遍被认为很混乱,需要进行重构。


2
如果您有一个带有每个成员的约束条件的复杂数组,我不会使用匿名数组,而是使用一个明确定义的对象。使用数组时,您永远无法确定它所持有的内容,这有点像在Java中传递“Object”,您很少会考虑这是一个好选择。
然而,如果您的数组包含某种类型的对象,可以进行一些提示,如此处所解释的那样,但这并不是对您的问题的真正好答案。
如果您真的需要将参数作为数组,请按照方法描述中提出的方式进行文档化;但是,如果您使用对象作为参数,现代IDE(IntelliSense等)将为您提供额外的支持。
编辑:我的意思是,对我来说,问题是“为什么要使用匿名数组而不是自定义类型”,除了简单性(这将在以后维护和扩展代码时产生技术债务),我想不到任何原因,特别是与使用用户定义类型(自记录代码,通过标准方法可见和明确的约束等)相比。
如果您只需要数据转储,您可能希望选择一个简单的数组,但是由于您已经考虑了可选和必需的键,这就需要一个用户定义的类型。
编辑2:关于您的评论,如果您已经有一个数组作为源,则不确定是否需要将其传递为数组或在接收数组时执行“映射”操作(例如作为$_POST或从某些第三方库或PHP内部函数返回值等)。
我想人们可以争论模型并不涉及解释视图生成的数据(例如通过POST数据的HTML表单),而是控制器负责根据输入做出相应反应并将模型传输到适当的状态。我的意思是,如果您收到例如$_POST的数组,您可以像这样做:
$customer = new Customer();
$customer->setId($_POST['id']);
$customer->setName($_POST['name']);
$customer->setTown($_POST['town']);

“在访问$customer时,尽快处理错误,例如如果名称未设置(即$_POST ['name'] 为空等),则抛出异常。这样,您可以使用源数组调用对象的setter,而不是将数组传递给工厂(如Customer :: buildByHttpPostData(array $data)),从而委托视图细节的知识(HTML输入标记的名称等)。 总之,没有“标准”方法来声明必需或可选数组键,当然您可以在方法描述中描述这些限制,但也许您可以通过保持支持的方法(如setter或getter上的PHPDoc注释)来规避这一点。
当然,可能有更好的方法来解决问题,也许有人会提出更好的答案来处理它。”

谢谢stef77,但如果源是一个数组,例如$_POST呢?在某个时候,数组需要加载到一个对象中,因此在那个时候需要对其进行文档化。 - DatsunBing
请查看我修改后的答案,试图解决你的问题... - stef77

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接