Laravel 4:从数据库中的字符串动态加载类

use*_*764 5 php class dynamic laravel laravel-4

我希望我知道如何更恰当地搜索这个问题/短语.这阻碍了我对先前问题的搜索; 如果这是重复的话,请耐心等待.

请参阅更新/编辑在底部这个职位

背景/我正在尝试做什么:

我有一个看起来很像这样的网址:

http://myapp.com/calculate/$fileID /$calculateID

$fileID并且$calculateID是我用来跟踪数据集的键和我称之为"计算"的东西.从本质上讲,该URL表示$calculateID对数据执行$fileID.

我去我的数据库(mongo),并要求一个PHP类名称或sring或文件路径或你有什么匹配$calculateID.例如,让我们说这个表看起来像这样:

 +-----+-------------------+
 | _id |     phpFile       |
 +-----+-------------------+
 |   1 | basicCalcs.php    |
 |   2 | advancedCalcs.php |
 |   3 | summaryCalcs.php  |
 +-----+-------------------+
Run Code Online (Sandbox Code Playgroud)

注意:可以安全地假设phpFile列中的每个文件都有一个公共接口/公共方法集.

例:

http://myapp.com/calculate/23/2

将转到数据库,从集合中获取数据23,然后加载函数advancedCalcs.php.一旦advancedCalcs.php加载,内部函数将接收数据.从那里,对数据执行一组计算和变换.

我的问题

我的问题是什么是"laravel 4 friendly"方式来动态加载advancedCalcs.php并将数据提供给一组方法?有没有办法懒惰加载这种类型的东西.目前,我只知道非常简单的require_once()方法.我真的想避免这种情况,因为我确信laravel 4具有动态加载底层类并将其连接到公共接口的功能.

编辑1

感谢Antonio Carlos Ribeiro,我取得了一些进展.

运行dump-autoload命令后,我的vendor/composer/autoload_classmap.php文件有一些新的条目如下所示:

'AnalyzeController' => $baseDir . '/app/controllers/AnalyzeController.php',
'AppName\\Calc\\CalcInterface' => $baseDir . '/app/calculators/CalcInterface.php',
'AppName\\Calc\\basicCalcs' => $baseDir . '/app/calculators/basicCalcs.php',
Run Code Online (Sandbox Code Playgroud)

使用下面的示例代码,我可以创建basicCalcs类的实例:

$className = "AppName\\Calc\\basicCalcs";

$instance = new $className; 

var_dump($instance);
Run Code Online (Sandbox Code Playgroud)

basicCalcs.php文件看起来像这样:

//PATH: /app/calculators/basicCalcs.php
<?php namespace Reporter\Calc;


class basicCalcs {


    public function sayHi(){
        echo("hello world! i am basicCalcs");
    }

};

?>
Run Code Online (Sandbox Code Playgroud)

更新的问题: 我如何创建类似于AnalyzeController条目的别名, autoload_classmap.php而不是必须引用basicCalcs.php完整的命名空间?

Ant*_*iro 6

将库文件夹添加到composer.json自动加载:

"autoload": {
    "classmap": [
        "app/commands",
        "app/controllers",
        "app/models",
        "app/extended",
        "app/calculators",  <------- This is where you put all your calculators
        "app/database/migrations",
        "app/database/seeds",
        "app/tests/TestCase.php"
    ]
},
Run Code Online (Sandbox Code Playgroud)

更新自动加载的类:

composer dump-autoload
Run Code Online (Sandbox Code Playgroud)

如果你想确定它确实有效,请检查你的类是否自动加载打开文件

vendor/composer/autoload_classmap.php
Run Code Online (Sandbox Code Playgroud)

要以dinamically方式实例化它们,最好将它作为表类名称:

+-----+-------------------+-------------------+
| _id |     phpFile       |  namespace        |
+-----+-------------------+-------------------+
|   1 | basicCalcs        | Reporter\Calc\    |
|   2 | advancedCalcs     | Reporter\Calc\    |
|   3 | summaryCalcs      | Reporter\Calc\    |
+-----+-------------------+-------------------+
Run Code Online (Sandbox Code Playgroud)

然后你只需要使用它

class CalculateController extends Controller {

    public function calculate($fileID, $calculateID)
    {
        $file = phpFile::find($fileID);

        $className = $file->namespace . $file->phpFile;

        $calculator = new $className; //// <--- this thing will be autoloaded

        return $calculator->calculate( $calculateID );
    }

}
Run Code Online (Sandbox Code Playgroud)

我假设你的计算器都是:

class basicCalcs {

    public function calculate($calculateID)
    {
        return performCalculation( $calculateID ); /// something like this
    }

}
Run Code Online (Sandbox Code Playgroud)

而你的路由器就是这样的想法

Route::get('/calculate/{fileID}/{calculateID}', array('as'=>'calculate', 'uses'=>'CalculateController@calculate'));
Run Code Online (Sandbox Code Playgroud)