为任何对象键入提示

Gor*_*onM 48 php type-hinting

我一直在研究那些打算与对象一起使用的代码,而不是真正关心对象的类型.我想输入提示,正在编写的方法需要任何类型的对象,但遇到了一些困难.

我试过function myFunc (object $obj),function myFunc (stdClass $obj)但当我尝试传递对象时,这两个都会产生错误:

可捕获致命错误:传递给MyClass :: MyFunc()的参数1必须是对象的实例,给出ObjectActualClass的实例

同样的事情发生stdClass,以及

我错过了什么?我认为所有未明确继承自另一个类的类继承自stdClass,这意味着PHP中每个类的基类都是stdClass.这不是这种情况吗?

Abd*_*lah 46

stdClass不是基类!PHP类不会自动从任何类继承.所有类都是独立的,除非它们显式扩展另一个类.PHP在这方面与许多面向对象的语言不同.


Gaz*_*dge 36

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

interface Object {

   // leave blank

}
Run Code Online (Sandbox Code Playgroud)

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

class SomeBase implements Object {

   // your implementation

}
Run Code Online (Sandbox Code Playgroud)

您现在可以根据需要调用您的函数

function myFunc (Object $obj);

myFunc($someBase);
Run Code Online (Sandbox Code Playgroud)

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

  • +1因为这是最好的oop答案..你应该总是只在接口上键入提示 (6认同)
  • 我同意您的上述评论,但我不同意该解决方案.在你的情况下,你认为你自己定义的一切,但在我们的现代生活中,我们都使用框架,然后他们已经定义.因此,对对象进行类型提示似乎不是一个好的解决方案 (6认同)
  • 但是对内部类不起作用. (5认同)

Ben*_*Ben 11

虽然对象没有类型提示,但您可以使用:

if (!is_object($arg)) {
    return;
}
Run Code Online (Sandbox Code Playgroud)


iai*_*inn 11

好吧,它只花了八年时间,但这很快就会成为可能:PHP 7.2引入了object类型提示!在我写这篇文章时,它目前处于RFC阶段,并将于11月发布.

更新,11月30日: PHP 7.2已经发布

RFC:对象类型提示

讨论

这与您的预期完全相同:

<?php

class Foo {}
class Bar {}

function takeObject(object $obj) {
    var_dump(get_class($obj));
}

takeObject(new Foo);
takeObject(new Bar);
takeObject('not an object');
Run Code Online (Sandbox Code Playgroud)

将导致:

string(3)"Foo"

string(3)"Bar"

致命错误:未捕获的TypeError:传递给takeObject()的参数1必须是一个对象,给定的字符串,在...中调用

请参阅https://3v4l.org/Svuij

这样做的另一个副作用是,object现在这是一个保留字,不幸的是,@ Gaz_Edge现有的解决方案已经破了.幸运的是,你需要做的就是删除界面.


Nik*_*kiC 7

没有所有对象扩展的基类.您应该只删除typehint并记录@param注释中的预期类型.