如何解决php doc:输入将始终实现给定接口的字符串类名称
我有一个返回类名(字符串)的函数,但是返回的类始终实现相同的接口:
<?php
interface BaseInterface {}
class SomeClass implements BaseInterface {}
class AnotherClass implements BaseInterface {}
/**
* @return ....
*/
function getClassName($someCondition): string
{
if ($someCondition === 42) {
return SomeClass::class;
} else {
return AnotherClass::class;
}
}
是否可以在@return
标签中提供此信息?像这样(虚构的语法):
/** @return BaseInterface::class */
最终目标是使IDE知道getClassName(...)::myInterfaceMethod()
是有效的。
编辑:问题的具体用例
这是一个可运行的示例,显示了我如何在实际代码中使用::class
。
我重新编写了代码,使其尽可能短,但这实际上是Symfony项目的一部分,该项目使用php 7.4运行。
这个想法是在每个社交网络上实施一个类;所有这些小类都实现SocialNetworkInterface
并且只有静态方法。永远不会实例化它们,但是可以通过调用其静态方法来进行咨询。
注意:变量$user
的类型应为User
,但是为了缩短代码,我只是在参数中保留了它们的类型。
我的问题(IDE抱怨)中解释的问题发生在renderLinkForUserNetwork()
内的第79行:
$class = $networkClass::getFontAwesomeLogoClass();
$url = $networkClass::getUrlForUsername($networkUsername);
<?php
interface SocialNetworkInterface
{
public static function getName(): string;
public static function getBaseUrl(): string;
public static function getUrlForUsername(string $username): string;
public static function getFontAwesomeLogoClass(): string;
}
abstract class AbstractSocialNetwork implements SocialNetworkInterface
{
public static function getUrlForUsername(string $username): string
{
// Most social networks use this kind of urls,but of course,this can
// be overloaded in final classes:
$baseUrl = static::getBaseUrl();
return "$baseUrl/$username";
}
public static function getFontAwesomeLogoClass(): string
{
$name = static::getName();
return "fab fa-$name";
}
}
class Facebook extends AbstractSocialNetwork
{
public static function getName(): string
{
return 'facebook';
}
public static function getBaseUrl(): string
{
return ('https://www.facebook.com');
}
}
class Twitter extends AbstractSocialNetwork
{
public static function getName(): string
{
return 'twitter';
}
public static function getBaseUrl(): string
{
return ('https://twitter.com');
}
}
class SocialNetworkHandler
{
public function getSocialNetworksForUser($user): array {
// Should return all the social network classes for which the user has
// information to give (normally depends on the user,fake data is given
// here for simplicity):
return [
Facebook::class,Twitter::class,];
}
public function renderLinkForUserNetwork($user,string $networkClass): ?string
{
// Make it runnable for this example,normally retrieved from $user
// and $networkClass:
$networkUsername = 'example';
// An ugly workaround: of course,$networkClass is not an instance of
// SocialNetworkInterface,but calling static methods work the same
// between class name strings and objects:
/** @var SocialNetworkInterface $networkClass */
// When not using the ugly workaround just above,the IDE is complaining
// here (method not found in string):
$class = $networkClass::getFontAwesomeLogoClass();
$url = $networkClass::getUrlForUsername($networkUsername);
return <<< HTML
<a href="$url"><i class="$class"></i></a>
HTML;
}
public function renderLinksForUser($user): string
{
$links = [];
foreach ($this->getSocialNetworksForUser($user) as $networkClass) {
$links[] = $this->renderLinkForUserNetwork($user,$networkClass);
}
return implode("\n",$links);
}
}
$handler = new SocialNetworkHandler();
$user = null; // Should be a User entity
echo $handler->renderLinksForUser($user);
输出:
<a href="https://www.facebook.com/example"><i class="fab fa-facebook"></i></a>
<a href="https://twitter.com/example"><i class="fab fa-twitter"></i></a>
解决方法
不,不幸的是,它不是这样工作的。您应该在此处指定一个返回类型,即使BaseInterface :: class是动态的,它也将是一个返回 value (类型为string
)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。