Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Срок жизни синглтона


Автор: v00d00 18.9.2009, 14:47
Доброго времени

Есть класс

Код

class Settings {

    private static $instance;
    private $settings;    
   
    private function __construct() {
        $this->settings = parse_ini_file("settings.ini", true);
    }
   
    public static function getInstance() {
        if(! isset(self::$instance)) {
            self::$instance = new Settings();           
        }
        return self::$instance;
    }
   
    public function __get($setting) {
        if(array_key_exists($setting, $this->settings)) {
            return $this->settings[$setting];
        } else {
            foreach($this->settings as $section) {
                if(array_key_exists($setting, $section)) {
                    return $section[$setting];
                }
            }
        }
    }
}


Как видим это синглтон. 

Используется он так:

Код

require_once('/service/InitConnection.php');    
$stns = Settings::getInstance();
$user=$stns->user;
$password=$stns->password;
$database=$stns->database;
$localhost=$stns->localhost;


Вопрос: как долго на вебсервере будет висеть инстанс класса? 

Автор: NewDima 18.9.2009, 15:00
Как только скрипт закончит работу, сборщик мусора выкинет инстанс

Автор: Simpliest 18.9.2009, 15:14
Цитата(v00d00 @  18.9.2009,  14:47 Найти цитируемый пост)
Вопрос: как долго на вебсервере будет висеть инстанс класса? 

Если нужно долго висеть, то возможно подойдет паттерн Registry

А в ZF можно посмотреть на его имплеменатцию http://framework.zend.com/manual/en/zend.registry.html

Автор: Ипатьев 18.9.2009, 15:25
Вот только в случае с коннектом к бд никакой паттерн не поможет.
Подключаться придется заново в любом случае

Автор: v00d00 18.9.2009, 15:31
А по какому принципу действует сборщик?

Ведь у меня по идее должна хранится ссылка на объект в статическом поле класса, хотя бы по этому он не может его удалить. 

Или парсер PHP будет каждый раз открывать файл через
Код

require_once('/service/InitConnection.php');    

и создавать новый инстанс?
А старый следовательно удалять?

Добавлено через 4 минуты
Кстати класс этот обертка вокруг INI файла(как вы видели). Просто хранит в себе считанные данные. 

Собственно вопрос и возник потому что использование синглтонов в PHP кажется сомнительным удовольствием.

Автор: NewDima 18.9.2009, 15:41
v00d00, хранит все инстансы только во время генерации ответа на запрос. Паттерн синглетон не предзназначен для передачи инстанса между сессиями запросов. Как только сервер сгенерировал ответ, скрипт отработал, сборщик мусора удалит из памяти все ссылки на синглетон и сам инстанс

Автор: v00d00 18.9.2009, 16:09
Пичаль. Сохраню настройки в пхп файл и буду инклюдить его как есть...

Автор: NewDima 18.9.2009, 16:11
v00d00, есть другой вариант, perl и java (на сколько я знаю) поступают наоборот, именно так как тебе надо  smile

Добавлено через 54 секунды
v00d00, если уж так надо сохранять синглетон - var_export в помощь

Автор: Simpliest 18.9.2009, 16:16
Цитата(v00d00 @  18.9.2009,  15:31 Найти цитируемый пост)
Кстати класс этот обертка вокруг INI файла(как вы видели). Просто хранит в себе считанные данные. 

Собственно вопрос и возник потому что использование синглтонов в PHP кажется сомнительным удовольствием

Singletone гарантирует что при работе скрипта будет только 1 инстанс класса. Но скрипт у тебя завершается отдав данные, 
а работа приложения еще не завершена.

Это особенность веб-приложений - они растянуты/разорваны в пространстве и времени. Т.е., когда произойдет следующий вызов скрипта(обращение к конкретному url) и какой именно скрипт будет вызван, мы не можем сказать со 100%й вероятностью.

Поэтому для корректной работы нам надо хранить "состояния" приложения.

Вот для хранения состояний между запросами/обращениями и используется Registry (в который ты, кстати, можешь сохранить и свой инстанс Singletone)

P.S. Состояния можно хранить и в URL, и в hidden полях на страницах, и в базе/файле на сервере - это уже особенности реализации

Автор: NewDima 18.9.2009, 16:19
Цитата(Simpliest @ 18.9.2009,  23:16)
Вот для хранения состояний между запросами/обращениями и используется Registry (в который ты, кстати, можешь сохранить и свой инстанс Singletone)

Для меня откровение

Добавлено через 6 минут и 6 секунд
И по-моему не правда
Перечитал еще раз полность о ZendRegistry, ничего подобного не нашел, только это (что в начале):
Цитата

A registry is a container for storing objects and values in the application space. By storing the value in a registry, the same object is always available throughout your application. This mechanism is an alternative to using global storage

Автор: Simpliest 18.9.2009, 16:26
http://wiki.agiledev.ru/doku.php?id=tdd:tests_affect_architecture:singletons

Автор: v00d00 18.9.2009, 16:26
На самом деле просто хотелось применить паттерн на практике. Проблема решается намного проще (и по реализации и по скорости выполнения) инклудом настроек. 

Офтопик: Registry  - это часть поставки Зенда? ( как тогда там реализован хранение данных между ответами ?)

Автор: NewDima 18.9.2009, 16:28
Никак, выражаясь языком Simpliest, это глупость

Автор: Simpliest 18.9.2009, 16:29
Цитата(v00d00 @  18.9.2009,  16:26 Найти цитируемый пост)
Registry  - это часть поставки Зенда? ( как тогда там реализован хранение данных между ответами ?) 

Registry - это паттерн. Он ничей smile

