Yii2-从控制台控制器调用Web控制器时出错

时间:2018-05-31 05:43:24

标签: controller yii2 yii2-advanced-app cron-task

我正在研究yii2。我的控制器中有一个名为create的{​​{1}}操作。

MeterpingController

以下是两个功能

class MeterpingController extends Controller
{
     public function beforeAction($action)
    {

    if ($action->id == 'create') {
        $this->enableCsrfValidation = false;
    }

    return parent::beforeAction($action);

   }

   public function actionCreate()
   {
      foreach ($record as $item){

        // var_dump($item->MSN);
         $date_time = str_replace('T', ' ', $item->PingDateTime);
        if($this->isSaved($item->MSN))
        {
           // return true;
        }
        else if($this->isVerified($item->MSN))
        {
            // return true;
        }
        else if($this->ogpCreated($item->MSN,$date_time))
        {
            $m = new MeterPing;
            $m ->load(Yii::$app->request->post());
            $m->start_date_time = str_replace('T', ' ', $start_time);
            $m->end_date_time = str_replace('T', ' ', $end_time);

           $m->meter_msn = $item->MSN;
           $m->meter_id = Meters::msnmapToid($m->meter_msn);
           $m->meter_type = Meters::mType($m->meter_msn);
           $m->sub_div_code = Ogpdetail::msnTosubdiv($item->MSN);
           $m->sub_div_name = Ogpdetail::subDivToName($m->sub_div_code);
           $m->meter_ping_date_time = str_replace('T', ' ', $item->PingDateTime);
        $m->save();
        }


    }
    return $this->redirect(['index']);
   }
}

我有一个控制台控制器,我试图调用上面的 public static function isVerified($msn) { $meter = Installations::find()->where(['meter_msn'=>$msn])->one(); if($meter) return true; return false; } public static function ogpCreated($msn,$date_time){ $meter = Ogpdetail::find()->where(['meter_serial' => $msn])->one(); if($meter) { if($date_time>$meter['created_at']) return true; return false; } else{ return false; } }

action

namespace console\controllers; use yii\console\Controller; use Yii; class CronController extends Controller { public function actionIndex() { Yii::$app->controllerNamespace = "backend\controllers"; Yii::$app->runAction('meterping/create'); } } 我正在使用以下命令

cmd

我得到的错误是

E:\xampp\htdocs\inventory-web>php yii cron

以前我直接从Stack trace: #0 E:\xampp\htdocs\inventory- web\backend\controllers\MeterpingController.php(126): backend\controllers\MeterpingController::isVerified('002999001152') #1 [internal function]: backend\controllers\MeterpingController- >actionCreate() #2 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\base\InlineAction.php(57): call_user_func_array(Array, Array) #3 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\base\Controller.php(156): yii\base\InlineAction- >runWithParams(Array) #4 E:\xampp\htdocs\inventory-web\vendor\yiisoft\yii2\base\Module.php(523): yii\base\Controller->runAction('create', Array) #5 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\console\Application.php(180): yii\base\Module- >runAction('meterping/creat...', Array) #6 E:\xampp\htdocs\inventory-web\console\controllers\CronController.php(24): yii\console\Application->runAction('meterping/creat...') #7 [internal function]: console\controllers\CronController->actionIndex() #8 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\base\InlineAction.php(57): call_user_func_array(Array, Array) #9 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\base\Controller.php(156): yii\base\InlineAction- >runWithParams(Array) #10 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\console\Controller.php(128): yii\base\Controller- >runAction('', Array) #11 E:\xampp\htdocs\inventory-web\vendor\yiisoft\yii2\base\Module.php(523): yii\console\Controller->runAction('', Array) #12 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\console\Application.php(180): yii\base\Module- >runAction('cron', Array) #13 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\console\Application.php(147): yii\console\Application->runAction('cron', Array) #14 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\base\Application.php(380): yii\console\Application- >handleRequest(Object(yii\console\Request)) #15 E:\xampp\htdocs\inventory-web\yii(27): yii\base\Application->run() #16 {main} 拨打echo并使用相同的命令我能够看到正确的结果。但是从另一个控制器调用actionIndex()似乎不起作用。

注意:我想按计划调用它,这就是我创建一个cron作业的原因。

如何将代码设置为不在action中显示此错误?

更新1

根据建议并遵循此link

