php 变更 obj,php-任何obj的类型提示

php-任何obj的类型提示

我一直在研究旨在与对象一起使用的代码,而实际上并不关心对象的种类。 我想输入一些提示,即所编写的方法应使用任何类型的对象,但会遇到一些困难。

我尝试了stdClass和stdClass,但是当我尝试在以下对象中传递对象时,这两个都生成了错误:

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

stdClass也发生了同样的情况

我想念什么? 我认为所有未显式继承自另一个类的类都继承自stdClass,这意味着PHP中每个类的基类都将是stdClass。不是这样吗?

GordonM asked 2020-02-16T10:06:51Z

9个解决方案

46 votes

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

Abdullah answered 2020-02-16T10:07:04Z

36 votes

实施此操作的最佳方法是创建一个名为Object的简并接口。简并接口意味着它没有定义的方法。

interface Object {

// leave blank

}

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

class SomeBase implements Object {

// your implementation

}

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

function myFunc (Object $obj);

myFunc($someBase);

如果传递任何从Object接口继承的对象,则此类型提示将通过。 如果您传入数组,整数,字符串等,则类型提示将失败。

Gaz_Edge answered 2020-02-16T10:07:38Z

11 votes

尽管没有对象的类型提示,但是您可以使用:

if (!is_object($arg)) {

return;

}

Ben answered 2020-02-16T10:07:58Z

11 votes

仅仅花了八年的时间,但这很快就会成为可能:PHP 7.2引入了object类型提示! 在我撰写本文时,它目前处于RFC阶段,定于11月发布。

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

RFC:对象类型提示

讨论区

这完全符合您的预期:

class Foo {}

class Bar {}

function takeObject(object $obj) {

var_dump(get_class($obj));

}

takeObject(new Foo);

takeObject(new Bar);

takeObject('not an object');

将导致:

string(3)“ Foo”

string(3)“酒吧”

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

见[https://3v4l.org/Svuij]

副作用是object现在是保留字,不幸的是,这使@Gaz_Edge的现有解决方案无效。 幸运的是,您只需删除接口即可解决该问题。

iainn answered 2020-02-16T10:09:07Z

7 votes

没有所有对象都从其扩展的基类。 您只需删除typehint并在@param批注中记录所需的类型。

NikiC answered 2020-02-16T10:09:27Z

3 votes

没有要求您接口的所有用户扩展指定类的内置机制,都无法做到这一点。 但是您为什么仍要这样做呢? 所有对象类型的共同点是什么,足以使它们适合您的API?

即使能够像这样键入提示,您也一无所获。 另一方面,类型暗示参数以实现接口(例如is_object)将更有意义。

如果您仍希望输入提示,则最好的方法是将运行时检查替换为参数is_object。

Jon answered 2020-02-16T10:09:57Z

2 votes

从php 7.2开始,此功能现已实现。 您现在可以为任何对象键入提示。

function myFunc(Object $myObject) : Object {

return $myObject;

}

您可以在官方文档中查看

Ophidian answered 2020-02-16T10:10:21Z

1 votes

适用于test.php的Typehint从PHP 5.3+开始运行(如果我没记错的话)。以下是对stdClass构造体使用typehint的有效代码:

示例test.php:

class Test{

function hello(stdClass $o){

echo $o->name;

}

}

class Arg2 extends stdClass{

public $name = 'John';

function sayHello(){

echo 'Hello world!';

}

}

$Arg1 = new stdClass();

$Arg1->name = 'Peter';

$Arg2 = new Arg2();

$Arg2->sayHello();

$test = new Test();

// OK

$test->hello($Arg1);

$test->hello($Arg2);

// fails

$test->hello(1);

打印输出:

你好,世界!

彼得

约翰

可捕获的致命错误:传递给Test :: hello()的参数1必须是stdClass的实例,给定的整数,在第32行的test.php中调用并在第5行的test.php中定义

lubosdz answered 2020-02-16T10:11:07Z

-3 votes

您可以执行以下操作:

function myFunc ($obj)

{

if ($obj instanceof stdClass) { .... }

}

Alon Eitan answered 2020-02-16T10:11:28Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值