奇怪和疯狂的 PHP 错误,清除浏览器历史记录后的页面加载导致脚本多次运行 [重复]

Posted

技术标签:

【中文标题】奇怪和疯狂的 PHP 错误,清除浏览器历史记录后的页面加载导致脚本多次运行 [重复]【英文标题】:Strange & Insane PHP Bug, Page load after clearing browser history causes script to run multiple times [duplicate] 【发布时间】:2020-04-25 13:51:56 【问题描述】:

基本上我正在为一个大学项目创建一个 php 框架 一切正常,除了一个奇怪的错误使所有 PHP SESSION 代码在请求生命周期后重复。

我已经编辑了我原来的问题,希望它更简单,更重要。 我做了一些进一步的测试,现在我可以看到发生了什么,但我不明白为什么。

我正在使用 DOMDocument 进行模板化,它正在运行 UNEXPECTED CODE 并通过在脚本结束后运行与会话相关的任何代码来导致脚本产生奇怪的结果。

基本上我正在使用一个简单的计数器功能测试会话和请求生命周期。

这里是代码和请求生命周期:

//Session config from config file:
const SESSION = [
'name' => 'MAPSID',
'storage' => 'files',
'options' => [
    //'read_and_close' => true,
    'cookie_lifetime' => false,
    'use_strict_mode' => true,
    'use_only_cookies' => 1,
    'cookie_httponly' => 1,
    'use_trans_sid' => 0,
    //Ensure this is true for production:
    'cookie_secure' => false
    ],
];
session_name(SESSION['name']);

//index.php:
define('MAP_INITIALIZE', microtime(true));
require_once __DIR__.'/../env.php';
session_start(SESSION['options']);
require_once __DIR__.'/../vendor/autoload.php';

//Set Session counter to 0 if not set
if (!isset($_SESSION['count'])) 
    $_SESSION['count'] = 0;


var_dump("SESSION count before increment:");
//Shows perfectly first time, then increments by 3, then by 2,
//Instead of one
var_dump($_SESSION['count']);

//Increment code which duplicates god knows where
$_SESSION['count']++;
var_dump($_SESSION['count']);

$app = map\factory\MapFactory::create_app();

$app->start(function ($request, $response)
    $response->capture(
        $request->route()
    );
    $response->send();
);

//App start method:
public function start(callable $initfunc=null)

    //Checks no illegal patterns in the URL, etc
    if ($this->request->is_valid()) 
        if (is_callable($initfunc)) 
            call_user_func_array(
                $initfunc,[$this->request, $this->response]
            );
        
    else
        $this->response->invalid();
    


//request is_valid:
public function is_valid()
    if (filter_var($url, FILTER_SANITIZE_URL)) 

        if ($url == '/') 
            return true;
        

        if (!preg_match_all("/^\/[A-Za-z0-9\/\?\&\=\-\%]+$/", $url)) 
            return false;
        

        if (preg_match_all("/\/\//", $url)) 
            return false;
        

        return true;

    else 
        return false;
    


//Route Request:
//I dont think this should matter as its the default index page,
no routes used
public function route()
   
    $route = $this->create_router(new Router(
         $this->path,
         $this->client->user)
    );
    include APP.'/routes/routes.php';
    return $route->response();


//Capture response:
public function capture($res)

    if ($res === false) 
        $this->not_found();
    elseif (is_string($res)) 

        //If I call this function, and then echo the response,
        //$_SESSION['count'] double increments,
        //and triple for the first request,
        $this->valid($response);

        //If I directly add the response without the valid method,
        //then the first refresh increments by 2 and then by 1
        //like so:
        $this->response = $res;//there is no error
    elseif (is_null($response)) 
        echo "Deal with this later";
     else 
        $this->invalid();
    


//Valid response method:
public function valid($response)

    $mapdom = file_get_contents(APP.'/main.html');
    $mapdom = new HTMLDom($mapdom);
    $root = $mapdom->getElementById('root');
    $response = new HTMLDom($res);
    $domelem = $response->body->firstChild;
    $import = $mapdom->importNode($domelem, true);
    $root->appendChild($import);
    $mapdom->save_html();
    $this->response = $mapdom->dom;


//send response:
public function send()
    foreach ($this->headers as $header) 
        header($header);
    
    $this->response = 'some string';//No error
    echo $this->response;

基本上,当我使用 $this->valid() 函数时,第一个请求的增量三倍,然后加倍, 如果我不使用它,它会在第一个请求时加倍,然后加一, 这里显然有一个模式,我正在努力弄清楚。 尝试在 PHPStorm 中使用调试器,没有错误,它只是 var_dump() 输出不正常,让我想知道,错误是什么

我希望这个问题没有模棱两可,任何建议将不胜感激!很高兴提供完整的源代码 请有人能告诉我哪里出错了 谢谢

【问题讨论】:

您是否将会话设置为自动启动?还是您在其他任何地方调用session_start();?您是否检查过您的 HTTP 标头并确认您正在接收 GET 和/或 POST(大写)?或者$_SERVER['request_method'] 发送的是正确的值? Auth::form() 是否在其他任何地方被调用?您是否尝试过使该方法成为非静态方法? 另外,$app->response->send(); 是做什么的? 我将为 Session 处理程序创建包装类,看看它是否修复它 那个函数只是回显响应,我已经为它添加了代码 不是全部在单独的文件中,如果有帮助我会添加生命周期的所有代码 【参考方案1】:

在我回答我自己的问题之前,我会说我很傻,但希望这对其他人也有帮助。

当使用任何前端控制器模式或服务器重定向时,我必须确保在公共文件夹的根目录中保留一个 favicon.ico,以应对浏览器的请求。 由于 Apache 会将所有无效文件重定向到 index.php,因此如果不是实际图像,保留 favicon.ico 虚拟文件至关重要。

如果此文件丢失,apache 将根据重写规则将其重定向到 index.php,这将导致脚本再次运行,这可能会损坏会话变量并产生意想不到的问题和结果,因为我永远不会最疯狂梦想已经猜到会和问题有关,如果不是这个答案:https://***.com/a/19761612/11995521

【讨论】:

以上是关于奇怪和疯狂的 PHP 错误,清除浏览器历史记录后的页面加载导致脚本多次运行 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

chrome退出清除历史记录

如何清除/禁用 UIWebView 的浏览历史记录

google浏览器主页几个历史记录怎么删除啊(如图)

Window 任务栏清除历史记录

怎么清除历史纪录和Internet临时文件

Edge浏览器怎样设置退出时删除浏览历史记录?