Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP参数顺序问题:错误还是勘误?_Php - Fatal编程技术网

PHP参数顺序问题:错误还是勘误?

PHP参数顺序问题:错误还是勘误?,php,Php,我是PHP新手,在我的PHP版本(5.4.13)中遇到了一些奇怪的行为,这些行为可能是错误,也可能不是错误。我发现函数参数的顺序在函数声明中很重要。以下示例中的示例: class Book { function __construct() { } public static function withDescriptors($isNotOrmObject, $isArray, $isScalar) { $instance = new self(); // initial

我是PHP新手,在我的PHP版本(5.4.13)中遇到了一些奇怪的行为,这些行为可能是错误,也可能不是错误。我发现函数参数的顺序在函数声明中很重要。以下示例中的示例:

class Book {
  function __construct() { }

  public static function withDescriptors($isNotOrmObject, $isArray, $isScalar) {
    $instance = new self();
    // initialization here
    return $instance;
  }
}
调用WithDescriptor会导致“数组到字符串转换”异常。调用WithDescriptor时会引发错误,即WithDescriptor从未实际执行。但是,使用数组参数切换对象参数可以解决此问题。即

public static function withDescriptors($isArray, $isNotOrmObject, $isScalar){ ....
这是PHP的已知特征还是一个bug

更明确地说:

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);

有效很好。唯一的区别是参数序列,“此处初始化”代码是相同的。

一般来说,函数参数的顺序很重要。
只有当参数类型相同或函数实现了get opt long之类的功能时,才会出现这种情况

通常,函数参数中的顺序很重要。
只有当参数类型相同或函数实现了get opt long之类的功能时,才会出现这种情况

在第二个示例中没有得到警告的原因是,作为第二个参数传递的
对象正在实现一个magic
\uu toString()
方法。PHP不是一种强类型语言,但较新版本的类型暗示功能有限

说明警告

function saySomething($shouldBeAString)
{
    echo $shouldBeAString
}

saySomething(array('hello'));
输出 “数组”

以及一个警告
数组到字符串的转换

class Foo {
   public function __toString() {
       return 'Hi I am Foo';
   }
}

$bar = new Foo();

 saySomething($bar);
将输出

'Hi I am Foo'
毫无预兆

如前所述,PHP提供有限的类型暗示。您可以指定所需的“类/对象类型”和“数组”作为接受的参数,但不能指定标量类型,如“字符串”、“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);
        }
    }
}

注意:上面的代码是“假”代码,只是为了说明这个想法

在第二个示例中没有得到警告的原因是,作为第二个参数传递的
对象正在实现一个magic
\uu toString()
方法。PHP不是一种强类型语言,但较新版本的类型暗示功能有限

说明警告

function saySomething($shouldBeAString)
{
    echo $shouldBeAString
}

saySomething(array('hello'));
输出 “数组”

以及一个警告
数组到字符串的转换

class Foo {
   public function __toString() {
       return 'Hi I am Foo';
   }
}

$bar = new Foo();

 saySomething($bar);
将输出

'Hi I am Foo'
毫无预兆

如前所述,PHP提供有限的类型暗示。您可以指定所需的“类/对象类型”和“数组”作为接受的参数,但不能指定标量类型,如“字符串”、“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);
        }
    }
}

注意:上面的代码是“假”代码,只是为了说明这个想法

这里有一些很好的答案,但这种特殊情况是由PHP解释器中的错误引起的。

这里有一些很好的答案,但这种特殊情况是由PHP解释器中的错误引起的。

当然这很重要。在任何语言中,它都很重要,即使是严格键入的语言。对于3个标量参数,您希望它的行为如何?它必须知道后面的参数是什么。对于PHP来说,你看起来并不像代码中的“某处”那样是“新的”,PHP希望/将数组参数视为字符串。可能,您正在使用的对象能够通过“魔术”方法转换为字符串。因此,错误不会出现。但是,在没有实际来源的情况下,不确定是什么导致了问题code@thaJeztah-NotORM可能有一个_toString()方法,但我仍然不确定它在参数列表中的位置有什么关系。“我知道的强类型语言(C++,Java)不关心参数在函数定义中的顺序。”-这里一定有很大的误会。当您调用声明中的函数时,这两种语言都以相同的顺序接受参数。当然这很重要。在任何语言中,它都很重要,即使是严格键入的语言。对于3个标量参数,您希望它的行为如何?它必须知道后面的参数是什么。对于PHP来说,你看起来并不像代码中的“某处”那样是“新的”,PHP希望/将数组参数视为字符串。可能,您正在使用的对象能够通过“魔术”方法转换为字符串。因此,错误不会出现。但是,在没有实际来源的情况下,不确定是什么导致了问题code@thaJeztah-NotORM可能有一个_toString()方法,但我仍然不确定它在参数列表中的位置有什么关系。“我知道的强类型语言(C++,Java)不关心参数在函数定义中的顺序。”-这里一定有很大的误会。两个