从类名创建对象在命名空间中不起作用


Object creation from class name not working within namespace

我正在我的项目中创建一个工厂类,其中该类以字符串形式获取报告类型。此字符串具有实现报表接口的具体类的名称。

遇到的问题是,当我实例化这个类时,我收到一个Class not found错误。

下面是工厂代码。

namespace App'Term'Reports;
class Factory
{
    public static function build($type)
    {
        $obj = new CableBySensor();  // Works!
        // $type == 'CableBySensor'
        $obj2 = new $type;         // Class not found :(
        // ... validates if the class exists ...
        // ... and if it implements the Report Interface ...
        // ... throw exception if class doesn't exist or doesn't implements interface
        // ... then returns the corresponding object.
    }
}

这两种方法实际上是一回事。

首先:为什么必须在字符串中指定类的完整限定名才能使其工作?类CableBySensorFactory 位于同一命名空间中。

这开始给我带来麻烦,因为我还想验证正在实例化的类是否实现了ReportsInterface

第二:我该如何克服这个问题?我应该像这样$myReport = Factory::build('App'Term'Reports'' . $className);调用工厂,还是应该在 Factory 类中使用 __NAMESPACE__ 常量,例如:$obj = new __NAMESPACE__ . ''' . $className

谢谢。

无动于衷地对待工厂方法在这里是否有用,问题在于尝试从动态变量实例化。

或者正如 php.net 的akhoondi指出的那样:

必须注意的是,当使用动态类名时,"当前命名空间"[...]是全局命名空间。

可能有 3 种解决方案:

  • 将完全限定的类名传递给工厂方法(啊...

    $instance = Factory::build('Acme'CableBySensor');
    
  • 或者,检查您的构建方法并在必要时为命名空间添加前缀(如此处建议)(对我来说听起来不是那么万无一失)

    public static function build($type)
    {
        if ($type[0] !== '''') {
            $type = '''' . __NAMESPACE__ . '''' . $type;
        }
        $obj = new $type;
        ...
    }
    
  • 或者,如果你有PHP 5.5+,为什么不通过::class使用类名解析?就个人而言,我会尽可能选择那个:

    $instance = Factory::build(CableBySensor::class);