我最近一直在做很多Objective-C编程,现在我要回到PHP,我必须诚实地说,我想念命名参数(一开始我讨厌它们,现在我喜欢它们,想想看)。
无论如何,在PHP中,我有时看到人们将数组传递给函数作为一种命名参数的伪方法(额外的好处是不必担心顺序),但有时这会使函数编写过于复杂。此外,有时我想用命名参数调用函数,但有时不这样做更容易更快。
有人这样做吗?
function calculateArea( $width, $height ) {
// do calculations here...
}
// and then call the function like so:
calculateArea( $width = 10, $height = 5 );
它似乎工作得很好,至少在我的PHP版本中,我想知道其他人是否也使用这种技术作为命名参数的解决方案。我也想知道是否有人知道一些令人信服的理由,为什么我不应该这样做。
谢谢!
更新:
感谢大家的快速回复。为了让事情更清楚,我只想说,我理解传递关联数组在大多数情况下是一个更好的选择,但有时你正在使用你已经写好的函数,你不想改变它们在你代码的每一部分中的调用方式。另外,有时候你正在使用一个辅助框架,你无法控制函数是如何编写的。
如果我看我一年前写的代码,我看到:echo $zc->expand('Foo', 'Bar', 10, 1, 0, null, null, array('class'=>'code'), false);
,这不是很有帮助。
所以,换句话说,我的问题基本上是这样的:
有时通过赋值传递参数给函数更容易阅读。这样做的缺点是什么?它是否适用于所有版本的PHP?
我认为这是一个坏主意,从你没有任何安全的角度来看,如果你得到错误的顺序。使用地图是一种更安全的模拟方式。在局部作用域中设置这些变量的值也会产生副作用,这可能是个问题,也可能不是。
calculateArea( $height = 5, $width = 10 ); # oops!
function calculateArea( $width, $height ) {
// do calculations here...
}
对于数组(map),它们的顺序是无关紧要的。
calculateArea( array( 'height' => 5, 'width' => 10 ) ) # yea!
function calculateArea( $dimensions ) {
$width = $dimensions['width'];
$height = $dimensions['height'];
}
使用calculateArea( $width = 10, $height = 5 )
时,您不需要像在Python等其他语言中那样通过名称指定参数。
函数调用中的$width = 10
和$height = 5
只是两个变量赋值表达式。
这仍然像预期的那样工作的原因是赋值表达式不仅赋值,而且还返回赋值:
赋值表达式的值就是赋值。即"
$a = 3
"的值为3。
因此,有效地calculateArea( $width = 10, $height = 5 )
调用calculateArea
的参数与calculateArea(10, 5)
相同,但它也分配了两个变量:
calculateArea( $width = 10, $height = 5 );
var_dump($width); // int(10)
var_dump($height); // int(5)
不应该在函数调用中使用变量赋值,因为这可能会导致意想不到的结果。calculateArea($a = 10, $b = 5)
也可以。函数调用完成后,$a === 10, $b === 5。如果这些变量在函数调用之前有不同的值,这些值将被覆盖。
你可以用以下任何一种方式调用你的函数:
calculateArea (10, 5);
或:
calculateArea(宽度、高度美元);
或:
calculateArea (xvar美元,5);
但是在函数调用中赋值通常是不好的做法。这在技术上是正确的,但使代码难以阅读。而不是这样做:
计算区域($width = 10, $height = 5);
这样做:
$width = 10;
$height = 5;
calculateArea( $width, $height );
或:
$width = 10;
$height = 5;
calculateArea( 10, 5 );
它们都具有相同的效果,但是在函数外声明变量可以明确它们的作用域。
现在您知道了,PHP没有这个特性。但我想说,传递数组也是一种不好的方式。在这种情况下,你必须在内存中保存(或者在phddoc注释中最好的情况下),哪些键可以在数组中使用,你不能设置'默认值',你可以很容易地在数组的键名中输入错误。
所以我更喜欢在这种情况下使用对象(因为PHP也没有"结构")。在object中,您可以设置默认值,您可以在函数声明中设置所需对象的类型,并且在IDE中,您可以获得对象字段名称的代码完整。为例:
class DimensionsParams
{
public $width = 5;
public $height;
}
function calculateArea(DimensionsParams $params)
{
// do calculations here...
return $params->height*$params->width;
}
当然,它不是每个函数的最佳选择,但它是"命名参数"的最佳变体(在我看来)。