我正在努力
yii2
。我的控制器中有一个名为 create
的 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()
并使用相同的命令我能够看到正确的结果。但是从另一个控制器调用 action
似乎不起作用。
注意: 我想按计划调用它,所以这就是我创建 cron 作业的原因。
如何将我的代码设置为不在
cmd
中显示此错误?
更新1
根据给出的建议并遵循此链接
我已经做了以下事情
components
文件夹下创建了common
文件夹。 在组件文件夹中创建自定义组件
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
中注册组件
'components' => [
'pingManager' => [
'class' => 'common\components\MyComponent',
],
]
在我的网络控制器中我已经完成了以下操作
Yii::$app->pingManager->create();
return $this->redirect(['index']);
现在,当我尝试通过网络访问它时,出现以下错误
Unable to find 'common\components\MyComponent' in file: E:\xampp\htdocs\inventory-web\common/components/MyComponent.php. Namespace missing?
更新2
我缺少类名,因此我将其更新为
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
号码是$meter = Installations::find()->where(['meter_msn'=>$msn])->one();
任何帮助将不胜感激。
这可能不是您期望的答案,但您应该首先避免这个问题。如果您需要从不同的地方调用控制器操作代码,您的应用程序中可能存在一些设计问题。控制器应该很薄,并且不包含任何高级逻辑或可重用代码。如果您需要从不同的地方调用控制器操作,则此操作可能太胖,您应该将其逻辑提取到单独的组件或助手中。所以在你的情况下:
创建组件并将操作逻辑提取到其中:
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']);
}
}