gpt4 book ai didi

php - 我应该如何在 PHP 中实现延迟 session 创建?

转载 作者:行者123 更新时间:2023-12-03 00:11:36 26 4
gpt4 key购买 nike

默认情况下,PHP 的 session 处理机制会设置 session cookie header 并存储 session ,即使 session 中没有数据也是如此。如果 session 中没有设置数据,那么我不希望在响应中将 Set-Cookie header 发送到客户端,并且我不希望在服务器上存储空 session 记录。如果数据添加到 $_SESSION,则正常行为应该继续。

我的目标是实现 Drupal 7 和 Pressflow 那种延迟 session 创建行为。除非在应用程序执行期间将数据添加到 $_SESSION 数组,否则不会存储 session (或发送 session cookie header )。此行为的要点是允许反向代理,例如 Varnish缓存和服务匿名流量,同时让经过身份验证的请求传递到 Apache/PHP。 Varnish(或另一个代理服务器)被配置为传递任何没有 cookie 的请求,正确地假设如果 cookie 存在,则该请求是针对特定客户端的。

我已从 Pressflow 移植了 session 处理代码,该代码使用 session_set_save_handler() 并覆盖 session_write() 的实现来检查 $_SESSION 中的数据 数组,然后保存,并将其写为库,并在此处添加答案(如果这是最佳/唯一的路线)。

我的问题:虽然我可以实现完全自定义的session_set_save_handler()系统,但是否有一种更简单的方法可以以相对通用的方式获得这种惰性 session 创建行为,对于大多数应用程序来说是透明吗?

最佳答案

嗯,一种选择是使用 session 类来启动/停止/存储 session 中的数据。所以,你可以这样做:

class Session implements ArrayAccess {
protected $closed = false;
protected $data = array();
protected $name = 'mySessionName';
protected $started = false;

protected function __construct() {
if (isset($_COOKIE[$this->name])) $this->start();
$this->data = $_SESSION;
}

public static function initialize() {
if (is_object($_SESSION)) return $_SESSION;
$_SESSION = new Session();
register_shutdown_function(array($_SESSION, 'close'));
return $_SESSION;
}

public function close() {
if ($this->closed) return false;
if (!$this->started) {
$_SESSION = array();
} else {
$_SESSION = $this->data;
}
session_write_close();
$this->started = false;
$this->closed = true;
}

public function offsetExists($offset) {
return isset($this->data[$offset]);
}

public function offsetGet($offset) {
if (!isset($this->data[$offset])) {
throw new OutOfBoundsException('Key does not exist');
}
return $this->data[$offset];
}

public function offsetSet($offset, $value) {
$this->set($offset, $value);
}

public function offsetUnset($offset) {
if (isset($this->data[$offset])) unset($this->data[$offset]);
}

public function set($key, $value) {
if (!$this->started) $this->start();
$this->data[$key] = $value;
}

public function start() {
session_name($this->name);
session_start();
$this->started = true;
}
}

要使用,请在脚本开始时调用 Session::initialize()。它将用对象替换 $_SESSION ,并设置延迟加载。之后,你就可以这样做

$_SESSION['user_id'] = 1;

如果 session 未启动,它将启动,并且 user_id 键将设置为 1。如果您在任何时候想要关闭(提交) session ,只需调用 $_SESSION->close( )

您可能想要添加一些更多的 session 管理功能(例如 destroy、regenerate_id、更改 session 名称的能力等),但这应该实现您想要的基本功能...

它不是一个 save_handler,它只是一个管理 session 的类。如果您确实愿意,您可以在类中实现 ArrayAccess,并在构造时将 $_SESSION 替换为该类(这样做的好处是,遗留代码仍然可以像以前一样使用 session ,而无需调用 $session ->setData())。唯一的缺点是我不确定 PHP 使用的序列化例程是否可以正常工作(您需要在某个时候将数组放回到 $_SESSION 中......可能使用 register_shutdown_function()...

关于php - 我应该如何在 PHP 中实现延迟 session 创建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2998166/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com