Php Yii2从名称动态加载类

Php Yii2从名称动态加载类,php,yii2,Php,Yii2,我为这个问题挣扎了一段时间——原因可能很简单 背景 我已经为我的Yii2应用程序创建了解析器模块,所以我可以从其他地方(移动应用程序等)调用它,从各种网站获取数据。可能有许多解析器类,它们都实现相同的接口 项目结构 ... /modules \_ parser \_components \_parsers \_SampleParser.php \_controllers \_D

我为这个问题挣扎了一段时间——原因可能很简单

背景

我已经为我的Yii2应用程序创建了解析器模块,所以我可以从其他地方(移动应用程序等)调用它,从各种网站获取数据。可能有许多解析器类,它们都实现相同的接口

项目结构

...
/modules
    \_ parser
        \_components
            \_parsers
                \_SampleParser.php
        \_controllers
            \_DefaultController.php
        \_Parser.php
...
 
为了更好的可读性,我删除了一些代码

DefaultController.php:

namespace app\modules\parser\controllers;

use Yii;
use yii\web\Controller;
use app\modules\parser\components\parsers;
use app\modules\parser\components\parsers\SampleParser;

/**
 * Default controller for the `parser` module
 */
class DefaultController extends Controller
{
    
    private function loadParser($parserName){
        
        return new SampleParser();  // if I leave this here, everything works okay
        $className = $parserName.'Parser';
        $object = new $className();
        if ($object instanceof IParseProvider){
            return $object;
        }
    }
    
...
     public function actionIndex()
    {
        $url = "http://google.com";
        $parser = 'Sample';
        $loadedParser = $this->loadParser($parser);
        $response = $loadedParser->parse($url); 
                
            
        \Yii::$app->response->format = 'json';
        return $response->toJson();
    }
...
SampleParser.php:

<?php
namespace app\modules\parser\components\parsers;

use app\modules\parser\models\IParseProvider;

class SampleParser implements IParseProvider {
    
    public function canParse($url){
        
    }
    
    public function parse($url){
        
    }
}

请在Yii的帮助下重试:

private function loadParser($parserName)
{
    return \yii\di\Instance::ensure(
        'app\modules\parser\components\parsers\\' . $parserName . 'Parser',
        IParseProvider::class
    );
}
请记住,当传递的引用不是您期望的类型时,
sure()
抛出
\yii\base\InvalidConfigException
,因此您需要在某个时候捕获它

如果您使用的是PHP<5.5而不是
IParseProvider::class
,则可以在名称空间中使用完整的类名


注意:删除
使用app\modules\parser\components\parser
除非您有名为
解析器的类
要使用。

谢谢,我已经删除了不必要的使用。顺便说一句,您的方法将调用未定义的方法app\modules\parser\models\IParseProvider::className()
——这是正确的,这只是纯接口。当我在interface和SampleParser中都包含static
className()
方法时,我得到了
无法调用抽象方法app\modules\parser\models\IParseProvider::className()
。哦,对不起,我忘了你的类没有扩展
yii\base\Object
-如果你使用的是PHP>=5.5,你可以使用
IParseProvider::class
IParseProvider::class
而不是
IParseProvider::className()
执行了该作业。非常感谢:)请将此信息添加到您的答案中,以便我可以接受。