1

我有以下问题:如何只运行一次 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 O?还是有另一种方法可以轻松读取模块文件一次?

就像是:

if(isFirstRequest){
    foreach (glob('*.php') as $module) {
        require_once($module);
    }
}
4

3 回答 3

1

在最基本的形式下,如果你想运行一次,并且只运行一次(每次安装,而不是每个用户),让你的密集脚本更改服务器状态的某些内容(添加文件,更改文件,更改记录数据库),然后在每次发出运行它的请求时对其进行检查。

如果您找到匹配项,则意味着脚本已经运行,您可以继续该过程而无需再次运行它。

于 2012-10-24T11:57:53.163 回答
0

调用时,锁定文件,在脚本结束时,删除文件。只调用一次。也因此不再需要,消失于涅槃。

这自然也可以反过来:

<?php

$checkfile = __DIR__ . '/.checkfile';

clearstatcache(false, $checkfile);

if (is_file($checkfile)) {
    return; // script did run already
}
touch($checkfile);

// run the rest of your script.
于 2012-10-24T11:56:49.683 回答
0

只需将array()缓存到文件中,当您上传新模块时,只需删除该文件。它必须重新创建自己,然后你又重新设置好了。

// 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 很快。

于 2012-10-24T12:55:25.643 回答