Паттерн Singleton на PHP5

Thorn

Guest
Паттерн Singleton на PHP5

Вот есть реализация паттерна Singleton на PHP5.
PHP:
class Singleton
{
    // Hold an instance of the class
    static private $_instance;

    private function __construct()
    {
        // Used to prevent object from direct creation
    }

    // The singleton method
    static public function instance()
    {
        if (!isset(self::$_instance)) {
            self::$_instance = new Singleton;
        }

        return self::$_instance;
    }

    // Example method
    public function run()
    {
        echo "method run() in Singleton class";
    }
}
Применение:
PHP:
$singleton = Singleton::instance();
$singleton->run();
или
PHP:
Singleton::instance()->run();
Все бы хорошо, свои функции он выполняет, но есть один момент. Разве должен быть возможен прямой вызов метода run() ?
PHP:
Singleton::run();
результат:
method run() in Singleton class

метод ведь не статический ? кто нибудь может подсказать почему он успешно вызывается ? версия PHP - 5.0.2
 

SiMM

Новичок
> метод ведь не статический ?
Статический. Без прямого указания своей статичности, но это видно из самой функции - для её выполнения нет необходимости в указателе на объект.
 

Thorn

Guest
А есть ли возможность предотвратить прямой вызов метода в неинстанцированном классе ? Как-то нелогично это все :confused:

или, так получается, если в методе не используются переменные класса или другие методы этого же класса - его можно беспрепятственно вызывать ?
 

Thorn

Guest
хм..да, вариант ;) только ломает его во всех методах прописывать )))

ну в-общем спасибо большое, что ответили. Но на самом деле, есть мнение, что было бы правильнее не расценивать такие методы как статические, по-умолчанию.
 

neko

tеam neko
мне если честно влом пробовать....

можешь подумать на тему _call
или как он там
чтобы не прописывать везде

во-вторых я так думаю, что если кто-то начнет вызывать статически то, что для этого не предназначенно он 1 черт увидит варинги

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

-~{}~ 16.02.05 09:55:

и вообще я считаю что синглтон это идеологически неправильный паттерн
 

Thorn

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

PHP:
// Example method
public function Run()
{
    $this->name = 'Run';
    echo "Run method in Singleton class";
}
результат:
Fatal error: Using $this when not in object context in f:\home\...

Все равно не то...карочи ладна, я понимаю что я придираюсь уже к мелочам, но вот к примеру если определить методы __get() и __set() и попытаться вызвать их как статические - получается ошибка именно, какая нужна..."нельзя вызвать метод, который не определен как статический", примерно так звучит... странно все это :confused:

То есть получается если прописать в методе:
PHP:
if (!isset($this)) {
    return false;
}
то можно вообще в один прекрасный момент надолго задуматься...в чем дело и почему метод не вызвался...можно конечно и эксепшн бросать, но это опять же прописывать нужно в каждый метод %)
 

neko

tеam neko
вот так делать точно нельзя
это совершенно очевидно

экспешен или триггер_еррор
 

filter

Новичок
Thorn

Разве это вызов статического метода?

Singleton::instance()->run();
 

neko

tеam neko
получается ошибка именно, какая нужна..."нельзя вызвать метод, который не определен как статический"
я говорю же
засунь их все в __call
но вообще это глупо момоему
довольно серьезные лишние действия, ради весьма сомнительной выгоды

filter
перечитай еще раз первый пост?
 

Thorn

Guest
видишь ли, в чем дело. Хочется чтобы просто было средство раннего выявления ошибок. Просто в качестве предосторожности. А нарочно в каждом методе прописывать проверки и прочее нет желания.

Спасибо за советы. Буду дальше разбираться ;)
 

filter

Новичок
neko
Перечитал - не успел отредактировать :)

Thorn
Я думаю не стоит тебе этим заморачиваться.

В твоем примере он вызвался так как в методе не используются переменные класса.
проблем в его вызове у тебя никогда не возникнет, так как он никогда не нарушит внутреннее состояние объекта, который контролирует твой Синглтон.
 

neko

tеam neko
баловство :)

PHP:
class A
{
	private function _doIt()
	{
		print "Blah!\n";
	}
	
	public function __call( $name, $params )
	{
		if( isset($this) && in_array( '_' . $name, get_class_methods( __CLASS__ ) ) )
			call_user_func_array( array( &$this, '_' . $name ), $params );
		else
			throw new eLamer();
	}
}
товаришь фильтер совершенно верно заметил, что это не имеет смысла
 

Thorn

Guest
Да речи нет, я и сам уже подумал что ну его нафик, заморачиваться этим. Просто было интересно вот и поинтересовался.

