【问题标题】:Fast and efficient PHP Session快速高效的 PHP 会话
【发布时间】:2012-05-12 05:18:49
【问题描述】:

我目前在我的网站上的每个页面都有以下代码。请任何人确认这是否是开始和继续 PHP 会话的好习惯?

//************************************************************
//Session Settings
//************************************************************

$session_name = 'PHPSESSID'; 
$session_exp_time = 10000; 

$previous_name = session_name($session_name);

//Set garbage collection parameters
ini_set('session.gc_maxlifetime',   $session_exp_time);
ini_set('session.gc_probability', '1');
ini_set('session.gc_divisor', '100');

ini_set('session.name', $session_name);
ini_set('session.cookie_domain', ''); //Session set to not be available to subdomains
ini_set('session.cookie_lifetime', 0);

//Set the session cookie parameters
session_set_cookie_params($session_exp_time, '/', '');

//Start or continue a session...
@session_start();

if (isset($_COOKIE[$session_name]))
setcookie($session_name, $_COOKIE[$session_name], 2147483647, '');

请注意,此脚本包含在每个页面中。

另一个相关问题:

我应该设置自定义会话保存路径还是只使用服务器的默认会话保存路径?优缺点都有什么?据我了解,如果您没有设置自定义会话保存路径,那么您可能会在共享主机上遇到某种冲突?请帮忙指教。

提前致谢!

【问题讨论】:

  • 你可以访问服务器的 php.ini 吗?或者它是否支持 .htaccess 文件?如果是这样,其中许多 ini 条目都可以删除。
  • 您也可以将其推送到包含的 php 文件中,这样您每次只包含该文件,而不是每次包含所有代码。除非你已经这样做了。就像@Jack 所说的 php.ini 或 htaccess 是您可以添加该代码的其他地方。但是,如果您只是将其推送到其自己的 php 文件中并在每页包含一次,这也是一种很好的做法,您可以在 1 个文件中进行 1 次更改,并且它会在引用该文件的所有位置自动更新。

标签: php performance session


【解决方案1】:

您的许多语句涉及会话配置设置;这些通常可以在服务器的php.ini 或顶级.htaccess (Apache) 中移动。

session.name = PHPSESSID
session.gc_maxlifetime = 10000

session.gc_probability = 1
session.gc_divisor = 1000

session.cookie_domain =
session.cookie_path = /
session.cookie_httponly = 1
session.cookie_lifetime = 0

你不应该让会话持续时间长(到 2038 年到期);会话通常使用会话 cookie 来延续(从技术上讲,它会持续到浏览器关闭)。如果您想实现“记住我”功能,我建议您将其添加到会话之上,如下所述:http://jaspan.com/improved_persistent_login_cookie_best_practice

我发现区分开始新会话和恢复现有会话很重要,尤其是在会话仅作为登录过程的一部分创建的情况下。当会话无法恢复时,出现问题,应将用户重定向回登录页面(或主页)。

PHP 不理解这种区别,session_start 将自动创建一个会话,如果它不存在,更糟糕的是,如果给出任意会话 ID;后者允许会话采用攻击,如下所述:http://gihyo.jp/dev/serial/01/php-security/0025 - 它是日语,您必须使用浏览器进行翻译。

要确定会话是否可以恢复,您需要通过添加特殊键(例如$_SESSION['_id'] = session_id())来启动每个新会话。如果找到该密钥,则会话已经存在,您可以恢复它;如果不是,则会话不存在或有人试图为您提供错误的 ID。

要开始一个新的会话,你首先看它是否可以恢复;如果没有,您使用session_regenerate_id(true) 更改会话 ID(这使得攻击者更难劫持会话)。

最后,共享服务器上的会话保存路径可以写入您自己的主文件夹下,但这仅在您的共享主机与每个虚拟主机的专用用户一起运行时才有意义(即suexec)。否则,为了保护您的会话免受窥探攻击,您将不得不对会话数据(可能还有密钥)进行编码。查看mcrypt 扩展名:http://sg.php.net/mcrypt - 你应该可以在网上找到示例。

我希望这或多或少能回答你的问题。如果您认为有任何问题,请告诉我。

【讨论】:

  • 感谢您抽出宝贵时间提供帮助,杰克。非常欣赏。我无法知道是否可以恢复会话。我尝试使用: if(session_id() == '') 来查看会话是否已经开始,但它总是返回 TRUE,即使会话已经开始?
  • 您可以随时调用 session_start(),然后按照描述检查该会话中的密钥,即 isset($_SESSION['_started'])
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-12
  • 2019-12-29
  • 2012-09-27
  • 2016-07-06
  • 2018-07-21
  • 2016-08-08
相关资源
最近更新 更多