更新 - 我能够通过将application.controllers。*添加到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界面预先加载所有控制器,但为此目的,它解决了问题并且工作正常。导入方法最初通过控制器接受请求,但随后调用模型方法,适用于db和文件系统级逻辑和操作。 (是的,我确实有其他专用于此目的的导入模型类,主要是因为Yii中与行为相关的内存泄漏)。
一个人不应该在控制器中做任何逻辑的想法是错的,imo。在这种情况下,我选择在执行某些输入过滤逻辑的控制器中创建导入方法,因为用户(人或者cron)需要提交大量输入,这需要在我们到达之前进行。将文件解析到数据库中的任务。此控制器导入方法根据用户输入解析文件,并将预过滤的数据传递给模型方法。我选择这样做是因为文件输入数据实际上是不受信任的用户输入,我需要根据用户请求参数进行一些预处理。是的,您可以在模型方法中执行此操作,但这会导致在模型中处理请求数据,或者传递大量参数和数据,这是一个麻烦并增加内存使用量。
答案 0 :(得分:0)
通常这样的问题是次优架构的标志。我说在使用MVC框架时,在控制器中有太多与模型相关的代码,这是最常见的开发人员错误之一。
假设您的代码将批量导入文件(或其他一些数据源)中的数据。这是模型任务!所以你应该在相关的模型类中编写一个方法,例如一个public static import($filename)
。在该方法中,您还应该避免与其他组件紧密耦合(例如,CLI中没有的Yii::app()->user
)。
如果这是一项更复杂的任务,您甚至可以为导入编写一个专用类。该类可以表示导入作业,并提供import()
或getError()
等方法来获取导入的错误状态。
这样的解耦类可以大大提高可重用性:您现在可以使用该模型方法或从控制器操作和CLI命令中导入类。