2009-10-10 31 views
21

我是否错过了某些东西,或者真的不支持PHP 5.x中的通用对象类型提示?PHP类型提示:数组支持,对象不是?

我觉得很奇怪,提示数组是支持的,而提示对象不是,至少不是开箱即用的。

我想有这样的事情:

function foo(object $o) 

正如我们:可能使用

function foo(array $o) 

实例:对象集合类的方法。

解决方法:使用一个接口“对象”的所有类实现或从通用类“对象”延伸的所有类和写是这样的:

function foo(Object $o) 

嗯,这只是一点都不可爱。

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

Catchable fatal error: Argument 1 passed to c::add() must be an instance of stdClass, instance of b given

+1

请勿使用具体类型进行提示。要么使用接口,要么阅读鸭子打字。 – 2009-10-10 11:41:45

+0

如果我要走没有具体的类型路径,我宁愿使用is_object()。但这不是讨论的重点。 – 2009-10-10 11:54:04

+5

看,PHP是一种非常不一致的语言,在这种语言中,对象不像Java一样从一个类继承。对于一般物体没有暗示的事实是一个疏忽,但我认为你必须通过这一点并为其他奇怪的事情做好准备。 – 2009-10-10 12:03:37

回答

6

不,不能这样做。我没有失去任何东西。

+0

不正确。看到我的答案 – 2015-07-14 15:42:03

7

由于类型提示应该让客户端代码适应你的API,以接受接口解决方案似乎是适当的。

这样看:yourMethod(array $input)给出yourMethod()一个数组使用,从而知道exactly which native functions适用并可以使用yourMethod()

如果你指定你的方法,如:yourSecondMethod(yourInterface $input)你也知道哪些方法可以应用到$input,因为你知道/可以查找与接口yourInterface相伴随的哪组规则。

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

function foo(Object $o) { 
    return $o->thisMethodMayOrMayNotExist(); 
} 

(不意味着语法是有效的)

+1

对象集合类的情况并非如此,它将充当(伪)容器,该容器不会在其子级上调用任何方法,也不会使用它们的任何属性/属性。 知道一个变量是一个对象也可以使用它的许多本地功能,所以我真的不明白你的观点。 – 2009-10-10 11:42:40

+2

如何使用类型提示,如SplObjectStorage或ArrayObject? – chelmertz 2009-10-10 12:12:37

+0

简单容器对象\ stdClass – Kzqai 2016-12-01 22:18:48

0

为什么要提示object当你可以提示一个实际的类名时 - 这会更有用。还请记住,您无法暗示int,float,bool,stringresource

+3

为什么你想要打一个数组?记住所有那些你不能暗示的类型......因为没有所有PHP类都从其下降的公共基类,所以能够提示对象,就像提示一个数组一样有意义。我的意见,但我怀疑我一个人在这一个。 – 2009-10-20 11:31:08

+1

仅仅因为你无法想象一个类型暗示一个通用对象的实例,并不意味着这种需求永远不会存在.Rikki的评论就是一个很好的例子。在我看来,无法为int,float,bool,string和resource输入提示也是一个疏忽。有很多实例,我宁愿明确地限制一个参数为一个整数。相反,我坚持使用“is_int”无意义调用。 – 2015-05-01 06:35:41

6

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

尽管有许多其他海报说过,但想要'对象'类型暗示是非常有意义的;他们只是没有考虑到需要它的场景。

我正在尝试使用反射API做一些工作,因此我不在乎传递给我的函数的类是什么。我只关心它是一个对象。我不想要一个int,一个浮点数,一个字符串或一个数组。我想要一个对象。鉴于反射现在是PHP的一部分,所以具有对象类型提示是明智的。

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(),并抛出一个异常,但我很情愿能够用类型提示,而不是去做。好吧,那么不是世界末日,但我认为这是一种耻辱。

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'; 
} 
0
public static function cloneObject($source) 
{ 
    if ($source === null) 
    { 
     return null; 
    } 

    return unserialize(serialize($source)); 
} 

在这里,你会需要它。

+4

为了提高答案的质量,请包括您的帖子如何/为什么解决问题。 – 2012-10-05 09:01:29

3

执行此操作的最佳方法是创建一个名为Object的退化界面。简并接口意味着它没有定义的方法。

interface Object { 

    // leave blank 

} 

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

class SomeBase implements Object { 

    // your implementation 

} 

现在,您可以打电话给你的功能你想

function myFunc (Object $obj); 

myFunc($someBase); 

如果您通过从您的Object接口继承的任何对象,这种暗示会通过。如果你传入一个数组,int,string等,那么类型提示将失败。

+0

不幸的是,这可能是您在PHP中最接近的,但它确实意味着您创建的每个类都必须实现'Object'接口,这对于像这样简单的事情来说确实是很大的开销。 Ahhhhh,PHP .. – mAAdhaTTah 2015-08-05 14:22:20

+3

OP已经在这个问题中描述了这个策略作为一种可能的解决方法,它很糟糕;这不会让你传递在第三方库中定义的内置类或类的实例。 – 2015-10-17 13:00:26

1

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

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

自PHP 5.4的还有一种类型的提示调用。 请参见手册http://php.net/manual/en/language.types.callable.php

相关问题