私はこの問題にしばらく苦労しています。その理由はおそらく些細なことです。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){
}
}
今すべてが多かれ少なかれOK働くので、私は私が正しい名前空間をインポートしていますね。しかし、私はreturn new SampleParser();
を削除して、オブジェクトが文字列名によって作成されるようにしましょうと、それはエラーで失敗します。強調表示されたラインと
PHP Fatal Error – yii\base\ErrorException
Class 'SampleParser' not found
を:
$object = new $className();
私はここで間違って何をしているのですか?ありがとう!
ありがとうございました。ところで、あなたのメソッドは、 '未定義のメソッドapp \ modules \ parser \ models \ IParseProvider :: className()'を呼び出します。私がインターフェイスと 'SampleParser'の両方に静的' className() 'メソッドを含めると'抽象メソッドapp \ modules \ parser \ models \ IParseProvider :: className() 'を呼び出せません。 – Mark
ああ、申し訳ありません、あなたのクラスは 'yii \ base \ Object'を拡張していないことを忘れています - PHP> = 5.5を使用しているなら' IParseProvider :: class'を使うことができます – Bizley
それは動作します! 'IParseProvider :: className()'の代わりに 'IParseProvider :: class'がその仕事をしました。ありがとうございました:)この情報をあなたの答えに加えて、私はそれを受け入れることができます。 – Mark