問題描述
我看過很多關(guān)于 cron 和 ZF 的帖子,但大多數(shù)解決方案都讓工作運(yùn)行,以供公眾觸發(fā).
I've seen plenty of posts about cron and ZF but most of the solutions leave the job to be run available to triggering by the public.
如果你想設(shè)置一個(gè)只能由cron運(yùn)行的動(dòng)作怎么辦?不是某個(gè)匿名用戶,也不是必須登錄的人?
What if you want to set up an action that can ONLY be run by cron? Not by some anonymous user and not by someone that has to log in?
我使用的解決方案涉及將一個(gè)文件放在我的網(wǎng)絡(luò)根目錄之外,讓它引導(dǎo)足夠的 ZF 來(lái)使用我需要的東西(比如,我不需要視圖),然后從 cron 中點(diǎn)擊它.我的問題是,這是一種最佳實(shí)踐"方式嗎?如果您需要使代碼可通過網(wǎng)絡(luò)訪問,但仍需要防止隨機(jī)用戶找到并運(yùn)行它,該怎么辦?
The solution I am using involved putting a file outside of my web root, having it bootstrap enough of the ZF to use what I need (like, I don't need the view) and then hit that from cron. My questions are, is this a "best practice" way to do this? What if you needed to make the code accessible over the web but still need to prevent random users from finding and running it?
為了說明,這是我正在為從 php 命令行和在同一臺(tái)服務(wù)器上運(yùn)行的 cron 作業(yè)執(zhí)行的操作(有效),如下所示:
For illustration, here is what I am doing (that works) for a cron job run from the php command line, and on the same server, something like this:
* 10 * * * php /Apps/ZF/cronjobs/crontest.php
Webroot 是:/Apps/ZF/someproject/
crontest.php:
crontest.php:
<?php
ini_set('include_path', ini_get('include_path') . ':/Apps/ZF/someproject/library');
define('APPLICATION_PATH','/Apps/ZF/someproject/application');
define('APPLICATION_ENVIRONMENT','test');
//Include the loader (for loading ZF resources)
require_once 'Zend/Loader.php';
//Include the model (to access the Sites model in this case)
require_once(APPLICATION_PATH . '/models/Planets.php');
Zend_Loader::registerAutoload();
$configuration = new Zend_Config_Ini(
APPLICATION_PATH . '/config/config.ini',
APPLICATION_ENVIRONMENT
);
// DB adapter
$dbAdapter = Zend_Db::factory($configuration->database);
// DB table setup
Zend_Db_Table_Abstract::setDefaultAdapter($dbAdapter);
// Whatever code we want to run...
$test = new Model_Planets();
$test->fetchEntries();
Zend_Debug::dump($test);
?>
所以,正如我所說,這行得通,所以我不是在找人給我寫一個(gè)解決方案……只是對(duì)把這個(gè)做得更好"感到好奇.另外,如果我需要通過網(wǎng)絡(luò)訪問它但仍然希望它只能由 cron 運(yùn)行怎么辦?讓它更靈活怎么樣(因?yàn)樵谶@里我硬編碼了一些我懷疑可以變得更加動(dòng)態(tài)的路徑)?
So, as I said, this works so I'm not looking for someone to write me a solution... just curious about doing this "better". Also, what if I needed this to be accessible via the web but still want to keep it only runnable by cron? What about making it more flexible (because here I am hard coding a few paths that I suspect could be made more dynamic)?
我假設(shè)我可以列出允許的服務(wù)器列表,然后使用 $_SERVER['REMOTE_ADDR']
進(jìn)行測(cè)試?
I assume I could make a list of permitted servers, then test that with $_SERVER['REMOTE_ADDR']
?
大家怎么看?建議?我一個(gè)人工作,所以我沒有同事可以在這件事上尋求幫助......在某種程度上,我的同事就是這樣.
What do you all think? Suggestions? I work alone so I have no colleague to ask for help on this... SO is my colleague, in a way.
推薦答案
一種方法是設(shè)置環(huán)境變量.
One way is to set an environmental variable.
所以在你的 crontab 中
So in your crontab
SCRIPT_RUN_ENV=cron
* * * * * foo.php // Whatever your line is
然后,在應(yīng)用程序中,只需檢查:
Then, in the application, just check that:
if (get_env('SCRIPT_RUN_ENV') != 'cron') {
echo "Program cannot be run manually
";
exit(1);
}
現(xiàn)在,任何人都可以將他們的環(huán)境變量設(shè)置為該值并成功運(yùn)行 cron,但它應(yīng)該停止瑣碎的運(yùn)行(或意外)...
Now, anyone can set their environmental variable to that value and successfully run the cron, but it should stop the trivial running (or accidental)...
但還要注意,任何可以在服務(wù)器上編輯環(huán)境變量的人都可以執(zhí)行它,所以沒有真正的方法從那個(gè)角度來(lái)保護(hù)它(至少?zèng)]有一個(gè)是自動(dòng)化的)......還值得注意的是你無(wú)法通過 HTTP 注入環(huán)境變量.
But also note that anyone who can edit the environmental variable on the server can already execute it, so there's no real way to secure it from that angle (none that are automated at least)... It's also worth noting that you cannot inject an environmental variable through HTTP.
這篇關(guān)于使用 Zend 框架安全地運(yùn)行 Cron 作業(yè)的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!