如何在 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 添加到Bphpdoc。

/**
* 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 语法并强制返回类型为 MyClassnull(感谢 ? 允许 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 模式?

如何在 TypeScript 中表示包含多种类型的二维数组?

如何在 json 模式中表示 sum/union 类型

如何在 MySQL 中表示树及其内容?

如何在VB6中表示64位整数?

在 Scheme (R6RS) 中表示代数数据类型构造函数的惯用方式是啥?