【问题标题】:Sessions and PHP classes会话和 PHP 类
【发布时间】:2011-05-03 23:26:38
【问题描述】:

我习惯了 java、objective c 和一点 c++。 现在我想使用 PHP 创建一个网站。我创建了几个类,但为了简单起见:3 个类。

账户 - 数据映射器 - 数据管理器

这意味着我可以从数据库中获取一个帐户。在 DataManager 中,我跟踪所有事情。比如用户的userId。

问题是,通常所有设置的变量都保持“设置”,但现在我正在使用 php,我显然需要使用会话来存储它们。 数据管理器:

<? php
class DataManager
{
    // Hold an instance of the class
    private static $dm;
    private $dataMapper;
    private $dictationView;
    private $userId;

    private function __construct()
    {
        $this->dataMapper = new DataMapper();
        $this->dictationView = new DictationView();
    }

    // The singleton method
    public static function singleton()
    {
        if (!isset(self::$dm)) {
            $c = __CLASS__;
            self::$dm = new $c;
        }

        return self::$dm;
    }

    // Prevent users to clone the instance
    public function __clone()
    {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }


    function __get($prop) {
        return $this->$prop;
        }

    function __set($prop, $val) {
        $this->$prop = $val;
        }
}

?>

如果我在单例 DataManager 类中设置 userId,下次我 调用 DataManager 类的一个实例,它不会记住 userId。我想我必须在某个地方处理会话。如何在 DataManager 中以良好的 OOP 方式使用会话?谢谢!

【问题讨论】:

  • 当您说“下一次”时,您是指在同一个请求中还是在后续请求中?请记住,PHP 本质上与 HTTP 一样是无状态的。另外,使用self::$dm = new self; 而不是$c = __CLASS__; self::$dm = new $c;
  • @Phil Brown PHP 不是无状态的,每种语言在服务器-客户端架构师的请求之间都是无状态的,服务器-客户端架构师处理不同进程中的每个请求。 PHP 可以像任何其他语言一样具有状态。
  • @Itay 我指的是 PHP 没有像 Tomcat 这样的容器。您当然可以使用会话和其他外部存储来维护状态,但如果您来自 Java,这些事情可能并不明显。

标签: php oop session get set


【解决方案1】:

如果你愿意,你可以在 PHP 中为会话创建一个包装器。它实际上可能是有益的,特别是如果您的应用程序稍后必须迁移到服务器集群并且会话将被移动到分布式缓存中。然后,为了促进这种迁移,您只需要在相同的Session 类接口时提供不同的实现。

说了算。

这段代码本身不是一个好的OOP。你应该stop using singletons。而且,如果你的类需要DataMapperDictationView 的实例,那么它们应该在类外部创建并在构造函数中提供。 而不是创建紧密耦合,因为您的构造函数正在创建其他对象。

【讨论】:

    【解决方案2】:

    现在,您所指的不是 PHP,而是如何处理客户端-服务器架构。

    这是一个更改,假设您正确管理会话(关于 session_start - 应该在文件的引导程序中) 我还在您的代码中添加了一些主题更正,这将对您将来有所帮助:

        private function __construct()
        {
            $this->dataMapper = new DataMapper();
            $this->dictationView = new DictationView();
        }
    
        // The singleton method
        public static function singleton()
        {
            if(isset($_SESSION[self::MY_UNIQUE_IDENTIFIER] &&
               get_class($_SESSION[self::MY_UNIQUE_IDENTIFIER] == 'DataManager'){
                       self::$dm = $_SESSION[self::MY_UNIQUE_IDENTIFIER];
            }
            if (!self::$dm) {//LOOK HERE LOOK HERE!!!!!!!!!!!!!!!!!!!!
               $_SESSION[self::MY_UNIQUE_IDENTIFIER] = self::$dm = new self;
            }
    
            return self::$dm;
        }
    
        // Prevent users to clone the instance
        public function __clone()
        {
            trigger_error('Clone is not allowed.', E_USER_ERROR);
        }
    
    
        function __get($prop) {
            return $this->$prop;
            }
    
        function __set($prop, $val) {
            $this->$prop = $val;
            }
    }
    //LOOK HERE LOOK HERE no closing ?>
    

    一些陷阱我没有在这里解决,因为它们不是这个问题的主题:

    1. 管理会话的正确方法
    2. 调整类以允许继承而不破坏会话

    【讨论】:

    • 非常感谢,但也许最好的办法是摆脱单例类?我应该将我的会话存储在类的 __get 和 __set 中
    • @Oritm 将使其成为会话包装器。它不一定是单例,虽然很多人反对它,但总有安静的大多数人仍然使用它而没有任何问题。
    猜你喜欢
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 2012-02-29
    • 2012-08-01
    • 2023-04-09
    相关资源
    最近更新 更多