添加注释

用户贡献注释 23 个注释

145
final dot wharf at gmail dot com
13 年前
由于 PHP 的会话控制在使用 session_set_cookie_params() 时无法正确处理会话生命周期,因此我们需要做一些操作才能在用户每次访问我们的网站时更改会话过期时间。所以问题在这里。

<?php
$lifetime
=600;
session_set_cookie_params($lifetime);
session_start();
?>

这段代码在用户回到我们的网站或刷新页面时不会改变会话的生命周期。会话将在 $lifetime 秒后过期,无论用户请求页面多少次。所以我们只需覆盖会话 cookie,如下所示

<?php
$lifetime
=600;
session_start();
setcookie(session_name(),session_id(),time()+$lifetime);
?>

现在我们有了相同的会话 cookie,生命周期设置为正确的值。
52
frank at frankforte dot ca
4 年前
以下内容似乎适用于在 PHP < 7.3 上为会话 cookie 设置 SameSite 属性。

<?php

$secure
= true; // 如果你只想通过 HTTPS 接收 cookie
$httponly = true; // 阻止 JavaScript 访问会话 cookie
$samesite = 'lax';

if(
PHP_VERSION_ID < 70300) {
session_set_cookie_params($maxlifetime, '/; samesite='.$samesite, $_SERVER['HTTP_HOST'], $secure, $httponly);
} else {
session_set_cookie_params([
'lifetime' => $maxlifetime,
'path' => '/',
'domain' => $_SERVER['HTTP_HOST'],
'secure' => $secure,
'httponly' => $httponly,
'samesite' => $samesite
]);
}
?>
5
theking2(at)king.ma
11 个月前
根据 PHP 7 版本,session_start 可以包含一个选项数组,因此此函数已过时。所有 cookie 设置(以及更多)都可以在选项数组中作为 session_start() 的参数包含。

<?php
session_start
( [
'cookie_path' => '/',
'cookie_lifetime' => 300,
'cookie_secure' => true,
'cookie_httponly' => true,
'cookie_samesite' => 'lax',
] );
14
passerbyxp at gmail dot com
12 年前
需要注意的是,浏览器对 $path 参数区分大小写。

例如,如果您这样做
<?php
session_set_cookie_params
(0,"/webapp/");
session_start();
?>

并且您以这种方式访问您的网站
example.com/WebApp/

您将在每次请求时获得一个新的会话。

我不确定这是否是标准,但我看到这在 IE 6、Firefox 12(实际上是 Palemoon)、Chrome 19(便携版)以及 IIS 和 Apache 上都发生了。
19
Danack dot Ackroyd at gmail dot com
13 年前
在 session_set_cookie_params() 中设置 cookie 的域只会影响 PHP 设置的会话 cookie 所使用的域。

所有其他通过调用 setcookie() 函数设置的 cookie 都会
i) 使用在 setcookie() 调用中明确设置的域
或者
ii) 根本不设置 cookie 的域,因此浏览器假设它适用于当前域。

因此,要使所有 cookie 都在您网站的所有子域中可用,您需要这样做

<?php
$currentCookieParams
= session_get_cookie_params();

$rootDomain = '.example.com';

session_set_cookie_params(
$currentCookieParams["lifetime"],
$currentCookieParams["path"],
$rootDomain,
$currentCookieParams["secure"],
$currentCookieParams["httponly"]
);

session_name('mysessionname');
session_start();

setcookie($cookieName, $cookieValue, time() + 3600, '/', $rootDomain);
?>
14
Miki
14 年前
请记住,如果您有一个多子域站点,您必须添加以下内容以在整个网站上启用会话 ID

<?php
session_set_cookie_params
(0, '/', '.example.com');
session_start();
?>

否则,您将在例如 news.example.com 和 download.example.com 上拥有两个不同的会话
13
shrockc at inhsNO dot SPAMorg
22 年前
在设置 cookie 有效的路径时,请始终记住在末尾加上“/”。

正确
session_set_cookie_params (0, '/yourpath/');

错误
session_set_cookie_params (0, '/yourpath');

对花了我多少时间才意识到这是我的身份验证/会话问题的原因没有评论...
11
werner dot avenant at gmail dot com
12 年前
请注意 Ubuntu 和 Debian 等系统上的垃圾回收“功能”。

apt-get 在 /etc/cron.d/php5 中安装了一个 cron 脚本,该脚本检查 session.gc_maxlifetime 变量,然后每 9 分钟和 39 分钟删除所有旧会话。

