【问题标题】:When Should The Session Variable Be Cleared?什么时候应该清除会话变量?
【发布时间】:2011-03-27 19:27:40
【问题描述】:

我的应用程序的规范规定,两个用户必须能够同时处理网络应用程序的同一记录,而不会破坏彼此的数据(当然,除非他们每个人都修改了相同的字段,那么它将是最后一个保存的获胜者。)这是一个医疗系统,可以想象,当技术人员更新记录的另一部分时,计费人员可能正在处理记录。

因此,当用户保存表单时,系统应该只更改用户实际更改的数据库中的值。因为我使用的是 CakePHP,所以我试图在 PHP 方面处理这个问题,而不是在发送表单数据之前使用 JavaScript。

我的第一个想法是在保存之前立即检查数据库中的值,只更改不相同的值。但是,如果用户 A 在用户 B 打开表单后保存了表单,然后用户 B 保存了表单,那么用户 A 的更改将被用户 B 表单中的旧数据覆盖。

我的下一个想法是将表单的值保存在用户会话中。因此,当他打开表单时,数据将存储在会话中,并且只有与会话中的值不同的值才会在数据库中更新。因此,Session 将在其中序列化 $old_data。

这里的问题是,如果用户试图同时打开两条记录然后保存会导致悲伤。所以,我需要通过记录 id 存储会话数据。

而且,这让我想到了最后一个问题。当用户保存表单时,我可以从会话中取消设置数据(如果他们再次呈现相同的记录,则立即重新获取它)。但是,这并不能处理用户不保存表单的情况。如果他们打开表单并阅读它然后离开,他们的会话将逐渐变得充满碎片。

那么,什么时候是清理会话垃圾而不清除会话中实际需要的数据的最佳时间和方法?

【问题讨论】:

  • 请注意 - 因为这是一个 Web 应用程序而不是一个网站,所以我们的用户通常整天都在使用该应用程序。因此,如果他们正在处理数十张唱片,事情可能会变得非常疯狂。

标签: php session cakephp


【解决方案1】:

今天下午我准备迎接一些挑战,所以试一试 - 主要是看看是否所有逻辑都可以封装到一个组件中,而无需从控制器操作中手动调用代码。

生成的SaveDiff component 尚未用于生产,因此需要进行一些测试。 (如果发现任何错误,请随时在 GitHub 上进行更改。)

<?php
class ModelsController extends AppController {

    public $components = array(
        'SaveDiff' => array( # include the component
            'actions' => array('edit'), # tell it which actions to work with
        ),
    );

    public function edit($id) {
        $record = $this->read(null, $id)
        # not found
        if (!$record) {
            $this->cakeError('error404');
        }
        # populate form
        if (!$this->data) {
            $this->data = $record;
            return;
        }
        # save form
        $saved = $this->Model->save($this->data);
        if (!$saved) {
            $this->Session->setFlash('Failed validation');
            return;
        }
        # success
        $this->Session->setFlash('Saved changed fields');
        $this->redirect(array('action' => 'index'));
    }
}

在控制器操作期间(上例中的ModelsController::edit()),使用$this-&gt;data 填充表单。该组件将在控制器操作呈现后触发并将$this-&gt;data 保存到会话中。好吧,除非验证失败,因为那时我们可能正在处理用户提交的数据。

当新请求进入组件时,在控制器操作之前再次触发,并从$this-&gt;data 中清除任何未更改的数据(通过将其与会话进行比较),这意味着它应该满足您的要求(仅更改的字段)并且是准备保存。

注意:我注意到我的 SaveDiffComponent::extractChanges() 方法不太正确,但我会留给你。确保在测试时使用 DebugKit(会话和变量选项卡)并记住您需要刷新两次才能看到新的会话数据(因为 PHP 在下一个请求之前无法读取新的会话数据......或类似的东西)。

【讨论】:

  • 谢谢,我现在就玩这个。正是这样的东西让我爱上了 stackoverflow。
【解决方案2】:

您可以将每个项目放入会话数据中,每个记录都是它自己的数组。 又名 $_SESSION["client1"] 将是第一个客户端的信息,而$_SESSION["client2"] 将是第二个客户端的信息。

【讨论】:

    【解决方案3】:

    感谢您概述您的思考过程。

    我的下一个想法是保存这些值 用户会话中的表单。所以, 当他打开表格时,数据得到 存储在会话中,并且只有 已经改变的价值观 在他的会话中将得到更新 数据库。所以,会话会有 在其中序列化 $old_data。

    我认为这是最好的方法。

    而且,这让我进入了决赛 问题。我可以从 用户保存表单时的会话 (然后立即重新获取它,如果 他们再次呈现相同的记录)。 但是,这不涉及 用户不保存的情况 表格。如果他们打开表格并 读完然后慢慢走开 他们的会议将充满 碎片。

    请记住,会话最终会过期。届时,旧的会话数据将被删除。如果这对您来说太长,您可以在会话数据中添加日期时间,并在加载页面时循环浏览会话数据以删除过时的信息。

    打扫的频率由您决定。我会将其设置为您认为一个人处理特定表单所需的最长时间 + 1 分钟的任何值。

    希望有帮助!

    【讨论】:

      【解决方案4】:

      我不确定您的系统的设计,但您提到这是一个医疗系统,表格是否有某种修订标识符?如果是这样,您可以有一个隐藏字段来跟踪两个用户的起点,然后仍然可以比较已更改的内容,而无需将太多内容拉入会话对象。

      【讨论】:

        猜你喜欢
        • 2011-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-21
        • 2020-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多