Как получить имя дочернего класса в статичном методе родительского

kode

never knows best
Как получить имя дочернего класса в статичном методе родительского

Вопрос такой, как узнать имя класса "сына" в обьекте родителя. необходимо в реализации шаблона синглтон. Те код-тест

PHP:
class base_module {
	protected static $instance;

	static function getInstance(){
		if(!isset(self::$instance)){
			$class = __CLASS__; // <------------------- см. сюда
			self::$instance = new $class;
		}

		return self::$instance;
	}

	public function test(){
		return get_class($this);
	}
}

class simple_module extends base_module {

	function __construct(){
		//some stuff
	}

}

$module = simple_module::getInstance();

if($module->test() == "simple_module"){
	echo "Test success";
}else{
	echo "Test failed!";
}
Вариант с извратов ввиде разбора бектрейса не пойдёт.


PS. Сразу говорю, вариант с перегрузкой метода в дочернем классе c передачей названия класса в параметре тоже не катит (сейчас так сделано, но блин это против моей религии)
PSS. Кто предолжит get_class($this) - найти ближайшую стенку и убитсо.
PSSS. Вариант "никак" ожидаем и приемлем, всё равно парочка решений есть (в основном на передаче имени класса параметром, просто фактически такие методы - костыли)
 

kode

never knows best
Автор оригинала: zerkms
в статике получить - имхо никак


в бэктрейсе этой инфы нет

ps: убери & у getInstance
Посмотри паттерны в доках....мы что передаём? да - мы передаём ссылку на обьект, но не принципиально

В моём случае инфу можно вытянуть из бектрейса, но нестоит :)

PHP:
class base_module {
	protected static $instance;

	static function getInstance($class){
		if(!self::$instance){
			self::$instance = (get_parent_class($class)==__CLASS__)?new $class:null;
		}

		return self::$instance;
	}
	
	public function test(){
		return get_class($this);
	}
}

class simple_module extends base_module {

	function __construct(){
		/* stuff */
	}

}

$class = 'simple_module';

$module = eval("return {$class}::getInstance('{$class}');");

if($module->test() == $class){
	echo "Test success";
}else{
	echo "Test failed!";
}
Вот рабочий, но децл извращённый вариант, фактически "костлявый" вариант
 

zerkms

TDD infected
Команда форума
Посмотри паттерны в доках....мы что передаём? да - мы передаём ссылку на обьект, но не принципиально
перед тем как тыкать в доку, надо быть уверенным, что сам знаешь ту её часть, в которую тыкаешь

Код:
As of PHP 5, objects are assigned by reference unless explicitly told otherwise with the new clone keyword
+ пример из мануала
PHP:
class Example
{
   // Hold an instance of the class
   private static $instance;
   
   // A private constructor; prevents direct creation of object
   private function __construct() 
   {
       echo 'I am constructed';
   }

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

       return self::$instance;
   }
   
   // Example method
   public function bark()
   {
       echo 'Woof!';
   }

   // Prevent users to clone the instance
   public function __clone()
   {
       trigger_error('Clone is not allowed.', E_USER_ERROR);
   }

}
вместо того, чтобы самому же почитать о паттерне фабрика (или фабричный метод) - ты пытаешься делать костыли, при этом ещё и говоришь что они лучше переопределения методов в наследниках. зачот, угу ;)
 

kode

never knows best
Автор оригинала: zerkms
перед тем как тыкать в доку, надо быть уверенным, что сам знаешь ту её часть, в которую тыкаешь

Код:
As of PHP 5, objects are assigned by reference unless explicitly told otherwise with the new clone keyword
вместо того, чтобы самому же почитать о паттерне фабрика (или фабричный метод) - ты пытаешься делать костыли, при этом ещё и говоришь что они лучше переопределения методов в наследниках. зачот, угу ;)
фактический у меня фабрика реализована, но дальше, мне нужно тут с наследственным синглтоном разобратся. :) Использование фабрики не подуразумевает что получаемые обьекты синглтоны. К тому-же здесь не весь шаблон. Хотя тут разницы мало, всё равно не деле всё по другому написано, это я просто намекаю что давай-те писать по делу а не к деталям привязыватся, то как __тут__ (те на форуме) написано меня мало волнует, мне интересно получить знания по теме не сваливаясь в холивар по тему стоит ли обьекты возвращять ссылкой. Если это задевает твои религиозные чуства :) или режет глаз - я уберу.
 

zerkms

TDD infected
Команда форума
PHP:
<?php
class a {}
class b extends a {}
class c extends b {}
class d extends a {}

function factory($name)
{
    if (!class_exists($name)) {
        throw new Exception('Class ' . $name . " doesn't exists");
    }
    
    $class = new ReflectionClass($name);
    return $class->newInstance();
}

var_dump(factory('a'));
var_dump(factory('d'));
точно так же фабрику можно спрятать и в статический метод класса a.

понятно - что метод не исключает и прямого инстанциирования класса, но в зависимости от целей - можно пользоваться и им
 

kode

never knows best
Автор оригинала: zerkms
PHP:
<?php
class a {}
class b extends a {}
class c extends b {}
class d extends a {}

function factory($name)
{
    if (!class_exists($name)) {
        throw new Exception('Class ' . $name . " doesn't exists");
    }
    
    $class = new ReflectionClass($name);
    return $class->newInstance();
}

var_dump(factory('a'));
var_dump(factory('d'));
точно так же фабрику можно спрятать и в статический метод класса a.

понятно - что метод не исключает и прямого инстанциирования класса, но в зависимости от целей - можно пользоваться и им
Видимо нету красивого решения - будем костылить :)
 

kode

never knows best
всем хорошо, но всёравно костыль. Вот например у меня в конструкте есть какое-то действие, которое нельзя выполнять несколько раз (например к базе коннектимся). не смертельно, но нужно учитывать что не только я буду классы писать. ИМХО вариант выше больше подходит, но там свои проблемы (в уме уже накидал парочку)

За ссылочку спасибо, вот только get_called_class(); не нашёл в мане :)) + там используются cvs ные "возможности" :)

Можно только надеятся что 5.3 зарелизили побыстрее.
 
Сверху