我有以下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()
语句以节省一些空间。
答案 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。它们应该立即可用。
快乐编码!