【问题标题】:How to call a console command in web application action in Yii?如何在 Yii 的 Web 应用程序操作中调用控制台命令?
【发布时间】:2012-04-26 11:17:12
【问题描述】:

我有一个控制台命令来执行消费时间,并且我需要知道如何在 YII 的 Web 应用程序操作中调用(执行)它。

class MyCommand extends CConsoleCommand{
      public function actionIndex(){
          $model = new Product();
          $model->title = 'my product';
          ...
          $model->save();
          .
          .
          .
      }
}

我想执行这段代码。

【问题讨论】:

  • 为什么你希望这是一个命令而不是控制器?
  • 这是一个示例代码。我刚刚提到我需要在 web 操作中运行命令操作。
  • 但是命令的目的是运行离线任务,所以 ju 可以将它与 cron 作业一起使用。
  • 确实我需要随机创建一些 16 位数字,然后在表中插入主题,因为它需要太长时间我得到最大限制时间执行错误。我需要以其他方式做到这一点。

标签: yii console-application


【解决方案1】:

试试这个:

    Yii::import('application.commands.*');
    $command = new MyCommand("test", "test");
    $command->run(null);

值为“test”的2个参数必须设置但没有影响,它们用于使用控制台时的--help选项。

/**
 * Constructor.
 * @param string $name name of the command
 * @param CConsoleCommandRunner $runner the command runner
 */
public function __construct($name,$runner)
{
    $this->_name=$name;
    $this->_runner=$runner;
    $this->attachBehaviors($this->behaviors());
}

https://github.com/yiisoft/yii/blob/master/framework/console/CConsoleCommand.php#L65

【讨论】:

  • 您的回复没有被接受是不公平的,因为它是最短和最干净的方式。这是我的 +1 作为次要替代品
  • 如果命令没有动作而只有run 方法怎么办?我用什么作为第一个参数。
【解决方案2】:

试试这个

Yii::import('application.commands.*');
$command = new GearmanCommand('start', Yii::app()->commandRunner);
$command->run(array('start', '--daemonize', '--initd'));

其中array('start', '--daemonize', '--initd') 是一个动作和动作参数

【讨论】:

    【解决方案3】:

    我遇到了同样的问题 - 我需要从控制器内部和命令调用操作

    我说的是同样的问题,因为它实际上是一样的——你有需要从控制台调用的操作,也可以从控制器调用它。

    If you need to call an action(command) as a part of controller action, then i think you need to modify this solution a little。或者我的解决方案对你来说足够了吗?

    所以这是我的解决方案:

    首先按照http://www.yiichina.net/doc/guide/1.1/en/basics.controller#action 中的说明创建操作

    class NotifyUnsharedItemsAction extends CAction
    {
        public function run()
        {
            echo "ok";
        }
    }
    

    然后在控制器中的动作照常加载:

    class TestController extends Controller
    {
    
        public function actions() {
            return array(
                'notifyUnsharedItems'=>'application.controllers.actions.NotifyUnsharedItemsAction',
        );
    }
    

    并且在命令中我以这种方式运行操作:

    class NotifyUnsharedItemsCommand extends CConsoleCommand
    {
        public function run($args)
        {
            $action = Yii::createComponent('application.controllers.actions.NotifyUnsharedItemsAction',$this,'notify');
            $action->run();
        }
    
    }
    

    【讨论】:

    • 我需要照你说的做,反之亦然。
    • 啊,我现在明白了。你不想反之亦然,你想以不超过时间限制的方式执行它。那我的回答不正确,是的。为什么不将它作为 cron 作业运行,然后在 Web 应用程序中使用保存的结果呢?
    【解决方案4】:

    接受我们在 linux 服务器上,对于 Yii 1.1 的实际示例是:

    $run = '/usr/bin/php ' . Yii::getPathOfAlias('root').'/yiic' [command]
    exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $run, '/dev/null', '/dev/null'));
    

    这将在后台运行 Yii 控制台命令。

    【讨论】:

      【解决方案5】:

      Yii 是 PHP -> 您可以使用在http://php.net/manual/en/function.exec.php 指定的标准 php 构造以及页面底部附近的相关方法,具体取决于您想要实现的目标。

      【讨论】:

      • 我需要知道如何执行 CConsoleCommand 的操作。
      【解决方案6】:

      另外,cebe gist 上的另一个非常干净的解决方案:

      <?php
      // ...
      $runner=new CConsoleCommandRunner();
      $runner->commands=array(
          'commandName' => array(
              'class' => 'application.commands.myCommand',
          ),
      );
      
      ob_start();
      $runner->run(array(
          'yiic',
          'idbrights',
      ));
      echo nl2br(htmlentities(ob_get_clean(), null, Yii::app()->charset));
      
      Yii::app()->end();
      

      【讨论】:

      【解决方案7】:

      通常情况下,您应该做的是重构。 将“通用”代码移出 MyCommand 并将其放入位于 components 文件夹中的类中。 现在,您可以将任何头放在“通用”代码之上,而无需更改您的功能。例如:

      受保护的/components/Mywork.php:

      <?php
      class Mywork
      {
          public function doWork()
          {
              $model = new Product();
              $model->title = 'my product';
              ...
              $model->save();
              ...
          }
      }
      

      受保护/控制器/MyworkController.php:

      <?php
      class MyworkController
      {
          public function actionDowork()
          {
              $mywork = new Mywork;
              ...
          }
      }
      

      protected/commands/MyworkCommand.php:

      <?php
      class MyworkCommand extends CConsoleCommand
      {
          public function run($args)
          {
              $mywork = new Mywork;
              ...
          }
      }
      

      这种方法也使测试变得更容易,因为您可以将 Mywork 作为您正在使用的视图之外的单个单元进行测试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-29
        • 1970-01-01
        • 1970-01-01
        • 2013-10-30
        • 1970-01-01
        • 2015-01-31
        • 1970-01-01
        • 2019-11-10
        相关资源
        最近更新 更多