PHP类型提示:支持数组,对象不是?

时间:2009-10-10 11:19:01

标签: php oop

我是否遗漏了某些东西,或者在PHP 5.x中确实不支持通用对象类型提示?

我发现支持提示数组非常奇怪,而提示对象却没有,至少不是开箱即用。

我想要这样的事情:

function foo(object $o)

就像我们一样:

function foo(array $o)

可能的使用示例:对象集合类的方法。

解决方法:使用所有类实现的接口“Object”或扩展泛型类“Object”中的所有类,并编写如下内容:

function foo(Object $o)

嗯,那不可爱。

使用stdClass作为类型提示不起作用:

  

可捕获的致命错误:参数1   传递给c :: add()必须是一个实例   stdClass,b的实例

10 个答案:

答案 0 :(得分:7)

由于类型提示应该使客户端代码适应您的API,因此您接受接口的解决方案似乎恰到好处。

以这种方式查看:yourMethod(array $input)yourMethod()提供了一个数组供您使用,因此您知道exactly which native functions适用并可由yourMethod()使用。

如果您指定的方法如下:yourSecondMethod(yourInterface $input)您还知道哪些方法可以应用于$input,因为您知道/可以查找接口附带的哪组规则{{1} }}

在您的情况下,接受任何对象似乎是错误的,因为您无法知道在输入上使用哪些方法。例如:

yourInterface

(并不意味着语法有效)

答案 1 :(得分:6)

不,它无法完成。我没有遗漏任何东西。

答案 2 :(得分:6)

我感觉到你的痛苦,但我也找不到办法。

尽管许多其他海报都说过,但想要“对象”类型暗示是完全合理的。他们只是没有考虑需要它的场景。

我正在尝试使用反射API进行一些工作,因此我不关心将哪个类传递给我的函数。我只关心它是一个对象。我不想要int,float,字符串或数组。我想要一个物体。鉴于反射现在是PHP的一部分,对象类型提示肯定是有道理的。

答案 3 :(得分:4)

在输入对象时,你不能只说“对象”......你必须定义你期望的WHICH对象。

来自:http://php.net/manual/en/language.oop5.typehinting.php

class MyClass
{
    /**
     * A test function
     *
     * First parameter must be an object of type OtherClass
     */
    public function test(OtherClass $otherclass) {
        echo $otherclass->var;
    }


    /**
     * Another test function
     *
     * First parameter must be an array
     */
    public function test_array(array $input_array) {
        print_r($input_array);
    }
}

// Another example class
class OtherClass {
    public $var = 'Hello World';
}

答案 4 :(得分:3)

强制执行此操作的最佳方法是创建名为Object的简并接口。简并接口意味着它没有定义的方法。

interface Object {

   // leave blank

}

然后在您的基类中,您可以实现Object

class SomeBase implements Object {

   // your implementation

}

您现在可以根据需要调用您的功能

function myFunc (Object $obj);

myFunc($someBase);

如果传递任何继承自Object接口的对象,则此类型提示将通过。如果传入数组,int,string等,则类型提示将失败。

答案 5 :(得分:2)

这是另一个需要它的例子......

我已经创建了一个实现记录锁定的类。记录是许多不同对象类型之一。锁定类有几个方法需要一个对象(一个被锁定的对象),但不关心它是什么类型的对象。

E.g。

public static function lockRecord($record, User $user, $timeout=null)
{
    if(!is_object($record)) throw new \InvalidException("Argument 1 must be an object.");

    $lock=new Lock();
    $lock->setRecord($record);
    $lock->setUser($user);
    $lock->setTimeout($timeout);
    $lock->activate();
    return($lock);
}

你会看到我的解决方案是使用is_object()并抛出一个异常,但我宁愿用类型提示代替它。

好的,所以不是世界末日,但我认为这是一种耻辱。

答案 6 :(得分:1)

php中的对象不是某些StdClass或Object的子类,因为它在其他OOP语言中。所以没有办法暗示对象的类型。但我明白你的意思是因为有时你想确保传递了Object,所以我想唯一的方法是手动提出问题。

public function yourFunction($object){
    if(is_object($object)){
        //TODO: do something
    }else{
        throw new InvalidArgumentException;
    }
}

从PHP 5.4开始,还有一个类型提示可调用。 请参阅php manual http://php.net/manual/en/language.types.callable.php

答案 7 :(得分:0)

为什么要在提示实际的类名时提示object - 这会更有用。另请注意,您无法提示intfloatboolstringresource

答案 8 :(得分:0)

public static function cloneObject($source)
{
    if ($source === null)
    {
        return null;
    }

    return unserialize(serialize($source));
}

这是您需要的地方。

答案 9 :(得分:0)

PHP 7.2 起,您终于可以声明所需的方式:

function functionName(object $someObjectVariable)

在此页面上查看名为“有效类型”的表: https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration