typehinting: method should accept any $arg that is an object

眉间皱痕 提交于 2020-01-04 02:36:06

问题


I have a class 'Collection', which has an add method. The add method should only accept objects. So this is the desired behaviour:

$x=5;//arbitrary non-object
$obj=new Foo; //arbitrary object

$collection=new Collection;
$collection->add($obj); //should be acceptable arg, no matter the actual class
$collection->add($x); //should throw an error because $x is not an object

According to the PHP manual, one can typehint methods by prefacing the $arg with a class name. Since all PHP classes are children of stdClass, I figured this method signature would work:

public function add(stdClass $obj);

But it fails with "Argument must be an instance of stdClass".

If I change the signature to a parent class defined by me, then it works:

class Collection {
  public function add(Base $obj){
    //do stuff
  }
}

$collection->add($foo); //$foo is class Foo which is an extension of Base

Does anyone know how to type hint for a generic object?


回答1:


Unlike Java's Object class, PHP does not have a base class for objects. Objects do not inherit stdClass: it's a default object implementation, not a base class. So, unfortunately, you can't type hint for all objects in PHP. You have to do something like:

class MyClass {
    public function myFunc($object) {
        if (!is_object($object))
             throw new InvalidArgumentException(__CLASS__.'::'.__METHOD__.' expects parameter 1 to be object");
    }
}

Luckily, PHP already defines the InvalidArgumentException class for that purpose.




回答2:


There is no root class in PHP. Objects don't even inherit from stdClass:

class Foo {}
var_dump(new Foo instanceof stdClass); // bool(false)
var_dump(get_parent_class(new Foo));   // bool(false)

Apparently there is no known way in PHP to type hint for object even though object is a data type in PHP (like array), and typecasting to object yields a stdClass object:

echo get_class((object) "string"); // stdClass

I guess as a workaround you could tell the method to throw an exception or die with a fatal error if is_object($obj) returns false.




回答3:


Well the thing is, that PHP is still a dynamic language, and type hints are just that: hints. I think you will have to fall back to the old is_object or similar methods and throw a custom exception.

class Collection {
  public function add(Base $obj){
    if(!is_object($obj))
    throw new Exception("Parameter must be an object");
    // do stuff
  }
}



回答4:


In PHP 7.2 there is now an object type hint. You can simply do

class Collection {
  public function add(object $obj){
    //do stuff
  }
} 


来源:https://stackoverflow.com/questions/4218693/typehinting-method-should-accept-any-arg-that-is-an-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!