【问题标题】:How to transform a className to uninstantiated class in >php7.1如何在 >php7.1 中将类名转换为未实例化的类
【发布时间】:2021-08-12 00:57:47
【问题描述】:

正如预期的那样,下面的示例不起作用,但我如何告诉 php 我的类名字符串应该是一个未实例化的类? 我知道我可以用一些技巧来解决问题,但有没有合适的方法?

感谢 magnus,我想补充一点,在使用中我不想在函数中硬编码类名,它可以是任何东西,但要注意它的存在等不是问题的一部分。

(对于 php>7.1)

另一个方向适用于get_class

Interface iFoo {
    static function getBar(): string;
}
class Foo implements  iFoo {
    private static $bar = "`My test value`";
    static function getBar(): string {
        return self::$bar;
    }
}

function getMyClass() : iFoo {
    $classes = array('Foo');
    print "this works: ".$classes[0]::getBar();
    // return failes
    print "this does not:";
    return $classes[0];
}

输出:

this works: `My test value`this does not:

Fatal error:  Uncaught TypeError: Return value of getMyClass() must implement interface iFoo, string returned

我知道它可以与 : iFoo | string 一起使用,但是类型提示已经过时了。我错过了诸如 make-class-of-string() 函数之类的东西。

提前感谢您的帮助:)

【问题讨论】:

  • 如果: iFoo 可以表示字符串或类实例,那么它作为类型将毫无用处。类型用于确保您始终从函数/方法中获得期望的结果。如果它可以返回一个字符串或一个对象,那将是模棱两可的,您将不知道应该使用getMyClass()->foo() 还是getMyClass()::foo()。在这里解释您真正想要解决的问题,我们可能会提供帮助。目前,这听起来像是XY problem。您不能返回未实例化的类。
  • 完全正确,但我想强制它成为该类型的类对象(而不是类的实例)。我会根据条件使用它来路由到 iFoo 的特定实现。
  • 一个对象一个类的实例,所以语句“强制它是一个类对象(不是一个类的实例)” 没有意义。您可以返回名为 iFoo、扩展 iFoo 或实现 iFoo 的类的 instance。如果要返回字符串,请使用: string。如果要确保返回的字符串是实现特定接口的有效类名,则需要在返回字符串之前在函数中对其进行验证。你可以使用class_implements()
  • new className() 将是一个实例 className 是一个class。我很清楚这里发生了什么我想知道是否有一种语法方式来确保它只能是 class 以便 typehinting 正常工作
  • 如果您只想返回一个实际的对象,您可以通过执行以下操作动态实例化该类:return new $classes[0];。但是由于您明确表示您不想“将其强制为类的实例”,因此我不确定这是否是您想要的(除非您实际上只是表示您不想想要硬编码函数中的类名?)如果没有,我不知道你真正想要什么。

标签: php php-7


【解决方案1】:

没有办法。

返回类型是实例的类型(无论是复杂类型还是原始类型)。存在于记忆中的东西。

::class 关键字是一个简单的帮助器,它解析为一个类的完全限定名,它是一个字符串(一种原始类型)。

返回类型是对象的一种类型,而不是实例化时的特定类型。并且没有任何技巧可以说“在实例化时,此字符串的类型为Foo”。

$classes[0]::getBar() 构造之所以有效,是因为它是一种语法糖。 PHP 将其解析为 Foo::getBar() 之类的东西,在语法上是对静态函数的调用。正如您所注意到的 - 效果非常好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    相关资源
    最近更新 更多