4

当数组元素是方法的参数时,记录数组元素的最佳方法是什么?例如,使用 PHPDoc 标头,我可能有类似的东西:

@param array $data

这并没有告诉我数组中哪些元素是必需的,哪些是可选元素。我想这应该在方法的解释中。就像是:

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

3 回答 3

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

这个使用学说的例子和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;
于 2013-07-22T08:59:11.007 回答
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 )
{
    //...
}

3 个参数几乎可以通过,但您应该开始寻找重构它的方法,就像我的第一个建议一样。4 个参数一般都被认为是乱七八糟的,你重构它。

于 2013-07-22T08:50:44.587 回答
2

如果您有一个对每个成员都有约束的复杂数组,我不会使用匿名数组,而是使用定义明确的对象。使用数组,您永远无法确定它包含什么,这有点像在 Java 中传递“对象”,您很少会认为这是一个好的选择。

但是,当您的数组包含此处解释的某种类型的对象时,可能会有一点提示,但这并不是您问题的一个很好的答案。

如果您确实需要将参数作为数组,您可以按照您在方法描述中提出的方式记录它;但是,如果您使用对象作为参数,您将在现代 IDE(IntelliSense 等)中获得额外的支持。

编辑:我的意思是,对我来说,问题是“为什么我要使用匿名数组而不是自定义类型” - 除了简单性(如果您维护和扩展代码,这将适得其反),我想不出一个原因,尤其是与使用用户定义类型(自我记录的代码、可见的约束并通过标准方法显式等)获得的收益相比。

如果您只需要转储数据,您可能希望使用一个简单的数组,但由于您已经在考虑可选和必需的键,因此需要用户定义的类型。

EDIT2:关于您是否已经将数组作为源的评论:我不确定您是否需要将其作为数组传递或在收到数组后立即执行“映射”操作(例如 $_POST 或从某些第三方库或 PHP 内部函数等返回值)。

我想有人可能会争辩说,解释视图生成的数据(例如 POST 数据的 HTML 表单)不是模型的业务,而是控制器对输入做出相应反应并在适当状态下传输模型的责任。我的意思是,如果你收到一个数组作为 $_POST,你可以做这样的事情:

$customer = new Customer();
$customer->setId($_POST['id']);
$customer->setName($_POST['name']);
$customer->setTown($_POST['town']);

并在您访问 $customer 时立即处理错误,例如,如果未设置名称(即为$_POST['name']空等)则抛出异常。这样,您可以使用源数组来调用对象上的设置器,而不是例如将数组传递给工厂Customer::buildByHttpPostData(array $data),从而委派视图细节的知识(HTML 输入标签的名称等)。

底线是,没有“标准”方式来声明必需或可选的数组键,当然您可以在方法描述中描述这些约束,但也许您可以通过使用 PHPDoc 对 setter 或 getter 的注释等受支持的方式来规避这一点。

当然,可能有更好的方法来解决这个问题,也许有人想出了一个更好的答案来处理它。

于 2013-07-22T08:51:42.397 回答