如何在 php 7.1 中表示返回类型是当前子类型?
Posted
技术标签:
【中文标题】如何在 php 7.1 中表示返回类型是当前子类型?【英文标题】:How to indicate in php 7.1 that the return type is the current child type? 【发布时间】:2018-03-04 06:41:36 【问题描述】:我有
abstract class A
public static function getSingle($where = [])
$classname = get_called_class();
$record = static::turnTheWhereIntoArecordFromDB($where);
$model = new $classname($record);
return $model;
class B extends A
$x = B::getSingle();
$x
没有类型提示... 我喜欢类型提示,所以我想要B
的类型提示,而不是A
的类型提示
如何直接为$x
启用类型提示?
我认为是这样的
public function getSingle($where = []) : ?get_called_class()
这显然行不通
有什么可以做的吗?
【问题讨论】:
A 作为返回值类型提示是否有问题?这意味着 A 和所有孩子都可以返回。 这似乎有点牵强......认为self
已经达到了魔力所能达到的程度。不过很有趣。这些可能的类是否扩展了一个共同的父类?实现一个通用接口?
@JoshuaK 我想为 B 类提供类型提示。@ficuscr A
基本上是一个面向差劲程序员的 ORM。例如。 save()
refresh()
delete()
等,但 B 将具有一些用于更高级 sqls 的实用功能......目前,仅此而已。但一切皆有可能
【参考方案1】:
将@method B getSingle
添加到B
类phpdoc。
/**
* Class B
* @method B getSingle
*/
class B extends A
https://docs.phpdoc.org/references/phpdoc/tags/method.html
【讨论】:
我也开始思考。 @Toskan 这仅仅是 IDE 糖吗? 实际上这破坏了我的 IDE。例如。执行$b->getSingle();
现在不再跳转到函数中,而是跳转到 php 文档中。它实际上是静态的,但似乎也不起作用。 @method static B getSingle
对我来说似乎无法正常工作
@ficuscr 正确的代码错误会更好,但是是的,IDE 糖目前更重要
在 PhpStorm 中工作,至少代码完成工作。但@bijiDango 方法似乎效果更好。【参考方案2】:
对于您提供的示例,为什么需要工厂方法?您正在从构造函数创建一个新实例,为什么不直接$x = new B($record)
!
以上更新
abstract class A
/**
* @param array $where
* @return static
*/
public static function getSingle($where = [])
$classname = get_called_class();
$model = new $classname($record);
return $model;
@return static
将键入提示其子类。我也把你的函数改成了静态函数,这是典型的工厂模式。
【讨论】:
可惜不能: ?static
不?
我不确定你的意思。
public static function getSingle($where = []) : ?static
无效 public static function getSingle($where = []) : ?MyClass
是有效的 php 7.1 语法并强制返回类型为 MyClass
或 null
(感谢 ?
允许 null)
我的意思是 phpdoc 没问题。但如果 php 本身支持将返回类型声明为 static
会更好
你说得有道理。也许有一天它会实现。但如果不是用于类型提示,我看不出:self
与:static
不同。【参考方案3】:
让抽象类实现一个接口并键入提示该接口。孩子不必显式地实现接口。
abstract class A implements BarInterface
public function foo (): BarInterface
return new static;
【讨论】:
但是B
显然会有更多的功能【参考方案4】:
我知道您指定 PHP 7.1,但从 PHP 8(将于 2020 年 11 月发布)开始这将通过添加 static
返回类型提示来实现。
The RFC was approved unanimously, 54-0.
这意味着你将能够做到:
class Foo
public static function build(): static
return new static();
class Bar extends Foo
此外,无需使用$classname = get_called_class(); new $classname();
。你可以简单地做new static()
,这样更整洁,结果也一样。
并且Bar::build()
被类型提示表明它返回Bar
而不是Foo
凭借后期静态绑定。
【讨论】:
以上是关于如何在 php 7.1 中表示返回类型是当前子类型?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Objective C 中表示当前的 JSON 模式?