我是PHP的新手,遇到了一些奇怪的行为,可能是也可能不是我的PHP版本中的错误(5.4.13)。我发现了函数声明中函数参数序列很重要的情况。在以下示例中:
class Book {
function __construct() { }
public static function withDescriptors($isNotOrmObject, $isArray, $isScalar) {
$instance = new self();
// initialization here
return $instance;
}
}
调用withDescriptors会导致'数组转换为字符串转换'异常。调用withDescriptors时会抛出错误,即。 withDescriptors永远不会被执行。但是,使用数组参数切换object参数可以解决问题。即
public static function withDescriptors($isArray, $isNotOrmObject, $isScalar){ ....
这是PHP的已知特性还是这个错误?
更明确地说:
class Book {
function __construct() { }
public static function withDescriptors($isNotOrmObject, $isArray, $isScalar) {
$instance = new self();
// initialization here
return $instance;
}
}
$book = Book::withDescriptors($isNotORMobject, $isArray, $isScalar);
失败和
class Book {
function __construct() { }
public static function withDescriptors($isArray, $isNotORMobject, $isScalar) {
$instance = new self();
// initialization here
return $instance;
}
}
$book = Book::withDescriptors($isArray, $isNotORMobject, $isScalar);
工作很棒。 ONLY 区别在于参数序列,“此处初始化”代码完全相同。
答案 0 :(得分:3)
您在第二个示例中未获得警告的原因是,您传递的Object
是第二个参数正在实施魔法__toString()
方法。 PHP不是强类型语言,但更新版本具有类型提示的有限功能。
说明警告;
function saySomething($shouldBeAString)
{
echo $shouldBeAString
}
saySomething(array('hello'));
输出 '阵列'
并发出警告array to string conversion
class Foo {
public function __toString() {
return 'Hi I am Foo';
}
}
$bar = new Foo();
saySomething($bar);
将输出
'Hi I am Foo'
没有警告
如上所述,PHP提供了有限的类型提示。您可以将所需的“类/对象类型”和“数组”指定为可接受的参数,但不是标量类型,如“string”,“int”,“bool”等。
function (array $myarray) {
// will only accept arrays
// or something that implements array-access
}
function (Foo $var) {
// Will only accept 'Foo' objects
}
其他一些语言允许多次定义相同的方法/函数,但具有不同的签名(其他参数类型)。 PHP没有明确支持这一点。
例如,在其他语言中,这是允许的:
function doSomething(string $arg1) { ......}
function doSomething(array $arg1) { .... }
function doSomething(string $arg1, string $arg2) { ... }
在这些语言中,根据参数的类型和数量,将执行变体1,2或3。 PHP不支持这一点,因为它要求函数/方法具有唯一名称。因此,PHP会抱怨函数doSomething()
已经定义。
但是,您可以通过多种方式在PHP中创建类似的东西;
// rename the functions/methods so that they have a unique name
function _doSomething1(string $arg1) { ......}
function _doSomething2(array $arg1) { .... }
function _doSomething3(string $arg1, string $arg2) { ... }
// create the 'wrapper' function *without arguments specified*
function doSomething() {
// determin which variant should be executed
$numargs = func_num_args();
$args = func_get_args();
if ($numargs == 2) {
// 2 arguments -> variant 3
return call_user_func_array('_doSomething3', $args);
} else if {$numargs == 1) {
if (is_array($args[0]) {
// first argument is an array
return call_user_func_array('_doSomething2', $args);
} else {
return call_user_func_array('_doSomething1', $args);
}
}
}
注意:上面的代码是 '假'代码 ,只是为了说明这个想法!
答案 1 :(得分:1)
通常,订单在函数参数中很重要。 它不是唯一的时候是参数是相同的类型,或者你的函数实现了像get opt long这样的东西。
答案 2 :(得分:-1)
这里有一些很好的答案,但这种特殊情况是由PHP解释器中的一个错误引起的。