YiiFramework Опасность в архитектуре yii Active Record

grigori

( ͡° ͜ʖ ͡°)
Команда форума
upd: *FIXED*

Мы сегодня наткнулись на серьезный недостаток архитектуры Active Record.

Программист написал в конструкторе модели Active Record обращение к несуществующему полю (к приватному полю родительского класса).

Пошел вызов CActiveRecord::__get(), оттуда - $this->getMetaData(), там вызов self::model(get_class($this)) - и там new $classname.

Рекурсия, сегфолт без логов, потерянный день, срыв запуска проекта.

Quang - говноархитектор. Как в его светлую голову пришла идея создавать экземпляр объекта при создании экземпляра объекта - непонятно.

Рекурсивное создание объекта - не исклчительная ситуация. При первом обращении к модели ActiveRecord всегда создается дополнительный instance для ... получения данных о структуре таблицы в базе. Этот дублирующий объект создается с параметром: new $className(null), который введен для разрыва бесконечной рекурсии.
Почему бы не получать информацию из отдельного класса, написанного для получения информации о структуре базы? Не знаю. Но злюсь.
Обращение к несуществующему полю - ошибка. Но архитектура, при которой ошибка приводит к сегфолту и потере дня целой командой - это дерьмо. Переведу на английский и напишу это ему.
 

Ragazzo

TDD interested
Переведу на английский и напишу это ему.
Мне кажется он не оценит :D Хотя всякое может быть. Кстати насколько стало изветсно сейчас 2ую ветку делает он почти один, может учтет это небольшое замечание :)
 

MiksIr

miksir@home:~$
У всех свои тараканы. У Yii такой таракан - не трогай конструктор, делай все в init().
 
  • Like
Реакции: Gas

fixxxer

К.О.
Партнер клуба
лол )) жесть какая

я могу понять, зачем хочется запихать в один класс, но и тут есть нормальные варианты
1) всю структуру засунуть в статики и использовать LSB
2) если уж так вышло как вышло, то никаких new classname, но ReflectionClass::newInstanceWithoutConstructor (если php < 5.4, берем хак из phpunit mockbuilder)
 

Ragazzo

TDD interested
fixxxer
ну BC же, плюс MiksIr верно подметил, зачем лезть туда куда не надо? это "just asking for troubles". Компоненты кстати через рефлексию инстанцируются да.
 

keltanas

marty cats
Мы сегодня наткнулись на серьезный недостаток архитектуры Active Record.
Да там вся архитектура - один большой недостаток.

Quang - говноархитектор.
Вот поэтому я на Yii посматриваю с осторожностью, и использую только на мелких сайтиках.

К тому же, сколько видел на нем проектов, во всех такой гавнокодище, что страшно становится. Тот же турдукен, только с использованием фрейворка. Словом, MVC в Yii для слабаков.
 

Ragazzo

TDD interested
keltanas
2ГИС смотрят на тебя... ну ты понял :D
>>Да там вся архитектура - один большой недостаток.
LOL
 

fixxxer

К.О.
Партнер клуба
fixxxer
ну BC же, плюс MiksIr верно подметил, зачем лезть туда куда не надо? это "just asking for troubles". Компоненты кстати через рефлексию инстанцируются да.
а я специально упомянул п.2.

разжую

php 5.4+ http://www.php.net/manual/en/reflectionclass.newinstancewithoutconstructor.php
php <5.4 https://github.com/sebastianbergmann/phpunit-mock-objects/blob/1.1/PHPUnit/Framework/MockObject/Generator.php#L230
 

Ragazzo

TDD interested
fixxxer
не надо мне разжовывать, я в курсе что такое MockBuilder и как он работает) просто странно что люди думают что залазя туда куда не надо они обязательно ничего не поломают, что за бред? есть же разумные границы которые переходить не надо, таких примеров думаю в других ФВ тоже можно найти, just тюлень.
 

fixxxer

К.О.
Партнер клуба
какие границы? если я все правильно понял, то выкидывая промежуточные шаги имеем:

1. Программист написал в конструкторе модели Active Record обращение к несуществующему полю
2. Рекурсия и segv

Это нормально, чтоли? =)
 

Ragazzo

TDD interested
fixxxer
Программист написал в конструкторе модели Active Record обращение к несуществующему полю
это нормально? в других языках например бы не скомпилировалось вообще :D
еще раз, никто не говорит что это нормально, а говорят не ходите туда куда не надо, или ходите, но осторожно. Тем более я думаю Кьенг так и ответит, хотя возможно это один из тех critical которые просмотрели, все же люди, да?
 

fixxxer

К.О.
Партнер клуба
вот если бы не скомпилировалось, или кинулся exception, или фатал еррор - это бы было нормально =)

если в конструктор ходить и писать там что-либо своими ручками нельзя вообще - он должен быть final.

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

Ragazzo

TDD interested
fixxxer
вот если бы не скомпилировалось, или кинулся exception, или фатал еррор - это бы было нормально
это к похапе наверное больше.
каждый раз этому фреймворку удается меня вновь удивить
зе юник ван :)
если в конструктор ходить нельзя вообще - он должен быть final.
никто не говорит что вообще ходить нельзя, можно но осторожно, чтобы не разрушить в том числе и иерархию классов. Ну ты понял вообщем меня, не мне тебе объяснять же BC и прочее ;)
 

fixxxer

К.О.
Партнер клуба
защита от дурака все равно нужна. ну там флажок при вызове инита выставлять "теперь можно" и его проверять, или вроде того

да хоть бы и банальный счетчик рекурсий
 

Ragazzo

TDD interested
fixxxer
никто не спорит что можно, а еще лучше сделать PR :) ладно тема избита походу уже со всех сторон.
>>ну там флажок при вызове инита выставлять "теперь можно"
как выше уже написали в ините и нужно "всякие свои дела" делать, на это он и нужен, т.е. тот самый "флажок".
 

fixxxer

К.О.
Партнер клуба
вот если бы не скомпилировалось, или кинулся exception, или фатал еррор - это бы было нормально
это к похапе наверное больше
вот не надо к похапе! в 5.0.x __get дергался только для undefined, но не для private/protected, это было жутко неудобно :)

UPD ээ, причем тут это вообще. пойду спать )
 

Ragazzo

TDD interested
keltanas
почитай их статьи на хабре и вообще как они его используют. Я не сомневаюсь что ты хороший разработчик но твои аргументы в пользу того "Yii говнокод и вообще проблемный с точки зрения архитектуры fw" опровергаются готовыми проектами крупных компаний, вообщем считай как хочешь, всем же все равно ;) Любой может найти говнокод на Kohana/Symfony/Laravel/Etc и сказать "Вот смотрите какое Г... Фу такими быть".
 

fixxxer

К.О.
Партнер клуба
Не то что прямо проблемный, но ОЧЕНЬ много небрежностей в обработке исключительных/нестандартных ситуаций. Это нормально для in-house разработки, но нехорошо для публичного fw.
 
Сверху