我做了以下

  1. cmd文件夹下创建了一个components文件夹。
  2. 在组件文件夹

    中创建自定义组件
    common
  3. namespace common\components; use Yii; use yii\base\Component; use yii\base\InvalidConfigException; use app\models\Installations; use app\models\Meters; use common\models\MeterPing; use common\models\MeterpingSearch; use common\models\Ogpdetail; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Reader\Xls\Style; public function create() { //...My code }

    中注册了该组件
    common/config/main-local.php
  4. 在我的网络控制器中,我做了以下

     'components' => [
    
       'pingManager' => [
    
          'class' => 'common\components\MyComponent',
    
          ],
        ]
    
  5. 现在,当我尝试通过网络访问它时,它会给我发出错误信息

    Yii::$app->pingManager->create();
    return $this->redirect(['index']);
    

    更新2

    我错过了班级名称,因此我将其更新为Unable to find 'common\components\MyComponent' in file: E:\xampp\htdocs\inventory-web\common/components/MyComponent.php. Namespace missing? 并通过网络访问。它确实有效。现在,当我尝试通过控制台运行它时,我遇到了错误。

    MyComponent

    Exception 'Error' with message 'Class 'app\models\Installations' not found' in E:\xampp\htdocs\inventory-web\common\components\MyComponent.php:89 Stack trace: #0 E:\xampp\htdocs\inventory-web\common\components\MyComponent.php(65): common\components\MyComponent::isVerified('002999001064') #1 E:\xampp\htdocs\inventory- web\backend\controllers\MeterpingController.php(148): common\components\MyComponent->create() #2 [internal function]: backend\controllers\MeterpingController- >actionCreate() #3 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\base\InlineAction.php(57): call_user_func_array(Array, Array) #4 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\base\Controller.php(156): yii\base\InlineAction- >runWithParams(Array) #5 E:\xampp\htdocs\inventory-web\vendor\yiisoft\yii2\base\Module.php(523): yii\base\Controller->runAction('create', Array) #6 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\console\Application.php(180): yii\base\Module- >runAction('meterping/creat...', Array) #7 E:\xampp\htdocs\inventory-web\console\controllers\CronController.php(24): yii\console\Application->runAction('meterping/creat...') #8 [internal function]: console\controllers\CronController->actionIndex() #9 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\base\InlineAction.php(57): call_user_func_array(Array, Array) #10 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\base\Controller.php(156): yii\base\InlineAction- >runWithParams(Array) #11 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\console\Controller.php(128): yii\base\Controller- >runAction('', Array) #12 E:\xampp\htdocs\inventory-web\vendor\yiisoft\yii2\base\Module.php(523): yii\console\Controller->runAction('', Array) #13 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\console\Application.php(180): yii\base\Module- >runAction('cron', Array) #14 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\console\Application.php(147): yii\console\Application->runAction('cron', Array) #15 E:\xampp\htdocs\inventory- web\vendor\yiisoft\yii2\base\Application.php(380): yii\console\Application- >handleRequest(Object(yii\console\Request)) #16 E:\xampp\htdocs\inventory-web\yii(27): yii\base\Application->run() #17 {main} 号码为89

    任何帮助都将受到高度赞赏。

1 个答案:

答案 0 :(得分:0)

这可能不是您预期的答案,但您应该首先避免这个问题。如果需要从不同的地方调用控制器操作代码,则可能在应用程序中存在一些设计问题。控制器应该很小,不包含任何高级逻辑或可重用代码。如果你需要从不同的地方调用控制器动作,这个动作可能太胖了,你应该提取它的逻辑来分离组件或帮助器。所以在你的情况下:

创建组件并将操作逻辑提取到其中:

class PingManager extends \yii\base\Component {

    public function create($record, $start_time, $end_time, $data) {
        foreach ($record as $item) {
            $date_time = str_replace('T', ' ', $item->PingDateTime);
            if ($this->isSaved($item->MSN)) {
                // return true;
            } else {
                if ($this->isVerified($item->MSN)) {
                    // return true;
                } else {
                    if ($this->ogpCreated($item->MSN, $date_time)) {
                        $m = new MeterPing();
                        $m->load($data);
                        $m->start_date_time = str_replace('T', ' ', $start_time);
                        $m->end_date_time = str_replace('T', ' ', $end_time);

                        $m->meter_msn = $item->MSN;
                        $m->meter_id = Meters::msnmapToid($m->meter_msn);
                        $m->meter_type = Meters::mType($m->meter_msn);
                        $m->sub_div_code = Ogpdetail::msnTosubdiv($item->MSN);
                        $m->sub_div_name = Ogpdetail::subDivToName($m->sub_div_code);
                        $m->meter_ping_date_time = str_replace('T', ' ', $item->PingDateTime);
                        $m->save();
                    }
                }
            }
        }
    }

    private function isSaved($msn) {
        // todo
    }

    private function isVerified($msn) {
        $meter = Installations::find()->where(['meter_msn' => $msn])->one();
        if ($meter) {
            return true;
        }

        return false;
    }

    private function ogpCreated($msn, $date_time) {
        $meter = Ogpdetail::find()->where(['meter_serial' => $msn])->one();
        if ($meter) {
            return $date_time > $meter['created_at'];
        }

        return false;
    }
}

在应用配置中注册组件:

'components' => [
    'pingManager' => [
        'class' => PingManager::class,
    ],
    // ...
],

在控制台控制器中使用它:

class CronController extends Controller {

    public function actionIndex() {
        // initialize $record, $start_time, $end_time, $data

        Yii::$app->pingManager->create($record, $start_time, $end_time, $data);
    }
}

在网络控制器中:

class MeterpingController extends Controller {

    public function beforeAction($action) {
        if ($action->id == 'create') {
            $this->enableCsrfValidation = false;
        }

        return parent::beforeAction($action);
    }

    public function actionCreate() {
        // initialize $record, $start_time, $end_time

        Yii::$app->pingManager->create($record, $start_time, $end_time, Yii::$app->request->post());
        return $this->redirect(['index']);
    }
}