P.S. Зато этот пример с __call очень даже удачно подходит чтобы использовать его для вызова методов в CMF которую я потихоньку пишу. В-принципе, я его так и хотел использовать. Ну имена методов прямо в URI прописываются и вызываются в зависимости от уровня доступа )) ...

{HOST}/object/sub_object/method/param_32

объект | метод | параметр_значение

ну собственна, это уже другая история ))))

Кстати, фишку с подчеркиванием не сразу заметил :) интересно придумал )))
 

Screjet

Новичок
PHP:
class Singleton {

	static public $self;
	var $test;

	public function __construct(){
		self::$self = $this;
	}

	public function run(){
		echo "method run() in Singleton class. Test=".$this->test;
	}
}

$t = new Singleton();
$t->test = "Ok\n";
Singleton::$self->run();
Я правильно назначение синглтонов понял? :)
 

Vasya

Guest
Screjet:
Я правильно назначение синглтонов понял?
Неа!
PHP:
<pre><?
/*... класс "синглтон" ... */
$t = new Singleton(); 
$t->test = "Ok\n"; 
Singleton::$self->run();

$t2 = new Singleton(); 
//$t2->test = "Ok\n"; 
Singleton::$self->run();
?></pre>
Выводит следующее:
-----
method run() in Singleton class. Test=Ok
method run() in Singleton class. Test=
-----
 

Screjet

Новичок
Можно попросить объяснения?
1) Идея сингтона в том, чтобы запретить конструктор?
2) Чтобы по определенному статическому методу возвращал только собственную инстанцию?

Как можно применить практически такой подход? Какие преимущества перед обычным объектным подходом?
 

Vasya

Guest
Автор оригинала: Screjet
Можно попросить объяснения?
1) Идея сингтона в том, чтобы запретить конструктор?
2) Чтобы по определенному статическому методу возвращал только собственную инстанцию?
Как можно применить практически такой подход? Какие преимущества перед обычным объектным подходом?
Это тоже довольно обычный объектный подход. Идея синглтона, IMHO, в том, чтобы на всё доступное пространство (в Яве, например, на всю JVM) у тебя был один объект такого-то класса. Например, в ява-сервлетах есть такой
public interface ServletContext
-------------
Определяет набор методов, которые использует сервлет для связи со своим сервлет-контейнером. Например, "получить MIME тип файла", "перенаправить запрос" или "писать в лог-файл".

Существует только один контекст на "web application" , на всю Java Virtual Machine.
-------------
В ПХП есть массив $_SERVER. Он похож на вышеописанное, но не содержит логики, кода, это не объект.

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

-~{}~ 16.02.05 19:49:

Можно применить синглтон для создания "авторитетного источника". Ну, например, Объект спрашивает у Сесии "этот юзер залогинился?". Сессия единственная для запроса, который поступил от одного юзера. Она ему отвечает, что мол "Да. Всё путём.". Если бы Сессий было много и они давали бы разные ответы, то задавать им такие вопросы не имело бы смысла.
 

Screjet

Новичок
Получается идея синглтона унаследована из жавы..
Ну вообще-то (имхо) жава-подход в ПХП неприемлем, т.к. принцип работы двигателя совершенно другой.
Получается в ПХП синглтоны в общем-то ненужны, т.к. в распоряжении програмера есть суперглобалы, а с другой стороны изолирование пространств очень жесткое.. Вобщем понятно.

Спасибо.
 

Vasya

Guest
Re: Паттерн Singleton на PHP5

Автор оригинала: Thorn
...
метод ведь не статический ? кто нибудь может подсказать почему он успешно вызывается ? версия PHP - 5.0.2
http://www.php.net/manual/en/language.oop5.static.php
-------------
dmintz at davidmintz dot org
09-Nov-2004 06:20
[Editor's Note: This is done for back compatability. Depending on your error level, An E_STRICT error will be thrown.]

PHP 5.0.1 doesn't seem to mind if you call a static method in a non-static context, though it might not be the best of style to do so.

On the other hand, PHP complains if you try to try to call a non-static method in a static context (if your error reporting is cranked up to E_STRICT).
PHP:
class Test { 
   
   static function static_method() { 
       echo "Here's your static method: Foo!<br />\n"; 
   } 
   function static_method_caller() { 
       echo "static_method_caller says:  ";$this->static_method();    
   } 
   function non_static() { 
       echo "I am not a static method<br />\n"; 
   } 

} 

$t = new Test(); 
$t->static_method(); 
$t->static_method_caller(); 
Test::non_static();
-------------
 
Сверху