类型提示:方法应该接受任何作为对象的 $art
Posted
技术标签:
【中文标题】类型提示:方法应该接受任何作为对象的 $art【英文标题】:typehinting: method should accept any $arg that is an object 【发布时间】:2011-05-12 05:55:42 【问题描述】:我有一个类 'Collection',它有一个 add 方法。 add 方法应该只接受对象。所以这是期望的行为:
$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
根据 php 手册,可以通过在 $arg
前面加上类名来输入提示方法。由于所有 PHP 类都是 stdClass
的子类,我认为这个方法签名会起作用:
public function add(stdClass $obj);
但它失败并显示“参数必须是 stdClass 的实例”。
如果我将签名更改为我定义的父类,那么它可以工作:
class Collection
public function add(Base $obj)
//do stuff
$collection->add($foo); //$foo is class Foo which is an extension of Base
有人知道如何为通用对象键入提示吗?
【问题讨论】:
assert(is_object($arg));
就是你所需要的。
【参考方案1】:
PHP 中没有根类。对象甚至不继承自stdClass
:
class Foo
var_dump(new Foo instanceof stdClass); // bool(false)
var_dump(get_parent_class(new Foo)); // bool(false)
显然,PHP 中没有已知的方法可以为 object
键入提示,即使 object
是 PHP 中的一种数据类型(如 array
),并且类型转换为 object
会产生一个 stdClass
对象:
echo get_class((object) "string"); // stdClass
我想作为一种解决方法,如果is_object($obj)
返回 false,您可以告诉该方法抛出异常或死于致命错误。
【讨论】:
我想既然你可以实例化stdClass,它必须是所有对象的基类。每天学些新东西。我想知道为什么 PHP 决定这样做。【参考方案2】:问题是,PHP 仍然是一种动态语言,类型提示就是:提示。我认为您将不得不退回到旧的 is_object 或类似方法并抛出自定义异常。
class Collection
public function add(Base $obj)
if(!is_object($obj))
throw new Exception("Parameter must be an object");
// do stuff
【讨论】:
【参考方案3】:与 Java 的 Object
类不同,PHP 没有对象的基类。对象不继承stdClass
:它是默认的对象实现,而不是基类。因此,不幸的是,您不能为 PHP 中的所有对象键入提示。您必须执行以下操作:
class MyClass
public function myFunc($object)
if (!is_object($object))
throw new InvalidArgumentException(__CLASS__.'::'.__METHOD__.' expects parameter 1 to be object");
幸运的是,PHP 已经为此目的定义了 InvalidArgumentException
类。
【讨论】:
+1 表示InvalidArgumentException
。请注意,它仅在加载 SPL 时可用。
你也可以在你的异常字符串中写__METHOD__
而不是MyClass::myFunc
。
是的。幸运的是,SPL 从 5.0.0 开始默认加载。我不明白为什么有人会禁用它,它非常有用。【参考方案4】:
在 PHP 7.2 中现在有一个 object
类型提示。你可以简单地做
class Collection
public function add(object $obj)
//do stuff
【讨论】:
以上是关于类型提示:方法应该接受任何作为对象的 $art的主要内容,如果未能解决你的问题,请参考以下文章
如何更新 json 类型的 json 中的任何字段?它应该接受一个对象或一个键数组,如果它存在则更新键,否则创建