2013-07-10 3 views
2

Я подозревал, что в то время как синглтоны PHP не являются реальными синглонами, поэтому я сделал тест. Я создал следующий класс:Почему PHP создает новый экземпляр singleton каждый раз, когда запускается скрипт, вызывающий Foo :: getInstance()?

class MySingleton { 


    private static $instance; 


    private function __construct() 
    { 
     error_log("I am a new instance of MySingleton. I was instantiated at " . time()); 
    } 


    private function __clone(){} 


    public static function getInstance() 
    { 
     if(!is_object(self::$instance)) { 
      self::$instance = new MySingleton(); 
     } 
     return self::$instance; 
    } 

} 

Затем я создал файл с именем test.php:

require('MySingleton.php'); 

$foo = MySingleton::getInstance(); 
$bar = MySingleton::getInstance(); 
$baz = MySingleton::getInstance(); 

Когда я запускаю скрипт test.php на моем локальном хосте я получаю одну запись в журнале ошибок Apache , что делает его похожим на то, что он должен делать. Однако каждый раз, когда я обновляю страницу в браузере, я получаю еще одну запись в журнале ошибок, что означает, что PHP создает экземпляр нового объекта.

Есть ли что-то, что я могу сделать по-другому, чтобы этот класс возвращал постоянный одиночный экземпляр объекта? (т. е. какой синглтон предположительно делать).

Пожалуйста, не отвечайте на все причины, по которым вы считаете, что одиночные игры плохие. Я уже знаком с этими речами.

Заранее благодарен!

ответ

11

PHP не имеет гражданства. По каждому запросу приложение создается и срывается. В этом случае ваш singleton создается один раз в течение всего хода приложения - то есть один раз за запрос.

Контрастность с чем-то вроде Java, где у вас есть сервер, например Tomcat или Jetty, который хранит объекты, загруженные в память. В этой ситуации ваш синглтон сможет выдержать несколько запросов ... Пока сервер не перезагрузится.

+0

Интересный (и неутешительный). В этом случае я полагаю, что для того, чтобы иметь реальный синглтон в PHP, мне пришлось бы сериализовать экземпляр и сохранить его в кэше пользователей APC. Тогда метод getInstance() будет проверять кеш вместо проверки self :: $ instance. Тем не менее, это кажется довольно сочным. –

2

В объектах singleton PHP живут до тех пор, пока сценарий не будет жить. Что происходит здесь, когда ваш запрос заканчивается, скрипт умирает. И для второго запроса он создает новый экземпляр скрипта, следовательно, новый объект MySingleton.

Смежные вопросы