Yii命令行-如何初始化我的整个web应用程序,并通过yiic调用其他控制器操作


Yii Command line - How to initialize my entire web app and call other controller actions via yiic?

更新-我可以通过将application.controller.*添加到config/console.php来解决这个问题,就像这样:

'import'=>array(
        'application.models.*',
        'application.components.*',
        'application.controllers.*',
        'application.extensions.CAdvancedArBehavior',
        'application.extensions.eUploadedImage.*',
       ),

然后调用cli命令中的操作,如下所示:

$myCtrl=new CopyNumberNewSegController(NULL);
$myCtrl->actionBatchImport($libraries,$action);

我在protected/commands/dBManagerCommand.php中有一个简单的yiic命令,我可以从命令行运行:

class DBManagerCommand extends CConsoleCommand
{
    public $verbose=false;
    public $divider="--------------------------------------------------------------------------'n";
    public $title="DB Manager Command'n";
    public function actionImportAnalysis($libraries=false,$action='incomplete') {
        echo $this->divider;
        echo $this->title;
        echo $this->divider;
        echo 'Importing '.$action ." analysis data from file system...'n";
        echo $this->divider;
        switch ($action) {
            case 'incomplete':
                CopyNumberNewSegController::batchImport($libraries,$action);

                break;
        }
        return 0;
    }
}

运行它会产生以下错误。显然它找不到我的其他控制器。我希望在应用程序的其余部分中运行现有控制器中的方法。这是从bash shell运行的(忽略代码颜色)

yiic dbmanager importAnalysis --action=incomplete
--------------------------------------------------------------------------
DB Manager Command
--------------------------------------------------------------------------
Importing incomplete analysis from file system...
--------------------------------------------------------------------------
PHP Error[2]: include(CopyNumberNewSegController.php): failed to open stream: No such file or directory
    in file /var/www/html/mioncoseq/pub/framework/YiiBase.php at line 418
#0 /var/www/html/mioncoseq/pub/framework/YiiBase.php(418): autoload()
#1 unknown(0): autoload()
#2 /var/www/html/mioncoseq/pub/protected/commands/dBManagerCommand.php(21): spl_autoload_call()
#3 unknown(0): DBManagerCommand->actionImportAnalysis()
#4 /var/www/html/mioncoseq/pub/framework/console/CConsoleCommand.php(141): ReflectionMethod->invokeArgs()
#5 /var/www/html/mioncoseq/pub/framework/console/CConsoleCommandRunner.php(65): DBManagerCommand->run()
#6 /var/www/html/mioncoseq/pub/framework/console/CConsoleApplication.php(91): CConsoleCommandRunner->run()
#7 /var/www/html/mioncoseq/pub/framework/base/CApplication.php(162): CConsoleApplication->processRequest()
#8 /var/www/html/mioncoseq/pub/framework/yiic.php(33): CConsoleApplication->run()
#9 /var/www/html/mioncoseq/pub/protected/yiic.php(7): require_once()
#10 /var/www/html/mioncoseq/pub/protected/yiic(4): require_once()

那么我该如何加载这些控制器方法呢?我相信有一种正确的方法可以初始化我的整个应用程序,而无需手动包含那些控制器文件。

谢谢大家!


为了回应下面关于滥用MVC架构的批评,我将把这个回应粘贴到这里,因为评论字段不够长。

首先,我不会为web界面预加载所有控制器,但出于这个目的,它解决了问题,运行良好。import方法最初通过控制器接收请求,但随后在适用于数据库和文件系统级逻辑和操作的情况下调用模型方法。(是的,我确实有其他导入模型类专门用于此目的,主要是因为Yii中与行为相关的内存泄漏)。

imo,认为不应该在控制器中执行任何逻辑的想法是错误的。在这种情况下,我选择在执行一些输入过滤逻辑的控制器中创建导入方法,因为用户(人类或cron)需要提交大量输入,这需要在我们将文件解析到数据库之前进行。此控制器导入方法基于用户输入解析文件,并将预过滤的数据传递给模型方法。我之所以选择这样做,是因为文件输入数据实际上是不受信任的用户输入,并且我需要根据用户请求参数进行一些预处理。是的,你可以在模型方法中这样做,但这会导致处理模型中的请求数据,或者传递大量的参数和数据,这很麻烦,还会增加内存使用率。

通常这样的问题是次优体系结构的标志。我想说,在使用MVC框架时,控制器中有太多与模型相关的代码是开发人员最常见的错误之一。

假设您的代码将从文件(或其他数据源)批量导入数据。这是一个模型任务!因此,您应该在相关的模型类中编写一个方法,例如public static import($filename)。在该方法中,还应避免与其他组件(例如CLI中不可用的Yii::app()->user)的紧密耦合。

如果这是一个更复杂的任务,您甚至可以为导入编写一个专用类。该类可以表示导入作业,并提供类似import()getError()的方法来获取导入的错误状态。

像这样解耦类大大提高了可重用性:您现在可以使用该模型方法或从控制器操作和CLI命令中导入类。