php 为什么我的 cookie 没有设置?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6970754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are my cookies not setting?
提问by Jason
I have the following PHP function:
我有以下 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");
}
And then I fetch the cookie:
然后我获取cookie:
echo $_COOKIE['username2']; exit();
echo $_COOKIE['username2']; exit();
(I only put exit()
for debugging purposes)
(我只exit()
用于调试目的)
Only problem, it's coming out blank. Any ideas?
唯一的问题,它出来是空白的。有任何想法吗?
UPDATE:This is how the function is called:
更新:这是函数的调用方式:
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);
I didn't include all the if()
statements to save some space.
if()
为了节省空间,我没有包含所有语句。
回答by bumperbox
try adding the path = /, so that the cookie works for the whole site not just the current directory (that has caught me out before)
尝试添加路径 = /,以便 cookie 不仅适用于当前目录,而且适用于整个站点(之前已经让我知道了)
example
例子
setcookie('password',$password,time()+60*60*24*365, '/');
also make sure the cookie is the first thing being output as advised in the php manual (this has caught me out before too)
还要确保 cookie 是按照 php 手册中的建议输出的第一件事(这也让我感到困惑)
Like other headers, cookies must be sent before any output from your script (this is a protocol restriction).
与其他标头一样,cookie 必须在脚本的任何输出之前发送(这是协议限制)。
回答by Francisco Presencia
Why you are having this problem
为什么你会遇到这个问题
The problem comes from the fact that setcookie() doesn't set the cookies immediately, it sends the headers so the browser sets the cookies. This means that, for the current page load, setcookie() will no generate any $_COOKIE
.
问题在于 setcookie() 不会立即设置 cookie ,它会发送标头以便浏览器设置 cookie。这意味着,对于当前页面加载, setcookie() 不会生成任何$_COOKIE
.
When the browser later on requests a page, it sends the cookies in the headers so the PHP can retrieve them in the form of $_COOKIE.
当浏览器稍后请求页面时,它会在标头中发送 cookie,以便 PHP 可以以 $_COOKIE 的形式检索它们。
Simple, oldsolution
简单的旧解决方案
About solutions, the obvious one:
关于解决方案,显而易见的一个:
setcookie('username',$username,time()+60*60*24*365);
// 'Force' the cookie to exists
$_COOKIE['username'] = $username;
A better solution
更好的解决方案
I created a class, Cookie
, that addresses the problems that setcookie() and $_COOKIE share:
我创建了一个类,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;
}
}
}
Then you can use it like this:
然后你可以像这样使用它:
$Cookie = new Cookie($_COOKIE);
$User = $Cookie->user;
$LastVisit = $Cookie->last;
$Cookie->last = time();
And of course, you have to pass it around. Much better than having globals.
当然,你必须传递它。比拥有全局变量要好得多。
回答by Kumar
Here is the general syntax of setcookie
这是 setcookie 的一般语法
setcookie(name,value,expire,path,domain,secure);
Look at third argument, if you do not set it the script will take it to current working directory. So if you set a cookie without setting path at a.com/b/setcookie.php
the cookie will not be available to a.com/checkcookie.php
. What you are doing is setting cookie in a subfolder and the redirecting to a parent folder, look at ../
, where it is not available hence the issue. How to avoid this? Normal procedure is to supply a path that is /
, in your case supply /
as fourth param. The fifth argument for your cookie will set it secure. http://www.php.net/setcookiehas more explanation. This should fix your problem. Setting domain path to domain.com
, will make the cookie available to everything under domain.com
but not to something.domain.com
. Set domain value to .domain.com
, look at the dot preceding domain.com, will make it available across anything.domain.com
. HTH!
查看第三个参数,如果您不设置它,脚本会将其带到当前工作目录。因此,如果您设置 cookie 而不设置路径,a.com/b/setcookie.php
则 cookie 将无法用于a.com/checkcookie.php
. 您正在做的是在子文件夹中设置 cookie 并重定向到父文件夹,请查看../
它不可用的位置,因此出现了问题。如何避免这种情况?正常程序是提供一个路径/
,在您的情况下/
作为第四个参数提供。您的 cookie 的第五个参数将使其安全。http://www.php.net/setcookie有更多解释。这应该可以解决您的问题。将域路径设置为domain.com
,将使 cookie 可用于 下的所有内容,domain.com
但不能用于something.domain.com
。将域值设置为.domain.com
,查看 domain.com 前面的点,将使其在anything.domain.com
. 哼!
回答by Marc
Thought I would add another possible reason why a cookie may not be either setting or showing random functional behaviour.
我想我会添加另一个可能的原因,为什么 cookie 可能不会设置或显示随机功能行为。
The following case may be applicable to some programmers having what appears to be an illusive cookie setting issue as a result of the incorrect usage of header_remove();
以下情况可能适用于某些程序员,由于header_remove()的错误使用而导致其出现了虚假的 cookie 设置问题;
If you try to set a cookie beforecalling header_remove()then the cookie will never be created because you have also destroyed the header that was set to create the cookie before the instruction was buffered out to the client.
如果您在调用header_remove()之前尝试设置 cookie ,那么将永远不会创建 cookie,因为您还破坏了在指令缓冲到客户端之前设置为创建 cookie 的标头。
You may find when fiddling around that your cookie suddenly works for an unknown reason:
您可能会在摆弄时发现您的 cookie 突然因未知原因起作用:
On a first run if you set a cookie and don't call header_remove() at all, Then on a second run you do call header_remove(), you will find your cookie is now always set.
在第一次运行时,如果您设置了 cookie 并且根本不调用 header_remove(),然后在第二次运行时调用 header_remove(),您会发现您的 cookie 现在总是被设置。
The same also applies if you try to alter a cookie value before header_remove(), you again will fail because it will wipe the changes you are trying to make before they are actually buffered out to the user. You need to set cookies and any other headers for that matter after a header_remove() not before.
如果您尝试在 header_remove() 之前更改 cookie 值,这同样适用,您将再次失败,因为它会在实际缓冲给用户之前擦除您尝试进行的更改。您需要在 header_remove() 之后而不是之前为此设置 cookie 和任何其他标题。
If you were using header_remove() for the intention of altering a hierarchy of HTTP Response codes for DOM Scripting, you can quickly resolve this cookie header wipe conflict by using the following to explicitly clear response codes only:
如果您使用 header_remove() 来改变 DOM 脚本的 HTTP 响应代码的层次结构,您可以通过使用以下内容来快速解决此 cookie 标头擦除冲突,仅显式清除响应代码:
header_remove('HTTP/1.0');
回答by Moftah
This requires that you place calls to this function prior to any output, including and tags as well as any whitespace.
这要求您在任何输出之前调用此函数,包括和标签以及任何空格。
this is how the structure looks
这是结构的样子
<?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>
回答by Evan Erickson
It might be a cache problem. Try closing the browser and opening a new one with the localhost file path. I had the same issue and my page was cached so the cookies weren't working, even though I could put in new code and see a change on the page. Very weird... Cleaning your cache might help, try that first. Then try a new browser, then try to go to your localhost:8080 index and hit refresh to see when the last page was modified.
可能是缓存问题。尝试关闭浏览器并使用本地主机文件路径打开一个新浏览器。我遇到了同样的问题,我的页面被缓存,因此 cookie 无法正常工作,即使我可以放入新代码并查看页面上的更改。很奇怪...清理缓存可能会有所帮助,请先尝试。然后尝试一个新的浏览器,然后尝试转到您的 localhost:8080 索引并点击刷新以查看最后一页何时被修改。
If that doesn't fix it, try restarting LAAMP or XAAMP or whatever you are using.
如果这不能解决问题,请尝试重新启动 LAAMP 或 XAAMP 或您正在使用的任何东西。