【问题标题】:Create new class instance from string name in an aliased namespace从别名命名空间中的字符串名称创建新的类实例
【发布时间】:2016-07-25 17:33:00
【问题描述】:

我见过像thisthis 这样的问题,但是如果您已经有一个命名空间并且该类位于别名命名空间中,这两个问题都没有解决如何从字符串名称创建类实例:

<?php
namespace my\project;

require 'vendor/autoload.php';

//Example aliased classes, more may be defined elsewhere
use League\OAuth2\Client\Provider\Google;
use Stevenmaguire\OAuth2\Client\Provider\Microsoft;

//This is mapped from a submitted form value
$provider = 'Google';

$g = new $provider;

这会抛出PHP Fatal error: Class 'Google' not found。在这些问题中,它说您应该以__NAMESPACE__ 为前缀,但问题是这些类不在my\project 命名空间中,所以这也不起作用,因为它导致类名my\project\Google '不存在。

对此特定代码的一个愚蠢的解决方法是使用一个数组来存储所有命名空间和类名,但如果我事先不知道所有可能的类名,那将无法工作。

我什至看不到如何使用反射来解决这个问题,因为出于同样的原因,我无法为别名类创建反射对象 - new \ReflectionClass($provider); 抛出相同的错误。

如何动态获取别名类名的命名空间?

【问题讨论】:

  • 试试use League\OAuth2\Client\Provider\Google as Google
  • @Xorifelse,不,这和我的一样

标签: php namespaces


【解决方案1】:

您只需使用:

$provider = 'League\OAuth2\Client\Provider\Google';

没有其他解决办法,类名变量需要包含全限定类名;别名不适用于字符串类名,内省也无济于事。

【讨论】:

  • 是的,这很清楚。但是如果加载了类文件,OP 可以(尝试)检索他的全名。为您的清晰/简洁+1
  • 而“(尝试)”正是这种方法相当......次优的原因。 :) 用全名(完全限定的)句点显式命名类。
【解决方案2】:

引入命名空间是为了允许在不同的上下文中使用相同的名称,因此答案是:不,这是不可能的。

您可以有一个类\League\OAuth2\Client\Provider\Google 和另一个类\League\OAuth1\Client\Provider\Google:在这种情况下,您如何确定要实例化哪个类?

假设你知道只有唯一的类名,你可以使用这个代码:

$provider = 'Google';
$found = False;
foreach( get_declared_classes() as $class )
{
    if( preg_match( "~(.*\\\)?($provider)$~", $class ) )
    {
        $found = $class;
        break;
    }
}

if( $found )
{
    $g = new '\\'.$found;
}
else
{
    echo "No '$provider' class found";
}

demo with DateTime class

但是这个例程只是您“使用数组来存储所有命名空间和类名”的想法的简化,因为——即使使用上面的代码——如果你不知道所有声明的类,你可能会得到不需要的结果.

【讨论】:

  • 谢谢。对此还有进一步的转折 - 自动加载的类不会出现在 get_declared_classes 列表中,并且拥有 use 语句并不一定意味着存在类 - 只有当您尝试实例化它时才重要。
  • 如果你使用自动加载我认为你没有机会:php怎么知道你想要什么?
  • 它知道我想要什么!如果我明确使用别名类名$a = new Google;,它可以正常工作。我认为这可能是一个 PHP 错误 - 类名解析似乎不完全正确。
  • 自动加载是股票作曲家。
  • 你打电话给require something/vendor/autoload.php; require something/vendor/autoload.php; ect... 吗?
猜你喜欢
  • 2011-04-09
  • 2011-04-14
  • 1970-01-01
  • 2015-11-23
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 2012-08-08
  • 1970-01-01
相关资源
最近更新 更多