问题是:如果您为特定虚拟主机设置了 maxlifetime,这些设置将被忽略。假设您希望服务器只存储 30 分钟的会话,但对于一个特殊的网站,您希望所有会话都持续 24 小时。如果您在 .htaccess、apache conf 中设置 session.gc_maxlifetime 或在代码中使用 ini_set,它将不起作用,会话仍然会在 30 分钟后被销毁。这是因为 /usr/lib/php5/maxlifetime(在该 cron 文件中找到)将始终返回 php.ini 中的值,而不是您在 .htaccess 中设置的值。

一个解决方法是将 maxlifetime 设置为您的网站所需的最高值,然后在 .htaccess 中为不需要它的网站配置更短的 maxlifetime。

另一种解决方案是为 /etc/cron.d 中的 php5 文件提供合理的值,例如,只让它在凌晨 3 点运行,但您必须记住每次更新 php 时都阻止替换该文件。
5
jordi at jcanals dot net
19 年前
一些我花了些时间调试的东西:当域参数只是一个一级域(就像 TLD)时,session_set_cookie_params() 不起作用。

我的网站位于内网中,我们的内部域是 .local,因此尝试将会话 cookie 设置为 .local 域不起作用

session_set_cookie_params(0, '/', '.local'); // 不起作用

在我完成的所有测试中,设置域仅适用于 SLD 及更高版本

session_set_cookie_params(0 , '/', '.sld.local'); 可行

这与 PHP 无关,而是与 http 协议有关,它不允许出于安全原因为 TLD 设置 cookie。
6
dan at vespernet dot co dot uk
16 年前
以下说明是“重置”页面刷新时会话过期时间的绝佳示例。

但是,请注意,当会话过期并且没有续订时(我相信这是一个错误)需要进行补偿。如果以下示例在每次执行脚本时运行,它将在会话无法续订后出现“未定义索引 <会话名称> 错误”。在前面加上一个 if isset() 条件。

<?php
private function startSession($time = 3600, $ses = 'MYSES') {
session_set_cookie_params($time);
session_name($ses);
session_start();

// 页面加载时重置过期时间
if (isset($_COOKIE[$ses]))
setcookie($ses, $_COOKIE[$ses], time() + $time, "/");
}
?>

上面的示例表明,会话将在没有页面刷新的一小时内持续有效,直到它被删除。页面刷新后,过期时间将再次重置为一小时。如果您希望让用户选择“永远保持登录状态”,只需为 startSession 提供“99999999”的值,这应该持续大约 3 年。
4
Anonymous
16 年前
回复 RC
>2008-04-23 04:45
>对于任何想知道哪些浏览器支持 HTTPOnly 标志的人,根据我的研究
>
>IE 6 SP 1 及更高版本。
>Firefox 3 及更高版本。
>Opera 9.50 及更高版本。

Firefox 2.0 也支持它们,但仅从 2.0.0.5 版本开始。

http://bugzilla.mozilla.org/show_bug.cgi?id=178993
1
theking2(at)king.ma
5 个月前
为了完全控制会话 cookie,我使用这段代码

<?php
session_set_cookie_params
( [
'lifetime' => 0,
'path' => '/',
'domain' => $_SERVER['HTTP_HOST'],
'samesite' => 'Strict',
] );
session_start( [
'name' => 'SESSION',
'sid_length' => 96,
'sid_bits_per_character' => 6,
'use_strict_mode' => true,
'referer_check' => $_SERVER['HTTP_HOST'],
] );
?>

这将参数设置为推荐的参数,并生成一个质量合理的 cookie ID。
0
eion at robbmob dot com
3 年前
不幸的是,session_set_cookie_params() 无法在活动会话期间调用,它只会发出 E_WARNING 并返回 false,这意味着调用 session_regenerate_id()(例如,在登录期间以防止会话固定攻击)最终可能会使用旧的 cookie 设置(例如,不是“SameSite=Strict”)。

为了确保所有将来的会话都使用正确的 cookie 设置创建,最好使用 ini_set() 设置 cookie 参数 - 这实际上是 session_set_cookie_params() 在幕后所做的。
1
jan at dewal dot net
14 年前
上面关于此函数只能在 session_start 之前使用的信息取决于您如何使用它。因为它在会话启动后也有用,如下所示

例如,您希望更改已设置的会话 cookie 过期时间的 value

<?php

// 我们照常开始
session_set_cookie_params('3600'); // 1 小时
session_start();

// 更多代码...

// 现在我们在某个数据库中发现用户希望
// cookie 在例如 10 分钟后过期
// 我们可以立即更改它!

session_set_cookie_params('600'); // 10 分钟。
session_regenerate_id(true);

// 这将删除旧的 cookie 并采用新的过期设置,并将
// 旧的 cookie 变量放到新的 cookie 中

