我有以下问题:如何只运行一次php脚本?在人们开始回答这确实是类似或重复的问题之前,请继续阅读...
情况如下,我正在编写自己的MVC框架,并且我已经提出了一个基于模块的系统,因此我可以轻松地为我的框架添加新功能。为此,我创建了一个/ROOT/modules
目录,其中可以添加新模块。
你可以想象,脚本需要读取目录,读取所有php文件,解析它们然后能够执行新功能,但是它必须为所有webbrowsers请求执行此操作。这将使这个任务关于O(nAmountOfRequests * nAmountOfModules),这在每秒有大量用户请求的网站上相当大。
然后我想,如果我要引入一个像$_SESSION['modulesLoaded']
之类的会话变量然后只是检查它是否设置怎么办?这会将负载减少到O(nUniqueAmountOfRequests * nAmountOfModules),但如果我唯一要做的就是读取目录一次,这仍然是一个很大的大O.
我现在拥有以下内容:
/** Load the modules */
require_once(ROOT . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . 'module_bootloader.php');
存在以下代码:
<?php
//TODO: Make sure that the foreach only executes once for all the requests instead of every request.
if (!array_key_exists('modulesLoaded', $_SESSION)) {
foreach (glob('*.php') as $module) {
require_once($module);
}
$_SESSION['modulesLoaded'] = '1';
}
所以现在的问题是,是否有一个解决方案,比如一个超级全局变量,我可以访问并存在于所有请求中,因此我可以创建一个仅存在nAmountOfModules的Big O而不是之前的Big Os?或者是否有另一种方法可以轻松读取模块文件一次?
类似的东西:
if(isFirstRequest){
foreach (glob('*.php') as $module) {
require_once($module);
}
}
答案 0 :(得分:1)
在最基本的表单中,如果要运行一次,并且只运行一次(每次安装,而不是每个用户),请让密集脚本更改服务器状态(添加文件,更改文件,更改文件)记录在数据库中),然后每次发出运行它的请求时检查它。
如果找到匹配项,则表示该脚本已经运行,您可以继续该过程而无需再次运行。
答案 1 :(得分:0)
调用时,锁定文件,在脚本末尾删除文件。只召唤一次。并且不再需要了,在涅ana中消失了。
这自然也是相反的:
<?php
$checkfile = __DIR__ . '/.checkfile';
clearstatcache(false, $checkfile);
if (is_file($checkfile)) {
return; // script did run already
}
touch($checkfile);
// run the rest of your script.
答案 2 :(得分:0)
只需将数组()缓存到文件中,当您上传新模块时,只需删除该文件即可。它必须重新创建自己然后再次设置。
// If $cache file does not exist or unserialize fails, rebuild it and save it
if(!is_file($cache) or (($cached = unserialize(file_get_contents($cache))) === false)){
// rebuild your array here into $cached
$cached = call_user_func(function(){
// rebuild your array here and return it
});
// store the $cached data into the $cache file
file_put_contents($cache, $cached, LOCK_EX);
}
// Now you have $cached file that holds your $cached data
// Keep using the $cached variable now as it should hold your data
应该这样做。
PS :我目前正在重写自己的框架并执行相同的操作来存储此类数据。您还可以使用 SQLite DB 来存储框架所需的所有此类数据,但请确保测试性能并确定它是否符合您的需求。 使用适当的索引,SQLite很快。