单例模式不返回现有实例


Singleton isn't returning existing instance

这就是我如何设置我的Singleton

<?php
    class MySingleton
    {
        private static $instance;
        private static $you;
        private function __construct()
        {
            $this->you = "foo";     
        }
        public static function singleton()
        {
            if (!isset(self::$instance)) {              
                $className = __CLASS__;
                self::$instance = new $className;
            }
            return self::$instance;
        }
        public function getYou()
        {
            return $this->you;
        }       
        public function setYou($val)
        {
            $this->you = $val;
        }
    }
?>

file1.php中,我这样做:

require_once('session.php');
$session = MySingleton::singleton();
$session->setYou('bar');
echo $session->getYou(); //echoes 'bar'

在file1.php中,我有一个指向file2.php的超链接,其中我有以下代码:

require_once('session.php');
$session = MySingleton::singleton();
echo ($session->getYou()); //prints 'foo' which gets set in the constructor

它似乎正在为file2创建一个新实例,这就是为什么$you具有默认值foo的原因。我哪里做错了?为什么不能得到file1。php中使用的实例?

PHP中的单例只对当前请求有效(因为HTTP是无状态的)。

如果你想保存该对象的状态,将其保存在会话中:

class MySingleton
    {
        private static $instance;
        private static $you;
        private function __construct()
        {
            $this->you = "foo";     
        }
        public static function singleton()
        {
            session_start();
            if (!($_SESSION['MyInstance'] instanceof MySingleton)) {              
                $className = __CLASS__;
                $_SESSION['MyInstance'] = new $className;
            }
            return $_SESSION['MyInstance'];
        }
        public function getYou()
        {
            return $this->you;
        }       
        public function setYou($val)
        {
            $this->you = $val;
        }
    }

singleton表示在一个请求期间是"single"。对于其他所有内容,您将不得不序列化对象或使用Sessions。

静态数据只能在一个PHP程序中使用。

如果你的两个脚本作为单独的页面运行,它们将不会共享任何状态

PHP中的单例意味着在程序的同一执行期间返回相同的对象实例,而不是在不同的页面或页面加载之间。您需要的是将对象存储在会话中(将其发送到"sleep")并稍后检索它("唤醒它"),但要注意,它们仍然是不同的实例,一个是另一个的克隆,更新一个不会更新另一个。