简体   繁体   English

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

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

Update - I was able to solve this by adding application.controllers.* to config/console.php like so: 更新-我能够通过将application.controllers。*添加到config / console.php来解决此问题,如下所示:

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

then calling the actions in the cli command like this: 然后像这样在cli命令中调用动作:

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

I have a simple yiic command in protected/commands/dBManagerCommand.php that I can run from the command line: 我在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;
    }
}

Running it produces the following error. 运行它会产生以下错误。 Apparently it can't find my other controllers. 显然它找不到我的其他控制器。 I want to run methods from existing controllers in the rest of my application. 我想从我的应用程序其余部分的现有控制器中运行方法。 This is run from the bash shell (ignore code colors) 这是从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()

So then how can i load those controller methods? 那么,我该如何加载那些控制器方法呢? I'm sure there is a proper way to do this that will initialize my entire app, without trying to manually include those controller files. 我确信有一种正确的方法可以初始化我的整个应用程序,而无需尝试手动包含那些控制器文件。

Thanks everyone! 感谢大家!


In response to the criticism about misuse of MVC architecture below, I'm going to paste this response here because the comment field is not long enough. 为了回应以下关于滥用MVC架构的批评,我将在此处粘贴此响应,因为注释字段不够长。

Firstly, I wouldn't pre-load all controllers for the web interface, but for this purpose it solved the problem and works fine. 首先,我不会为Web界面预加载所有控制器,但为此目的,它解决了该问题,并且运行良好。 The import method initially takes requests thru the controller but then calls model methods where appropriate for db and file system level logic and operations. import方法最初通过控制器接收请求,然后在适合于db和文件系统级逻辑和操作的地方调用模型方法。 (And yes I do have other import model classes dedicated for this purpose, mostly because of behavior-related memory leaks in Yii). (是的,我确实有其他专用于此目的的导入模型类,主要是因为Yii中与行为相关的内存泄漏)。

The idea that one should not do any logic in a controller is just wrong, imo. 恕我直言,不要在控制器中执行任何逻辑的想法是错误的。 In this case I've chosen to make import methods in controllers that do some input filtering logic, because there are a large number of inputs that the user (human or cron) needs to submit, and this needs to occur before we get to the task of parsing files into the db. 在这种情况下,我选择在执行某些输入过滤逻辑的控制器中制作导入方法,因为用户(人类或cron)需要提交大量输入,并且这需要在我们进入将文件解析到数据库中的任务。 This controller import method parses files based on user input and passes the pre-filtered data to the model method. 该控制器导入方法根据用户输入来分析文件,并将预先过滤的数据传递给模型方法。 I've chosen to do this because file input data is actually untrusted user input and I needed to do some pre-processing based on the user request params. 我之所以选择这样做,是因为文件输入数据实际上是不受信任的用户输入,并且我需要根据用户请求参数进行一些预处理。 Yes you could do this in a model method, but it would result in either processing request data in the model, or passing a large number of arguments and data around, which is a hassle and increases memory usage. 是的,您可以在模型方法中执行此操作,但这将导致在模型中处理请求数据,或传递大量参数和数据,这很麻烦,并且会增加内存使用量。

Usually problems like this are a sign of a suboptimal architecture. 通常,此类问题表明体系结构欠佳。 I'd say it's one of the most frequent developer mistakes to have too much model related code in the controller, when working with a MVC framework. 我想说的是,在使用MVC框架时,控制器中有太多与模型相关的代码是开发人员最常犯的错误之一。

Assumedly your code will batch import data from a file (or some other data source). 假设您的代码将从文件(或某些其他数据源)中批量导入数据。 This is a model task! 这是一个模型任务! So you should write a method in the related model class, eg a public static import($filename) . 因此,您应该在相关的模型类中编写一个方法,例如, public static import($filename) Inside that method you should also avoid tight coupling to other components (eg Yii::app()->user which is not available in CLI). 在该方法内部,您还应避免与其他组件紧密耦合(例如,CLI中不可用的Yii::app()->user )。

If it's a more complex task, you could even write a dedicated class for your import. 如果这是一项更复杂的任务,您甚至可以为导入编写一个专用的类。 That class could represent an import job and provide methods like import() or getError() to fetch the error status of the import. 该类可以表示导入作业,并提供诸如import()getError()来获取导入的错误状态。

Decoupling classes like this increases reusability a lot: You now can use that model method or import class from both, your controller action and your CLI command. 这样的解耦类可以大大提高可重用性:现在,您可以使用该模型方法或从控制器操作和CLI命令中导入类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM