Я борюсь с этой проблемой некоторое время - и причина, вероятно, тривиальна.Yii2 динамически загружающий класс от имени
фон
Я создал модуль синтаксического анализатора для моего приложения 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 Fatal Error – yii\base\ErrorException
Class 'SampleParser' not found
с выделенной линией:
$object = new $className();
Что я здесь делаю неправильно? Благодаря!
Спасибо, я удалил ненужное использование. BTW ваш метод вызывает «вызов неопределенного метода app \ modules \ parser \ models \ IParseProvider :: className()» - и это правильно, это просто чистый интерфейс. Когда я включаю статический метод 'className()' как в интерфейсе, так и в 'SampleParser', я получаю' Не могу вызвать приложение абстрактного метода \ modules \ parser \ models \ IParseProvider :: className() '. – Mark
О, извините, я забыл, что ваш класс не расширяет 'yii \ base \ Object' - вы можете использовать' IParseProvider :: class', если вы используете PHP> = 5.5 – Bizley
Он работает! 'IParseProvider :: class' вместо' IParseProvider :: className() 'выполнил задание. Большое спасибо :) Пожалуйста, добавьте эту информацию в свой ответ, чтобы я мог ее принять. – Mark