php 任何对象的类型提示
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7839059/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Type hinting for any object
提问by GordonM
I've been working on code that's intended to be used with objects, without really caring what the kind of object is. I wanted to type hint that the method being written expected an object of any type, but ran into some difficulty.
我一直在编写旨在与对象一起使用的代码,而并不真正关心对象的类型。我想输入提示正在编写的方法需要任何类型的对象,但遇到了一些困难。
I tried function myFunc (object $obj)
and function myFunc (stdClass $obj)
but both of these generated errors when I tried to pass objects in:
我尝试过function myFunc (object $obj)
,function myFunc (stdClass $obj)
但是当我尝试传入对象时,这两个都产生了错误:
Catchable fatal error: Argument 1 passed to MyClass::MyFunc() must be an instance of object, instance of ObjectActualClass given
可捕获的致命错误:传递给 MyClass::MyFunc() 的参数 1 必须是对象的实例,给出的 ObjectActualClass 的实例
The same happened with stdClass
as well
同样的事情发生stdClass
,以及
What am I missing? I thought that all classes that didn't explicitly inherit from another class inherited from stdClass
, meaning that the base class of every class in PHP would be stdClass
. Is this not the case?
我错过了什么?我认为所有没有显式继承自另一个类的类都继承自stdClass
,这意味着 PHP 中每个类的基类都是stdClass
. 不是这样吗?
采纳答案by Abdullah
stdClass is NOT a base class! PHP classes do not automatically inherit from any class. All classes are standalone, unless they explicitly extend another class. PHP differs from many object-oriented languages in this respect.
stdClass 不是基类!PHP 类不会自动从任何类继承。所有类都是独立的,除非它们显式扩展另一个类。PHP 在这方面不同于许多面向对象的语言。
回答by Gaz_Edge
The best way to enforce this would be to create a degenerate interface called Object
. A degenerate interface means it has no defined methods.
强制执行此操作的最佳方法是创建一个名为Object
. 退化接口意味着它没有定义的方法。
interface Object {
// leave blank
}
Then in your base classes, you can implement Object
.
然后在您的基类中,您可以实现Object
.
class SomeBase implements Object {
// your implementation
}
You can now call your function as you wanted to
您现在可以根据需要调用您的函数
function myFunc (Object $obj);
myFunc($someBase);
If you pass any object which inherits from your Object
interface, this type hint will pass. If you pass in an array, int, string etc, the type hint will fail.
如果您传递任何从您的Object
接口继承的对象,则此类型提示将通过。如果传入数组、整数、字符串等,类型提示将失败。
回答by iainn
Well it only took eight years, but this will soon be possible: PHP 7.2 introduces the object
type hint! As I write this, it's currently in the RFC stage, and is due to be released in November.
嗯,只用了八年,但这很快就会成为可能:PHP 7.2 引入了object
类型提示!在我写这篇文章时,它目前处于 RFC 阶段,将于 11 月发布。
Update, 30th November:PHP 7.2 has been released
11 月 30 日更新:PHP 7.2 已发布
This behaves exactly as you might expect:
这完全符合您的预期:
<?php
class Foo {}
class Bar {}
function takeObject(object $obj) {
var_dump(get_class($obj));
}
takeObject(new Foo);
takeObject(new Bar);
takeObject('not an object');
Will result in:
会导致:
string(3) "Foo"
string(3) "Bar"
Fatal error: Uncaught TypeError: Argument 1 passed to takeObject() must be an object, string given, called in...
字符串(3)“Foo”
字符串(3)“酒吧”
致命错误:未捕获的类型错误:传递给 takeObject() 的参数 1 必须是一个对象,给定的字符串,调用...
One side-effect of this is that object
is now a reserved word, which unfortunately renders @Gaz_Edge's existing solution above broken. Fortunately, all you have to do to fix it is delete the interface.
这样做的一个副作用是,object
它现在是一个保留字,不幸的是,它使 @Gaz_Edge 的现有解决方案超出了. 幸运的是,修复它所要做的就是删除接口。
回答by Ben
Although there is no type hinting for objects, you can use:
虽然没有对象的类型提示,但您可以使用:
if (!is_object($arg)) {
return;
}
回答by NikiC
There is no base class that all objects extend from. You should just remove the typehint and document the expected type in the @param
annotation.
没有所有对象都从其扩展的基类。您应该只删除 typehint 并在@param
注释中记录预期的类型。
回答by Jon
There is no built-in mechanism to do this without requiring all users of your interface to extend a specified class. But why would you want to do this anyway? What do all object types have in common that's enough to make them suitable input for your API?
如果不需要界面的所有用户扩展指定的类,就没有内置机制可以做到这一点。但是你为什么要这样做呢?所有对象类型有什么共同点足以使它们适合您的 API 输入?
In all probability you wouldn't gain anything even if able to type hint like this. On the other hand, type hinting a parameter to implement an interface (such as Traversable
) would be much more meaningful.
即使能够输入这样的提示,您也很可能不会获得任何东西。另一方面,类型提示参数以实现接口(例如Traversable
)会更有意义。
If you still want something akin to type hinting, the best you can do is substitute a runtime check with is_object
on the parameter.
如果你仍然想要类似于类型提示的东西,你能做的最好的事情就是用is_object
参数代替运行时检查。
回答by Ophidian
As of php 7.2 this feature has now been implemented. you can type hint for any object now.
从 php 7.2 开始,此功能现已实现。您现在可以为任何对象键入提示。
function myFunc(Object $myObject) : Object {
return $myObject;
}
You can review this in the official documentation
回答by lubosdz
Typehint for stdClass
works since PHP 5.3+ (if I am not wrong).
Following is valid code using typehint for stdClass
construct:
TypehintstdClass
自 PHP 5.3+ 开始工作(如果我没记错的话)。以下是使用 typehint 进行stdClass
构造的有效代码:
Example test.php
:
示例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);
Prints out:
打印出来:
Hello world!
Peter
JohnCatchable fatal error: Argument 1 passed to Test::hello() must be an instance of stdClass, integer given, called in test.php on line 32 and defined in test.php on line 5
你好,世界!
彼得·
约翰可捕获的致命错误:传递给 Test::hello() 的参数 1 必须是 stdClass 的实例,给定整数,在第 32 行的 test.php 中调用并在第 5 行的 test.php 中定义
回答by Alon Eitan
You could do something like this:
你可以这样做:
function myFunc ($obj)
{
if ($obj instanceof stdClass) { .... }
}