我有一个 PHP / MySQL 网站,我想输出主页上数据库/表中的条目数,但我不希望每次都进行此查询用户点击主页。我希望它每天自动运行一次并将查询结果输出到一个平面文件,然后我可以将其包含在内。我认为应该减少负荷。
我以前从未做过cron工作,也不熟悉Unix系统/命令。我的网站是一个拥有Plesk控制面板的ISP,我看到一个“crontab”部分,可以让我设置cron作业。
我不太确定要输入什么“命令”。我可以很好地制定查询,但不确定如何将结果输出到我可以通过PHP包含的平面文件。另外,理想情况下,平面文件将出现在Web根目录(与站点的其余部分)并且每天都会覆盖自己,我不想在年底使用365个平面文件。
答案 0 :(得分:5)
您应该编写一个独立的PHP脚本来完成所有工作,并将其添加到您的crontab中,如下所示:
0 2 * * * cd /path/to/script; /usr/bin/php daily.php 1> output.txt 2> errors.log
每隔凌晨2点,您的daily.php
脚本就会运行,输出位于output.txt
,生成的任何错误(启用display_errors)都会在errors.log
中结束。与将查询直接放入cron相比,这有一些优点:
在PHP页面中包含数据的最简单,最安全的方法可能是serialize()来自查询的一系列结果,然后在需要时反序列化():
// daily.php
$data = array(
'rows_in_table_foo' => 2343, // replace this with a query result
'rows_in_table_bar' => 4321, // replace this with a query result
);
echo serialize($data);
exit 0;
......并阅读它......
// index.php
$data = unserialize(file_get_contents('output.txt'));
答案 1 :(得分:2)
如果没有进一步了解您的托管系统,这可能有点棘手。如果有一个mysql命令行客户端可用,您可以尝试这样的事情:
/usr/bin/mysql -u db_user --password=db_password -e "SELECT COUNT(*) INTO OUTFILE '/tmp/myoutfile.txt' FROM my_table;" my_database
请注意,您必须在此调用中替换“db_user”,“db_password”等内容。另请注意,/usr/bin
恰好是客户端在我的系统上的目录。它可能在您的托管平台上有所不同。
如果Web前端允许您直接执行shell命令,我会首先尝试这种方式,因为如果出现错误或丢失,这应该会给您更好的反馈。
如果您对编写PHP感觉更舒服,另一种解决方案是编写一个小的PHP脚本来完成创建/更新文件的工作,并在您的crontab中调用该脚本:
/path/to/php/bin/php /path/to/my/phpscript.php
当然,这取决于系统上可用的PHP命令行版本。
答案 2 :(得分:1)
对于你问题的crontab部分,你可以在你的crontab中添加这样的东西(使用命令“crontab -e”编辑它):
0 0 * * * COMMAND TO EXECTUTE QUERY > THE_FILE
每天只执行查询并将其结果传递给THE_FILE,并将其内容覆盖。
crontab条目的格式为:
minutes hours day_of_month month day_of_week COMMAND
答案 3 :(得分:0)
首先关闭它的名为“cron”并且它很容易实现..查看一些关于它的信息:http://en.wikipedia.org/wiki/Cron和入门指南:http://www.unixgeeks.org/security/newbie/unix/cron-1.html。
您希望在此网站上看到多少流量?我不明白为什么在大多数情况下解雇查询会是个大问题......
答案 4 :(得分:0)
总结一下你的问题。你想缓存查询结果,你是怎么做到的?
在回答问题之前,您提出了一个解决方案(存储在平面文件中)。当然,你可以做到这一点。但是,如果要创建一些基础结构,为什么不编写缓存数据类并缓存各种内容。它可以有3个属性
- 缓存项目名称 - 缓存项目值 - 缓存项目上次更新时间戳
添加几个功能
function loadCachedData($itemName);
//see if more time has passed than in the cache expiration window
function isLoadedDataFresh($expirationWindowInSeconds);
function getLoadedItemValue();
function storeCacheValueForItem($itemName, $value);
您必须编写查询以选择项目,因此在您的控制器中,只需执行以下操作:
$cacheHandle = new Cache();
$cacheHandler->loadCachedData('whateverMyVarIs');
$displayValue = '';
if($cacheHandler->isLoadedDataFresh(60 * 60 * 24) ) //sec*min*hour = 1 day
{
$displayValue = $cacheHandler->getLoadedItemValue();
}
else
{
//update the display value here with your real query
$displayValue = doMyStuff();
$cacheHandler->storeCacheValueForItem('whateverMyVarIs', $displayValue);
}
当然,你必须清除那些代码的地狱,将你的到期时间窗口变成常量,然后实现这个类,但这不应该太难。另外,你已经拥有了一个数据库..只需用它来支持缓存类,然后缓存掉!或者如果你想使用更好的工具进行快速缓存,请使用memcached !! http://www.danga.com/memcached/
但最后,我只想问......你是否过早地进行了优化?有人真的抱怨过这个页面上的表现吗?