Ich kämpfe mit diesem Problem für eine Weile - und der Grund ist wahrscheinlich trivial.Yii2 dynamisch Klasse von Name
Hintergrund
I Parser-Modul für meine Yii2 Anwendung erstellt haben, so nenne ich kann es von anderen Orten (mobile App, etc.) Daten von verschiedenen Websites. Es kann viele Parser-Klassen geben, die alle dieselbe Schnittstelle implementieren.
Projektstruktur
...
/modules
\_ parser
\_components
\_parsers
\_SampleParser.php
\_controllers
\_DefaultController.php
\_Parser.php
...
Ich habe einige Code zur besseren Lesbarkeit entfernt.
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){
}
}
Gerade jetzt alles funktioniert mehr oder weniger ok, also denke ich, dass ich richtig bin Namespaces zu importieren. Aber wenn ich return new SampleParser();
entfernen und lassen Sie das Objekt durch string name erstellt werden, schlägt es mit Fehler:
PHP Fatal Error – yii\base\ErrorException
Class 'SampleParser' not found
mit markierten Linie:
$object = new $className();
Was mache ich falsch hier? Vielen Dank!
Danke, ich habe unnötige Verwendung entfernt. BTW Ihre Methode löst 'Aufruf zu undefinierter Methode app \ modules \ parser \ models \ IParseProvider :: className()' - und das ist richtig, das ist nur reine Schnittstelle. Wenn ich die static 'className()' Methode sowohl in Interface als auch in 'SampleParser' einfüge, bekomme ich' die abstrakte Methode app \ modules \ parser \ models \ IParseProvider :: className() 'nicht aufrufen können. – Mark
Oh, sorry, ich vergaß Ihre Klasse nicht 'yii \ base \ Object' zu erweitern - Sie können' IParseProvider :: class' verwenden, wenn Sie PHP> = 5.5 verwenden – Bizley
Es funktioniert! 'IParseProvider :: class' anstelle von' IParseProvider :: className() 'hat den Job erledigt. Vielen Dank :) Bitte fügen Sie diese Informationen zu Ihrer Antwort hinzu, damit ich sie akzeptieren kann. – Mark