【发布时间】:2013-09-29 11:06:04
【问题描述】:
您好,我想通过 cronjob 执行一个函数来启动 csv 导入。目前通过访问浏览器中的控制器触发导入 tld.de/Update
控制器有这个代码http://pastie.org/8351266
如何通过 Cronjob 执行 函数 init()?
谢谢!
【问题讨论】:
标签: php cron silverstripe
您好,我想通过 cronjob 执行一个函数来启动 csv 导入。目前通过访问浏览器中的控制器触发导入 tld.de/Update
控制器有这个代码http://pastie.org/8351266
如何通过 Cronjob 执行 函数 init()?
谢谢!
【问题讨论】:
标签: php cron silverstripe
在 SilverStripe 中,您也可以通过在命令行中运行 cli-script.php 来访问任何可通过 HTTP 访问的路由
还有sake,它只是 cli-script.php 的一个 bash 包装器(但需要安装清酒)
所以,从您的项目目录中,您可以运行将执行相同操作的两个命令(在这种情况下,运行 dev/build):
php framework/cli-script.php dev/build
sake dev/build
有关 silverstripe 的命令行用法,请参阅文档:http://doc.silverstripe.org/framework/en/topics/commandline
您的问题的第二部分(如何从控制器调用方法)实际上更多的是 silverstripe 中的路由问题,与调用方式无关(cronjob)
我假设您的控制器是 Page_Controller 或其子类(因此绑定到 SiteTree 模型),然后为您完成路由(它采用您在 CMS 中设置的 URL)。
所以让我们看一些示例代码并假设您有一个带有 URLSegment about 的页面:
class Page_Controller extends ContentController {
private static $allowed_actions = array('something');
public function init() {
// the init method will run before every action
// this means this code will run, no matter if you visit /about or /about/something
}
public function index() {
// this is the default action (this code is optional and can be removed),
// and will be called if you visit website.com/about
return $this;
}
public function something() {
// this is the somethingaction,
// and will be called if you visit website.com/about/something
// do something here
return $this;
}
}
然后您可以调用 run 来获取 index() 的结果:
php framework/cli-script.php about
这得到something()的结果:
php framework/cli-script.php about/something
注意:init 方法本身不能通过 URL 访问,它是在操作之前运行的“设置”
注意:除 @ 之外的所有操作987654331@ 必须通过将它们添加到 $allowed_actions 来允许(另请注意,添加到 $allowed_actions 后您需要 ?flush=1 以重新加载配置缓存)
编辑:这实际上是对您的第一个问题的回应,在看到您的代码示例后,添加:
对于独立控制器,它的工作方式相同,只是您必须定义路由,并确保路由中有$Action,以便可以调用something()
【讨论】:
没有 Silverstripe 的缘故,您也可以做到这一点。安装 curl 并通过 cronjob 调用 URL,即:
0 0 * * * curl --silent http://tld.de/Update
执行此操作的正确方法是编写 Silverstripe 任务,并从任务中调用您的控制器。我还没有测试过这段代码,但它会是这样的:
class YourTask extends BuildTask {
public $description = "...";
//...
public function run($request) {
YourController::init();
}
}
您可以通过以下方式调用它:
0 0 * * * /path/to/framework/sake dev/tasks/YourTask
【讨论】:
为什么不创建一个构建任务?专为此类要求而设计(至少我是这样考虑构建任务的)
<?php
class ArticleCsvUpdateTask extends BuildTask {
protected $title = 'Article Csv Update';
protected $description = 'Build task for article Csv update';
public function run($request) {
$loader = new ArticleCsvBulkLoader('Color');
if($loader->load('import-new.csv')) {
$loader->load('import-new.csv');
}
}
}
可以使用“yoursite/dev/tasks/ArticleCsvUpdateTask”从浏览器和使用“php framework/cli-script.php dev/tasks/ArticleCsvUpdateTask”或使用“sake dev/tasks/ArticleCsvUpdateTask”(如果您安装了sake)。
可能我没有得到您的确切要求,但我相信这是使用 silverstripe 运行 cron 作业的更清洁和更好的方式。
【讨论】:
请参阅Zauberfisch's answer 以获得完整的解决方案
我对 Silverstripe 不熟悉,但如果我理解正确的话,这个控制器 init 函数可以通过 HTTP 请求调用。
正如 silverstripe 文档所说,您可以从命令行调用任何 url:
php framework/cli-script.php Update/init
更多信息请参见here,并考虑使用sake 完成此任务。
【讨论】:
我认为正确的做法是创建一个 php 文件控制台,例如:
#!/usr/bin/env php
<?php
require_once "/path/to/your/class/Update.php";
$class = new Update();
$class->init();
给这个文件添加权限
chmod 755 consolefile
最后用 cronjob 运行这个脚本
【讨论】: