Создание экземпляра пользовательского класса унаследованного от созданного в расширении

vGhost

Новичок
Подскажите, как можно создать экземпляр пользовательского класса в расширении.
Допустим я создал в расширении класс "A", в нём есть статический метод getInstance потом в пхп коде:
PHP:
class B extends A{}
$o = B::getInstance();
Задача в том что я не знаю как в коде getInstance можно узнать имя пользовательского класса и создать его, а не экземпляр "A".
 

vGhost

Новичок
Вы издеваетесь? Я же написал что вопрос про расширение, а не про пхп.
Мне на сях надо создать этот экземпляр, при помощи object_init_ex в который надо передать class_entry которого у меня в расширении "как бы нет.".
 

fixxxer

К.О.
Партнер клуба
Простого способа нет. Но вообще не стоит этого хотеть. :) Единственный случай, когда это имеет смысл - это штуки типа DateTIme::createFromFormat() [1].

Всяким getInstance нечего делать в библиотеках и тем более расширениях: управление зависимостями - это забота DI.

[1] там тоже LSB не работает, и судя по тому, сколько времени висит баг, это действительно непросто.
 

vGhost

Новичок
Простого способа нет.
А не простой способ? Мы не ищем лёгких путей :D

Но вообще не стоит этого хотеть. :)
А если очень хочется? Я конечно могу накостылять getInstance на стороне пхп кода, создать базовый на сях, потом создать пользовательский в пхп и перекопировать все свойства базового класса в пользовательский. Но чёт как то не хочется так делать.

Единственный случай, когда это имеет смысл - это штуки типа DateTIme::createFromFormat() [1].
Увы, мне приходила мысль посмотреть исходники пыха, но увы там точно такое же поведение, если сделать
PHP:
class test extends DateTime {}
$date = test::createFromFormat('Y-m-d', '2009-02-15');
То мы в итоге получим экземпляр класса DateTime, а не test. И чёт мне в голову не приходит не один пышный класс который вёл бы себя иначе. Так что даже не знаю где посмотреть можно было бы.

[1] там тоже LSB не работает, и судя по тому, сколько времени висит баг, это действительно непросто.
Ну, я бы не назвал это багом, я не помню чтоб где то в документации было заявлено что должно быть иначе, это скорей особенность, ведь в том же пхп коде программист может писать как "new static" так и "new self", и то что она долго висит это вполне может быть из за того что мало кому надо чтоб оно было иначе.
 

fixxxer

К.О.
Партнер клуба
непростой - там каким-то макросом можно взять колл стек и оттуда выдрать :)
 

Вурдалак

Продвинутый новичок
LSB — очень сомнительная с точки зрения теории хрень. И правильно, что без костылей нельзя, ибо нефиг.

Оффтопег: а не надо от DateTime наследоваться, его вообще было бы неплохо final'ом сделать, ибо нехер.
 

fixxxer

К.О.
Партнер клуба
В похапе через lsb решаются проблемы, обусловленные другими проблемами похапе. Скажем, отсутствие перегрузки конструкторов. Ну или вот всякие Foo::dao().
 

Вурдалак

Продвинутый новичок
Зато это вносит новые проблемы: на конструктор наследника накладываются ограничения.

А что с Foo::dao()?
 

fixxxer

К.О.
Партнер клуба
Ну а как его сделать? Либо заставлять везде имплементить метод, либо get_called_class() или new static в базовом классе (== lsb), либо всякая жесть с eval().
 

Вурдалак

Продвинутый новичок
Вурдалак, пускай сначала сделают нормальное API для DateTime, а потом хоть final, хоть что.
Для расширения API тебе не нужно обязательно наследоваться, юзай сторонние сервисы, хоть тот же Carbon.

Ну а как его сделать? Либо заставлять везде имплементить метод, либо get_called_class() или new static в базовом классе (== lsb), либо всякая жесть с eval().
Ты о чём? Ты про Foo::dao()? Это типа получение DAO/DataMapper для сущности? А зачем вообще такой метод делать? И откуда у сущностей базовый класс?
 

hell0w0rd

Продвинутый новичок
Absinthe, Carbon наследует DateTime, а Вурдалак предлагает запретить это самое наследование.
Вурдалак, не говори чушь, все интерфейсы в современном коде используют \DateTime, как ты сервисом его реализуешь?

vGhost, проблема в том, как реализовать return new static() в расширении?
 

Вурдалак

Продвинутый новичок
hell0w0rd, то, что тебе не хватает от DateTime, ты можешь реализовать чем угодно, а потом написать ->toDateTime(). not a rocket science. Кстати, а что именно не хватает?

Сам по себе Carbon, как я погляжу, юзает modify() обычного DateTime. ололо пыщ пыщ. http://derickrethans.nl/immutable-datetime.html
 

Absinthe

жожо
hell0w0rd, то, что тебе не хватает от DateTime, ты можешь реализовать чем угодно, а потом написать ->toDateTime(). not a rocket science. Кстати, а что именно не хватает?

Сам по себе Carbon, как я погляжу, юзает modify() обычного DateTime. ололо пыщ пыщ. http://derickrethans.nl/immutable-datetime.html
Самому не нравится, что он наследник DateTime, но, вероятно, это сделали для того, чтобы было легче заменить DateTime в существующем коде.
 

vGhost

Новичок
В общем, я решил проблему, всем спасибо за участие, решается так:
Код:
zend_class_entry* ce = 0L;
if (EG(called_scope)) {
    ce = EG(called_scope);
} else if (!EG(scope))  {
    ce = EG(scope);
}
if(object_init_ex(return_value, ce) != SUCCESS) {
// еррор
} else {
// экземпляр удачно создан
}
 
Сверху