You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP会话计数器无法持久化:点击按钮后新值不保存

问题描述

点击按钮时,计数器会被正确修改,但新值无法保存供下次操作使用。具体表现为:点击按钮后,计数器应根据点击的按钮减少1或2,首次操作正常,但再次点击时会使用初始值6进行计算,而非上次操作后的结果。尝试过多种保存计数器的方式(如&$_SESSION["teller"]=$teller),但均无效,计数器始终重置为初始值6。

问题代码
<?php
// luciferSpel.php

declare(strict_types=1);

session_start();

if(!isset($_SESSION["lucifer"])) { 
   $_SESSION["lucifers"] = array_fill(0,7,"lucifer");
   $_SESSION["teller"] = 6;
}


if (isset($_GET['reset']) && $_GET['reset'] == 1) { 
    unset($_SESSION["lucifers"]); 
    unset($_SESSION["teller"]);
    header("Location: " .$_SERVER["PHP_SELF"]);
    exit;
}

$lucifers = &$_SESSION["lucifers"];
$teller = &$_SESSION["teller"];

if (isset($_POST["min1"]) && $teller >= 0) {
    unset($lucifers[$teller]);
    $teller --;
}

if (isset($_POST["min2"]) && $teller >=1) {
    unset($lucifers[$teller],$lucifers[$teller-1]);
    $teller -= 2;
}

if ($teller === -1) {
    header("Location: luciferSpelAfgelopen.php ");
    exit;
}

?>

<!DOCTYPE HTML>
<html>
<head>
<meta charset=utf-8>
<title>Luciferspel</title>
</head>
<body>
    <h1>Luciferspel</h1>
    <?php echo $teller; echo count($lucifers) ?>
        <?php for ($f=0; $f < count($lucifers); $f++) :?>
                <img src="img/lucifer.png" alt="lucifer" />     
            <?php endfor; ?>
    <form method="post">
            <button type="submit" name="min1">Een lucifer wegnemen
            </button> 
            <button type="submit" name="min2">Twee lucifers wegnemen
            </button>
    </form>
    <p>Klik <a href="?reset=1" >hier</a> om een nieuw spel te starten.</p>
</body>
</html>
解决方案

核心问题

代码里初始化session的判断条件写错了:!isset($_SESSION["lucifer"]) 应该改为 !isset($_SESSION["lucifers"])(注意变量名的复数形式)。原判断中检查的是不存在的lucifer键,导致每次请求都会重新初始化$_SESSION["lucifers"]和$_SESSION["teller"],所以计数器永远会被重置为初始值6。

修改后的完整代码

<?php
// luciferSpel.php

declare(strict_types=1);

session_start();

// 修正session判断的变量名
if(!isset($_SESSION["lucifers"])) { 
   $_SESSION["lucifers"] = array_fill(0,7,"lucifer");
   $_SESSION["teller"] = 6;
}


if (isset($_GET['reset']) && $_GET['reset'] == 1) { 
    unset($_SESSION["lucifers"]); 
    unset($_SESSION["teller"]);
    header("Location: " .$_SERVER["PHP_SELF"]);
    exit;
}

$lucifers = $_SESSION["lucifers"];
$teller = $_SESSION["teller"];

if (isset($_POST["min1"]) && $teller >= 0) {
    unset($lucifers[$teller]);
    // 重置数组索引,避免for循环跳过元素
    $lucifers = array_values($lucifers);
    $teller --;
    // 更新session中的值
    $_SESSION["lucifers"] = $lucifers;
    $_SESSION["teller"] = $teller;
}

if (isset($_POST["min2"]) && $teller >=1) {
    unset($lucifers[$teller],$lucifers[$teller-1]);
    // 重置数组索引
    $lucifers = array_values($lucifers);
    $teller -= 2;
    // 更新session中的值
    $_SESSION["lucifers"] = $lucifers;
    $_SESSION["teller"] = $teller;
}

if ($teller === -1) {
    header("Location: luciferSpelAfgelopen.php");
    exit;
}

?>

<!DOCTYPE HTML>
<html>
<head>
<meta charset=utf-8>
<title>Luciferspel</title>
</head>
<body>
    <h1>Luciferspel</h1>
    <?php echo $teller; echo " | 剩余火柴数:" . count($lucifers) ?>
        <?php foreach ($lucifers as $lucifer) :?>
                <img src="img/lucifer.png" alt="lucifer" />     
            <?php endforeach; ?>
    <form method="post">
            <button type="submit" name="min1">移除1根火柴</button> 
            <button type="submit" name="min2">移除2根火柴</button>
    </form>
    <p>点击 <a href="?reset=1" >这里</a> 开始新游戏。</p>
</body>
</html>

额外优化点

  1. 去掉了不必要的引用赋值(&),直接操作变量后更新session,逻辑更清晰。
  2. 使用array_values()重置数组索引:因为unset()会保留原数组的索引,导致后续for循环遍历数组时跳过缺失的索引,显示的火柴数量和实际不符。改用foreach遍历数组,或者重置索引后用for循环,都能解决这个问题。
  3. 优化了页面显示的文本,让剩余数量的展示更直观,按钮文字也调整为中文(需要保留原荷兰语可自行改回)。

内容的提问来源于stack exchange,提问作者Kara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:31:03