为什么我的饼干没有设置?

时间:2011-08-07 04:32:28

标签: php cookies

我有以下PHP函数:

function validateUser($username){
    session_regenerate_id (); 
    $_SESSION['valid'] = 1;
    $_SESSION['username'] = $username;
    setcookie('username2',$username,time()+60*60*24*365);
    header("Location: ../new.php");
}

然后我拿到了cookie:

echo $_COOKIE['username2']; exit();

(我只将exit()用于调试目的)

唯一的问题,它是空白的。有什么想法吗?

更新: 这是函数的调用方式:

    if(mysql_num_rows($queryreg) != 0){
    $row = mysql_fetch_array($queryreg,MYSQL_ASSOC);
    $hash = hash('sha256', $row['salt'] . hash('sha256', $password));
    if($hash == $row['password']) {
        if($row['confirm'] == 1){
            if(isset($remember)){
                setcookie('username',$username,time()+60*60*24*365);
                setcookie('password',$password,time()+60*60*24*365);
            } else {
                setcookie('username','',time()-3600);
                setcookie('password','',time()-3600);
            }
            validateUser($username);

我没有包含所有if()语句以节省一些空间。

7 个答案:

答案 0 :(得分:37)

尝试添加路径= /,以便cookie适用于整个站点,而不仅仅是当前目录(之前已经抓住了我)

例如

setcookie('password',$password,time()+60*60*24*365, '/'); 

还要确保cookie是输出的第一件事 正如在PHP手册中所建议的那样(这也让我感觉不舒服)

  

与其他标题一样,Cookie必须在您的任何输出之前发送   脚本(这是协议限制)。

答案 1 :(得分:17)

为什么会出现此问题

问题来自于setcookie()没有立即设置cookie ,它发送标题以便浏览器设置cookie。这意味着,对于当前页面加载,setcookie()将不会生成任何$_COOKIE

当浏览器稍后请求页面时,它会在标题中发送cookie,以便PHP可以以$ _COOKIE的形式检索它们。

简单,解决方案

关于解决方案,显而易见的一个:

setcookie('username',$username,time()+60*60*24*365);
// 'Force' the cookie to exists
$_COOKIE['username'] = $username;

更好的解决方案

我创建了一个类Cookie,它解决了setcookie()和$ _COOKIE共享的问题:

// Class that abstracts both the $_COOKIE and setcookie()
class Cookie
  {
  // The array that stores the cookie
  protected $data = array();

  // Expiration time from now
  protected $expire;
  // Domain for the website
  protected $domain;

  // Default expiration is 28 days (28 * 3600 * 24 = 2419200).
  // Parameters:
  //   $cookie: $_COOKIE variable
  //   $expire: expiration time for the cookie in seconds
  //   $domain: domain for the application `example.com`, `test.com`
  public function __construct($cookie, $expire = 2419200, $domain = null)
    {
    // Set up the data of this cookie
    $this->data = $cookie;

    $this->expire = $expire;

    if ($domain)
      $this->domain = $domain;
    else
      {
      $this->domain = 
        isset($_SERVER['HTTP_X_FORWARDED_HOST']) ?
        $_SERVER['HTTP_X_FORWARDED_HOST'] :
        isset($_SERVER['HTTP_HOST']) ?
          $_SERVER['HTTP_HOST'] :
          $_SERVER['SERVER_NAME'];
      }
    }

  public function __get($name)
    {
    return (isset($this->data[$name])) ?
      $this->data[$name] :
      "";
    }

  public function __set($name, $value = null)
    {
    // Check whether the headers are already sent or not
    if (headers_sent())
      throw new Exception("Can't change cookie " . $name . " after sending headers.");

    // Delete the cookie
    if (!$value)
      {
      setcookie($name, null, time() - 10, '/', '.' . $this->domain, false, true);
      unset($this->data[$name]);
      unset($_COOKIE[$name]);
      }

    else
      {
      // Set the actual cookie
      setcookie($name, $value, time() + $this->expire, '/', $this->domain, false, true);
      $this->data[$name] = $value;
      $_COOKIE[$name] = $value;
      }
    }
  }

然后你可以像这样使用它:

$Cookie = new Cookie($_COOKIE);
$User = $Cookie->user;
$LastVisit = $Cookie->last;
$Cookie->last = time();

当然,你必须传递它。比拥有全局变量要好得多。

答案 2 :(得分:4)

以下是setcookie

的一般语法
setcookie(name,value,expire,path,domain,secure); 

查看第三个参数,如果不设置,脚本会将其带到当前工作目录。因此,如果您设置的Cookie没有在a.com/b/setcookie.php设置路径,则a.com/checkcookie.php将无法使用该Cookie。你正在做的是在子文件夹中设置cookie并重定向到父文件夹,查看../,它不可用,因此问题。怎么避免这个?正常程序是提供/的路径,在您的情况下提供/作为第四个参数。您的cookie的第五个参数将设置为安全。 http://www.php.net/setcookie有更多解释。这应该可以解决您的问题。将域路径设置为domain.com,会使Cookie可用于domain.com下的所有内容,但不会something.domain.com。将域值设置为.domain.com,查看domain.com之前的点,将其设置为anything.domain.com。 HTH!

答案 3 :(得分:3)

以为我会添加另一个可能的原因,为什么cookie可能无法设置或显示随机功能行为。

以下情况可能适用于某些程序员由于错误使用 header_remove()而出现虚幻Cookie设置问题;

如果您尝试在调用 header_remove()之前设置Cookie ,则永远不会创建Cookie,因为您还销毁了设置为创建Cookie的标头在将指令缓冲到客户端之前。

你可能会发现,当摆弄时你的cookie突然因某种未知原因而起作用:

首次运行时,如果你设置了一个cookie并且根本没有调用header_remove(),那么在第二次运行时你会调用header_remove(),你会发现你的cookie现在总是被设置。

如果您尝试在header_remove()之前更改cookie值,同样也适用,您再次失败,因为它会在实际缓冲到用户之前擦除您尝试进行的更改。 您需要在header_remove()之后设置cookie和任何其他标头。

如果您正在使用header_remove()来更改DOM Scripting的HTTP响应代码层次结构,则可以使用以下内容快速解决此Cookie标头擦除冲突,以明确清除响应代码:

 header_remove('HTTP/1.0');

答案 4 :(得分:0)

这要求您在所有输出(包括和标记以及任何空格)之前都先调用此函数。

这是结构的外观

<?php
$cookie_name = "user";
$cookie_value = "Ahmed Moftah";
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/"); // 86400 = 1 day
?>
<?php
if(!isset($_COOKIE[$cookie_name])) {
    echo "Cookie named '" . $cookie_name . "' is not set!";
} else {
    echo "Cookie '" . $cookie_name . "' is set!<br>";
    echo "Value is: " . $_COOKIE[$cookie_name];
}
?>
<html>
<body>



</body>
</html>

答案 5 :(得分:0)

这可能是缓存问题。尝试关闭浏览器并使用localhost文件路径打开一个新浏览器。我遇到了同样的问题,尽管我可以输入新代码并在页面上看到更改,但我的页面已被缓存,因此cookie无法正常工作。非常奇怪...清理缓存可能会有所帮助,请先尝试。然后尝试使用新的浏览器,然后尝试转到localhost:8080索引并单击“刷新”以查看最后一页的修改时间。

如果仍不能解决问题,请尝试重新启动LAAMP或XAAMP或您正在使用的任何设备。

答案 6 :(得分:0)

这发生在会话 cookie 被禁用的情况下。

您可以导航到您的 php.ini 文件(根据服务器而变化。Ubuntu 20.04 的默认值是 /etc/php/{Xx}/{apache2|[others]}/php.ini)并确保 {{ 1}}

重新启动您的服务器,然后尝试设置 cookie。它们应该立即可用。

快乐编码!