Php Yii2从名称动态加载类
我为这个问题挣扎了一段时间——原因可能很简单 背景 我已经为我的Yii2应用程序创建了解析器模块,所以我可以从其他地方(移动应用程序等)调用它,从各种网站获取数据。可能有许多解析器类,它们都实现相同的接口 项目结构Php Yii2从名称动态加载类,php,yii2,Php,Yii2,我为这个问题挣扎了一段时间——原因可能很简单 背景 我已经为我的Yii2应用程序创建了解析器模块,所以我可以从其他地方(移动应用程序等)调用它,从各种网站获取数据。可能有许多解析器类,它们都实现相同的接口 项目结构 ... /modules \_ parser \_components \_parsers \_SampleParser.php \_controllers \_D
...
/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中都包含staticclassName()
方法时,我得到了无法调用抽象方法app\modules\parser\models\IParseProvider::className()
。哦,对不起,我忘了你的类没有扩展yii\base\Object
-如果你使用的是PHP>=5.5,你可以使用IParseProvider::class
IParseProvider::class
而不是IParseProvider::className()
执行了该作业。非常感谢:)请将此信息添加到您的答案中,以便我可以接受。