Cookie引发麻烦-Can';Don’不要留下饼干


Cookies causing trouble - Can't make a cookie stay

我遇到了一种cookie情况,我的cookie会存储一个颜色名称,或者什么都不存储。让我们这样解释吧。我的cookie与我的网站外观有关,我的网站有3个外观:

  • 正常(完全没有cookie)
  • 灰色(cookie设置为"imgit_style",值为"灰色")
  • 反转(cookie设置为"imgit_style",值为"反转")

我有3个按钮可以触发样式的切换。第一个按钮用于Normal,它删除cookie并使其看起来正常。

第二个按钮用于Grey,它创建名为"imgit_style"的cookie,并为其添加一个值-"灰色"。

这两个可以完全配合使用,但当设置倒置cookie时,它就不起作用了!当我点击第三个按钮时,它就会被删除,该按钮实际上应该用倒置替换灰色(如果设置了),或者如果第一个按钮未设置,则创建cookie。

希望我足够清楚。这是我的代码:

Styles.php

<?php
$style = '';
if (!isset($_COOKIE['imgit_style']))
{
    if (isset($_POST['green']))
    {
        setcookie('imgit_style', '', time()-31556952);
        $style = '';
    }
    if (isset($_POST['grey']))
    {
        setcookie('imgit_style', 'grey', time()+31556952);
        header('Location: ' . $home_action);
    }
    if (isset($_POST['inverted']))
    {
        setcookie('imgit_style', 'inverted', time()+31556952);
        header('Location: ' . $home_action);
    }
}
else if (isset($_COOKIE['imgit_style']))
{   
    $style =  '_' . $_COOKIE['imgit_style'];
    if (isset($_POST['green']) && $_COOKIE['imgit_style'] == 'grey' || $_COOKIE['imgit_style'] == 'inverted')
    {
        setcookie('imgit_style', '', time()-31556952);
        $style = '';
        header('Location: ' . $home_action);
    }
    if (isset($_POST['grey']))
    {
        if ($_COOKIE['imgit_style'] == 'inverted')
        {
            setcookie('imgit_style', '', time()-31556952);
            if (!isset($_COOKIE['imgit_style']))
            {
                setcookie('imgit_style', 'grey', time()+31556952);
                header('Location: ' . $home_action);
            }
        }
    }
    if (isset($_POST['inverted']))
    {
        if ($_COOKIE['imgit_style'] == 'grey')
        {
            setcookie('imgit_style', '', time()-31556952);
            if (!isset($_COOKIE['imgit_style']))
            {
                setcookie('imgit_style', 'inverted', time()+31556952);
                header('Location: ' . $home_action);
            }
        }
    }
}
?>

header.php

<!DOCTYPE HTML>
<html>
<head>
<?php include('styles.php'); ?>
<title>IMGit.org - the image host</title>
<link rel="stylesheet" type="text/css" href="css/<?php echo 'style' . $style . '.css'; ?>" media="screen" />
<link rel="icon" href="css/images/<?php echo 'favicon' . $style . '.png'; ?>" type="image/x-icon" />
<link rel="shortcut icon" href="css/images/<?php echo 'favicon' . $style . '.png'; ?>" type="image/x-icon" />
</head>
<body>
<div class="style-switcher">
<form action="" method="post">
<table>
    <tr>
        <td>
            <span class="normal" style="vertical-align: text-top;">Switch style:</span>
            <input type="submit" name="green" class="style_green-button" value="green" />
            <input type="submit" name="grey" class="style_grey-button" value="grey" />
            <input type="submit" name="inverted" class="style_inverted-button" value="inverted" />
        </td>
    </tr>
</table>
</form>
</div>

问题看起来是,尽管您将setcookie()调用为空白,但cookie值$_COOKIE仍然为该请求保留该值。在重新加载页面之前,其内容不会更改。因此,您继续检查!isset($_COOKIE['imgit_style']),但除非您明确取消设置,否则该值仍将被设置

if (isset($_POST['grey']))
{
    if ($_COOKIE['imgit_style'] == 'inverted')
    {
        // No need to unset the old one, just overwrite the new one
        // setcookie('imgit_style', '', time()-31556952);
        setcookie('imgit_style', 'grey', time()+31556952);
        header('Location: ' . $home_action);
    }
 }
 if (isset($_POST['inverted']))
 {
    if ($_COOKIE['imgit_style'] == 'grey')
    {
        // No need to unset the old one, just overwrite the new one
        // setcookie('imgit_style', '', time()-31556952);
        setcookie('imgit_style', 'inverted', time()+31556952);
        header('Location: ' . $home_action);
    }
 }

更新

这可能是问题所在。。。您没有括号组来对if()语句进行逻辑分组:

if (isset($_POST['green']) && $_COOKIE['imgit_style'] == 'grey' || $_COOKIE['imgit_style'] == 'inverted')

这里发生的情况是,无论何时$_COOKIE['imgit_style'] == 'inverted',即使没有设置$_POST['green'],后续代码都会运行并删除cookie。看起来您希望将('grey' || 'inverted')分组在一起:

if (isset($_POST['green']) && ($_COOKIE['imgit_style'] == 'grey' || $_COOKIE['imgit_style'] == 'inverted'))

您不需要使用长条件,因为它会产生不必要的过程,并使代码不稳定。

考虑以下代码:

if (isset($_POST['green']))
{
    setcookie('imgit_style', '', time() + 3600);
    $style = 'green';
}
if (isset($_POST['grey']))
{
    setcookie('imgit_style', 'grey', time() + 3600);
    $style = 'grey';
}
if (isset($_POST['inverted']))
{
    setcookie('imgit_style', 'inverted', time() + 3600);
    $style = 'inverted';
}

根据设置按钮,它将相应地设置cookie。将cookie设置为''将在用户端删除它,您可以使用print_r($_COOKIES);获取它,但只能在重新加载页面之后。

当然,要检查green设置,您需要使用isset($_COOKIES['imgit_style']),因为在这种情况下,cookie将被取消设置。

通过使用上述方法,以下只是一个附录:

if (isset($_POST['green']) && $_COOKIE['imgit_style'] == 'grey' || $_COOKIE['imgit_style'] == 'inverted')

这有点不可靠,因为您在使用OR ||AND &&时没有对参数进行分组,从而使自己处于操作员偏好的支配之下。你应该根据你想做的事情对条件进行分组。

例如,如果green设置为POST,但cookie当前为greyinverted,则您希望让条件块运行,则需要使用if ( (isset($_POST['green'])) && ($_COOKIE['imgit_style'] == 'grey' || $_COOKIE['imgit_style'] == 'inverted') )。据我所知,这是每个布尔代数的默认行为:

  • 首先,我们检查是否设置了$_POST['green']
    • 如果FALSE,则整个条件不可能为真,因此这是一个退出点
    • 如果是TRUE,我们检查cookie是grey还是inverted
      • 如果它们中的任何一个是TRUE,则方程将是TRUE,并且运行条件分支
      • 如果这两个都是FALSE,则方程将是FALSE,从而给我们一个出口点