【发布时间】: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];。但是由于您明确表示您不想“将其强制为类的实例”,因此我不确定这是否是您想要的(除非您实际上只是表示您不想想要硬编码函数中的类名?)如果没有,我不知道你真正想要什么。