我在这个问题上挣扎了一段时间 - 原因可能很简单。
背景
我为我的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){
}
}
现在一切都或多或少都可以,所以我想我正在导入正确的命名空间。但是当我删除return new SampleParser();
并让对象通过字符串名称创建时,它会失败并显示错误:
PHP致命错误 - yii \ base \ ErrorException
未找到类'SampleParser'
带突出显示的行:
$ object = new $ className();
我在这里做错了什么?谢谢!
答案 0 :(得分:2)
在Yii的帮助下再试一次:
private function loadParser($parserName)
{
return \yii\di\Instance::ensure(
'app\modules\parser\components\parsers\\' . $parserName . 'Parser',
IParseProvider::class
);
}
请记住ensure()
在传递引用时抛出\yii\base\InvalidConfigException
不是您期望的类型,因此您需要在某个时刻捕获它。
如果您使用的是PHP&lt; 5.5而不是IParseProvider::class
,您可以使用完整的类名称及其命名空间。
P.S。删除use app\modules\parser\components\parsers;
,除非您有一个名为parsers
的课程。