0

我是 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 从未真正执行过。但是,用数组参数切换对象参数解决了这个问题。IE

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

很好用唯一的区别是参数序列,“这里的初始化”代码是相同的。

4

3 回答 3

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

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

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

于 2013-04-07T11:47:19.897 回答
1

一般来说,顺序在函数参数中很重要。唯一不是这样的情况是,当参数类型相同或者你的函数实现了 get opt long 之类的东西时。

于 2013-04-07T10:53:30.703 回答
-1

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

于 2013-05-25T15:33:46.637 回答