?>

请注意,我只解释了会话 cookie 过期时间的浏览器(客户端)方面的更改。
0
gavin_spam at skypaint dot com
22 年前
session_set_cookie_params 的第一个参数是在未来(基于服务器当前时间)会话将过期的秒数。因此,如果您希望会话持续 100 天

$expireTime = 60*60*24*100; // 100 天
session_set_cookie_params($expireTime);

我使用的是 time()+$expireTime,这是错误的(我发现的大多数 session_set_cookie_params() 示例都做错了,但可能不在乎,因为他们只是做“无限”会话)。
0
php at mike2k dot com
23 年前
[编辑注

来自 PHP-General 列表的 Rasmus 的解决方案

只需使用会话 cookie(不提供过期时间)并将
服务器的过期时间戳添加到 cookie 的值中。然后,当你收到
该 cookie 发送给你时,根据服务器时间检查它,并根据此
决定是否接受该 cookie。

这样,你就不会受到人们未正确设置系统时钟的影响


-Rasmus

[email protected]]

我在使用它时注意到了一些事情。我认为它只有在你在 session_start() 函数之前设置 session_set_cookie_params() 函数的情况下才能正常工作。

此外,当你设置 cookie 的“生存期”时,它会从 SERVER 获取秒偏移量。它会将 cookie 编码为在 SERVER 时间超时。因此,如果你的服务器比客户端快 2 分钟,并且你将 cookie 设置为在 30 秒后超时,那么客户端实际上会在 cookie 超时之前有 2 分钟 30 秒。我不知道是否有任何方法可以在将来的版本中修补它,我想到的唯一替代方案是在 javascript 中设置 cookie,这在使用所有这些特定会话函数时几乎没有意义。
-1
William Leslie
16 年前
"info at xyzsite dot ru" 写道,Internet Explorer 无法正确处理域名包含下划线的 cookie。

然而,这种看似错误的行为是有充分理由的:下划线在 DNS 名称中是被禁止的。RFC 3696 说

"组成域名的标签... 只能包含 ASCII 字母数字字符和连字符。不允许使用其他符号或标点符号,也不允许使用空格。"

如果下划线在 Mozilla 或其他浏览器中有效,那仅仅是因为它们在域名验证方面比较宽容。
-2
Ashus
15 年前
跨域 cookie 在所有浏览器(路径“/”服务器“。example.com”)中都能正常工作,除了你在 IE6/7 中尝试它并且服务器名称是从:etc/hosts: 文件中检索到的情况,在这种情况下,cookie 甚至不会被保存。
-3
brandan, bildungsroman.org
16 年前
我发现使用会话有点困难,因为文档没有真正说明为了使 session_set_cookie_params() 有用,会话名称需要通过 session_name() 设置的必要性。我在本文中没有找到关于 session_name() 的任何参考,如果不是一个熟悉会话的朋友,我的会话函数就会一团糟。

所以,从本质上讲,对于任何想知道从哪里开始的人:在使用 session_set_cookie_params() 之前声明一个会话名称,否则你可能会激怒 php,以至于它会对你的 webserver 做出一些暴行。
-5
eddie at roosenmaallen dot com
16 年前
补充“info at xyzsite dot ru”和 William Leslie 的说法,OS X 上的 Safari 也不支持子域名中带有下划线的 cookie。

我发现的解决方法是将父域名指定为 cookie 域名 - 而不是“bad_name.example.com”,将路径设置为“。example.com”;虽然不是最佳方案,但可以完成任务。
-8
digitalmagnets at gmail dot com
14 年前
看起来,如果你在 https://subdomain123.example.com 上为 .example.com 设置会话 cookie,那么安全 cookie 的默认值不是 false 而是 true。

因此,你的 cookie 不会在 http://subdomainxyz.example.com 上工作,除非你将安全选项设置为 false。
-7
RC
16 年前
对于任何想知道哪些浏览器支持 HTTPOnly 标志的人,根据我的研究

IE 6 SP 1 及更高版本。
Firefox 3 及更高版本。
Opera 9.50 及更高版本。

截至 Safari 3.1.1(2008 年 4 月),Safari 尚未支持此标志。

此 cookie 标志是由 Microsoft 开发的,并且正在逐渐被其他浏览器采用:http://msdn2.microsoft.com/en-us/library/ms533046.aspx
-11
info at xyzsite dot ru
16 年前
还有一种糟糕的情况 - Internet Explorer 中的 cookie 不支持域名中的“_”。FF 和 Opera 则没有问题。因此,如果你的主机名类似于 test_host.example.com,IE cookie 将无法正常工作/
To Top