我正在尝试构建一个调用控制器中特定操作的cronjob。我编写的shell脚本似乎无法在调用之前绕过控制器。
我想过使用会话但到目前为止还没有运气。这是代码:
<?php
if (!isset($_SESSION)) session_start();
class MyShell extends AppShell
{
public function main() {
$_SESSION['toBypassBeforeFilter'] = "true";
CakeLog::write('debug', 'Calculating WIP...');
$this->requestAction('/account/wip_reports');
CakeLog::write('debug', 'Finishing WIP calculations...');
}
}
调试日志在动作调用之前写出第一个。
2015-10-05 02:08:49 Debug: Calculating WIP...
但是当动作调用完成时,不是第二个。我错过了什么?
修改
即使我仍然可以在浏览器中运行它,看起来对该路由的requestAction()调用是不可识别的。也许它应该是一条不同的路线?
答案 0 :(得分:3)
一般来说,使用requestAction
表示应用程序架构不佳。使用CakePHP的running cron jobs的正确方法是编写a cli process来调用实际直接执行操作的方法,而不是使用模拟http请求的cli进程。
在cli上下文中,shell是一个控制器 - 控制器代码应始终保持为minium。而目前你已经得到了这个:
class MyShell extends AppShell
{
public function main()
{
$this->requestAction('/account/wip_reports');
}
}
而且:
class AccountsController extends AppController
{
public function wip_reports()
{
... some code ...
}
}
原则上你应该拥有的是:
class MyShell extends AppShell
{
public function main()
{
$account = ClassRegistry::init('Account');
$account->something();
}
而且:
class AccountsController extends AppController
{
public function wip_reports()
{
$this->Account->something();
}
}
使用模型中的所有相关逻辑:
class Account extends AppModel
{
public function something()
{
... some code ...
}
}
通过这种方式,shell根本不依赖于控制器,甚至不与控制器交互 - 它只是调用控制器操作方法所使用的相同方法。
答案 1 :(得分:1)
嗯,你正在滥用控制器来解决不的问题,你现在必须面对这种滥用的结果。会话也不会在shell环境中可用。
重构代码,以便业务逻辑驻留在可从shell环境调用的模型或其他类中,并且不依赖于Web环境。