Я просто дал, как образец, ссылку на его реализацию в ZF http://framework.zend.com/manual/en/zend.registry.html 

Автор: IZ@TOP 18.9.2009, 16:47
Цитата(NewDima @  18.9.2009,  17:19 Найти цитируемый пост)
Для меня откровение 

Для меня тоже. Не вижу, что бы в Zend_Registry где-то сохранялось состояние объекта между сессиями и потом ресторилось. Да и нет там такого.

Автор: v00d00 18.9.2009, 16:49
Если рассматривать Реестр просто как паттерн он точно также будет каждый раз заново создавать объекты для каждой сессии( или я что-то упустил). Я думал есть реализация на PHP которая как раз решает техническую проблему хранения объектов избегая сборки мусора.

Автор: Simpliest 18.9.2009, 16:59
Блин, сходите по ссылкам, там все написано даже с примерами и у вас не будет глупых домыслов.

В скрипте vasya.php
Создали объект и сохранили
Код

$o = new SomeObject();
file_put_contents('somestore.txt', serialize($o));


В скрипте petya.php
Прочитали
Код

$o = unserialize(file_get_contents('somestore.txt'));


Это у нас новый объект? Или старый?

Автор: IZ@TOP 18.9.2009, 16:59
Цитата(v00d00 @  18.9.2009,  17:49 Найти цитируемый пост)
Если рассматривать Реестр просто как паттерн он точно также будет каждый раз заново создавать объекты для каждой сессии( или я что-то упустил). Я думал есть реализация на PHP которая как раз решает техническую проблему хранения объектов избегая сборки мусора. 

Такого средства нету. Если подумать, php-срипт, неважно, запустился из консоли или исполнился как FCGI, по завершении работы ему состояний в памяти не сохранить, поскольку он отработал и выгрузился. Разве что Apache и mod_php могут предоставить такой функционал, но это все равно будет костылем.

Добавлено через 1 минуту и 29 секунд
Simpliest, ключевое слово 
Цитата(IZ@TOP @  18.9.2009,  17:59 Найти цитируемый пост)
Я думал есть реализация на PHP которая как раз решает техническую проблему хранения объектов избегая сборки мусора. 


Уж наверное до file/shared memory/memcached/db сохранения мы додумались бы?

Автор: v00d00 18.9.2009, 17:02
Цитата(Simpliest @ 18.9.2009,  16:59)
Блин, сходите по ссылкам, там все написано даже с примерами и у вас не будет глупых домыслов.

В скрипте vasya.php
Создали объект и сохранили
Код

$o = new SomeObject();
file_put_contents('somestore.txt', serialize($o));


В скрипте petya.php
Прочитали
Код

$o = unserialize(file_get_contents('somestore.txt'));


Это у нас новый объект? Или старый?

Новый. При дисериализации будет вызван конструктор класса.

Добавлено через 1 минуту и 20 секунд
Цитата(IZ@TOP @  18.9.2009,  16:59 Найти цитируемый пост)
Уж наверное до file/shared memory/memcached/db сохранения мы додумались бы? 

Сорь. Очень скудный опыт веб разработки)

Автор: Simpliest 18.9.2009, 17:06
Цитата(IZ@TOP @  18.9.2009,  16:59 Найти цитируемый пост)
Уж наверное до file/shared memory/memcached/db сохранения мы додумались бы?

Точно?

А то как-то вы хотите конкретной реализации прямо от паттернов.

Паттерн - это не более чем подход/методика/алгоритм.

Добавлено через 8 минут и 34 секунды
Цитата(v00d00 @  18.9.2009,  17:02 Найти цитируемый пост)
Новый. При дисериализации будет вызван конструктор класса

Да ну?
Вы меня радуете....

Выполните два скрипта test.php и потом test2.php

test.php
Код

<?php
include 'sample.php';

$c = new Sample();
$c->newField = 'aaa';
file_put_contents('some.txt',serialize($c)); 
?>
    
                   
test2.php
Код

<?php
include 'sample.php';
$o = unserialize(file_get_contents('some.txt'));
var_dump($o);
?>


sample.php
Код

<?php
class Sample {
    public function __construct() {
        echo 'constructed';
    }

}
?>


some.txt
Код

O:6:"Sample":1:{s:8:"newField";s:3:"aaa";}


Посмотрите на вывод скриптов и застрелитесь.

Автор: nerezus 18.9.2009, 17:47
memcached/etc
Не забывайте юзать мьютексы при работе с данными из кэша.

Автор: IZ@TOP 18.9.2009, 18:09
Цитата(Simpliest @  18.9.2009,  18:06 Найти цитируемый пост)
Точно?

А то как-то вы хотите конкретной реализации прямо от паттернов.

Паттерн - это не более чем подход/методика/алгоритм.

Лично я - ничего не хочу. Я лишь сказал, что способа перекинуть объект не разрушая его между сессиями - нету. От паттернов тем более ничего не жду, я их использую где они нужны и все.

Автор: youri 18.9.2009, 20:58
Цитата(v00d00 @  18.9.2009,  16:49 Найти цитируемый пост)
Я думал есть реализация на PHP которая как раз решает техническую проблему хранения объектов избегая сборки мусора

а ты уже столкнулся с такой проблемой (не теоретически)?

Автор: nerezus 19.9.2009, 09:09
Цитата

а ты уже столкнулся с такой проблемой (не теоретически)?
 Ну как ты думаешь, если бы проблемы не существовало, то зачем тогда в куче проектов юзать memcached и прочие костыли, чтобы ее обойти?)

Автор: Ипатьев 19.9.2009, 09:11
ну, речь здесь, наверное, не о куче проектов, а об одном  конкретном

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)