ДА. ПОНЯЛ ПОЧЕМУ РЕКУРСИЯ!Автор оригинала:
...if(!$instance) здесь некорректно, ибо $instance при первом вызове не определен, надо проверять isset.
во-вторых, тебе не кажется, что тут бесконечная рекурсия?
в общем, http://phpfaq.ru/debug тебе поможет![]()
static function __instance() {
if(!isset($this->instance)) $this->instance = new Singleton();
else return $this->instance;
}
static function __instance() {
if(!isset($this->instance)) {
$this->instance = true;
$this->instance = Singleton::__instance();
}
else return $this->instance;
}
найди отличия в своем кодеPHP:static function getInstance() { if (self::$instance == NULL) { self::$instance = new Logger(); } return self::$instance; }
class Singleton {
static private $instance = NULL;
private function __construct() { }
private function __clone() {}
public static function __instance() {
if(is_null(self::$instance)) self::$instance = new Singleton();
return self::$instance;
}
public function hello() {
echo "Hello, World";
}
}
$single = Singleton::__instance();
$single->hello();
Но далее история повторяетсяHello, World
class Registry extends Singleton {
private $modules;
function get($key) {
return (isset($this->modules[$key])) ? $this->modules[$key] : false;
}
function set($key, $object) {
$this->modules[$key] = $object;
}
}
class Test {
function __construct() {
Registry::set(get_class($this), $this);
}
function check() {
echo "Current registry is: ";
print_r(Registry::get(get_class($this)));
echo "<br>";
}
}
$test = new Test();
$test->check();
Current registry is: Test Object ( [modules] => Array ( [Test] => Test Object *RECURSION* ) )
всё-равно спасибо. а что дальше?Автор оригинала: fixxxer
upd: опоздал![]()
ну правда не понимаюАвтор оригинала: fixxxer
ой, ну а сам ты как думаешь? а если проверить? ну ведь это же быстрее и полезнее, чем ждать пока кто-то ответит, правда же?![]()
class Singleton {
...
public static function __instance() {
if(is_null(self::$instance)) self::$instance = new Singleton();
else echo "instance already constructed. ";
return self::$instance;
}
...
}
class Registry extends Singleton {
private $modules;
function __construct() {
echo get_class($this)." reports: ".get_class(self::__instance())."<br>";
}
...
}
$single = Singleton::__instance();
$single->hello();
$reg = new Registry();
судя по всему, запоминает...Hello, World
instance already constructed. Registry reports: Singleton
class Registry extends Singleton {
private static $modules;
static function get($key) {
return (isset(self::$modules[$key])) ? self::$modules[$key] : false;
}
static function set($key, $object) {
self::$modules[$key] = $object;
}
static function check() {
print_r(self::$modules);
}
}
class Test {
function __construct() {
Registry::set(get_class($this), $this);
}
function test() {
echo "inner calling work successfully!<br>";
}
}
class innerCallingTest {
function __construct() {
Registry::set(get_class($this), $this);
}
function test() {
echo Registry::get("Test")->test();
}
}
В какой-то момент времени, я подумал: а как же я пытаюсь обратиться к методу неинициализированного класса Registry? И сделал оба метода статическими. В результате, "лёд тронулся" и пошло говно по трубам".inner calling work successfully!
Array ( [Test] => Test Object ( ) [innerCallingTest] => innerCallingTest Object ( ) )
спасибо. теперь отвечу.Автор оригинала: ustas
почему тут работает только класс2? точно должен понять.
Если из головы выбрасить названия такие как патерн, сиглинтоны фсякие, то понять будет проще.
http://www.php.net/manual/ru/language.oop5.static.php
проблема в обращении из статического метода к несозданому обьекту и еще через $this- то есть текущий объект (сделать невозможное). если бы ты включил error_reporting(E_ALL | E_STRICT);
понял бы быстрее
ini_set('display_errors',1);
error_reporting(E_ALL);
те же яйца, только в профильАвтор оригинала: ustas
читай еще раз error_reporting(E_ALL | E_STRICT);
class core_ModuleSingleton
{
protected static $instance;
function __construct()
{
}
function __destruct()
{
}
public static function __instance()
{
if(is_null(self::$instance))
{
self::$instance = new core_ModuleSingleton();// кстати, можно и self::$instance = new self;
}
return self::$instance;
}
function doit()
{
return 'core_ModuleSingleton';
}
}
class core_ModuleSingletonUrlWrapper extends core_ModuleSingleton
{
function doit()
{
return 'core_ModuleSingletonUrlWrapper';
}
}
я это, не долго думая, продемонстрирую как я решил проблему наследования SingltonaАвтор оригинала: maxru
Так вот, как видно из вышеприведенного кода видно, что статический метод класса core_ModuleSingleton возращает экземпляр core_ModuleSingleton, то есть себя самого.
При получении экземпляра core_ModuleSingletonUrlWrapper через метод __instance() я получаю core_ModuleSingleton (что вполне естественно), а мне надо получить core_ModuleSingletonUrlWrapper.
Либо я совсем дурак, либо чего-то недопонял. Как же все-таки получить core_ModuleSingletonUrlWrapper через core_ModuleSingletonUrlWrapper::__instance() ?
class Singleton {
public static function __instance($classname) {
if(is_null(self::$instance) || get_class(self::$instance) != $classname) self::$instance = new $classname();
Registry::set(get_class(self::$instance), self::$instance);
return self::$instance;
}
}
class Test extends Singleton {
function message($msg) {
echo $msg;
}
}
$test = Singleton:__instance("Test");
$test->test("Всё работает");
Э-э-э-э... белиберда и получицца. test() на то и тест - чтобы не париццаАвтор оригинала: maxru
Погоди-ка... а если я белиберду запихну в $test->test('@##@$#@^#@$^#$^#$&%#$&%&') - что получится, а?