Критика работы с БД в SimplePHPframework от AmdY

флоппик

promotor fidei
Команда форума
Партнер клуба
И если я опечатаюсь в имени поля — я получу ошибку именно в той строке, где я обратился неправильно, ведь сюрприз — моя модель знает о структуре таблицы! А ты будешь ловить все ошибки всегда в одном месте — там, где ты запрос выполнить пытаешься.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
А теперь пишем обновление данных в табличке... а может, это не апдейт, а инсерт? А нам какая разница, нам SQL не писать!

PHP:
$history = ORM::factory('history', $id);
$history->user_id = 146;
$history->save();
А может, у нас там большая форма в админке? Форма редактирования, или создания? Все ли поля заполнены? А какая разница?
PHP:
$history = ORM::factory('history', $id);
$history->values($_POST, array('user_id', 'point_id', 'source'));
$history->save();
А теперь выведем ка мы их на страничке:
PHP:
$history = ORM::factory('history', $id);
if ($history->loaded())
{
   $this->set('history', $history); // Вуаля! У нас в шаблоне есть все данные из записи! Мы можем их вывести так, как только захотим!
} else
{
  throw new Http_Exception_404();
}
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Возможно, Фанат, тебе стоит преодолеть полутора секундный барьер самому. а?
 

Фанат

oncle terrible
Команда форума
упадет с ошибкой, ведь date по которому ты сорируешь — зарезервированное слово.
у меня не падает.

по остальному.
ты не есликай, ты сразу примеры приводи.
в частности, пример where со скобками. и сразу чтобы между условиями во WHERE было не AND, а OR.
меня смущает это "вроде".
 

Фанат

oncle terrible
Команда форума
А теперь пишем обновление данных в табличке...
вот это сообщение состоит из говнорекламы чуть более, чем полностью.
в демо-песочницах всё так и есть - я и спорить не буду :)

меня больше интересует реальный код из реальных приложений.
к примеру, у меня юзер пишется в две или более таблиц.
 

WMix

герр M:)ller
Партнер клуба
я незнал все строки интересуют или всего одна.. сорь
PHP:
$res = $this->getAdapter()->fetch[Row/All/..]($sql);
если строка читать как
PHP:
$res = $this->getAdapter()->fetchRow($sql);
если все строки как
PHP:
$res = $this->getAdapter()->fetchAll($sql);
 

MiksIr

miksir@home:~$
> к примеру, у меня юзер пишется в две или более таблиц
Подписываем модель второй таблицы на события записи в первой. По этому событию - создаем вторую запись.

Секрет заключается в том, что эта работа является нормальной для всех. Вообще для всех. В реальной жизни.
В воображаемом идеальном мире, в котором живёт большинство программистов - да, это ненормально, и никогда не бывает.
В грязном грешном реальном коде - это везде. В качестве досадных исключений, TODOs, временных хаков и заплаток - но везде. И меньше этих "временных" исключений не становится

поэтому лично я - за реализм.
Как было написано в одном объявлении - "Не льсти себе - встань поближе" ;-)
Фанат, мне кажется ты забыл, что это не форум студентов твоего класса у которых 0 опыта, много теории в голове и Великий Учитель. Многие, кому ты тут говоришь "не теоретизируй", каждый день делают практику и на практике прошли весь путь с граблями. Может у тебя и правда архитектура так ужасна, что любое красивое решение сразу обозначается "песочница,в реальности так не бывает". Бывает...
 
  • Like
Реакции: scb

флоппик

promotor fidei
Команда форума
Партнер клуба
Фанат
слишком много слов.
кода было бы достаточно
 

WMix

герр M:)ller
Партнер клуба
в частности, пример where со скобками. и сразу чтобы между условиями во WHERE было не AND, а OR.
для OR в zend зарезервированно orWhere(...) но порою используя эти методы код становиться плохочитабельным, бывает извращаюсь, но все можно написать именно таким способом, и юнионы туда приписать, и вложенные селекты с юнионами
http://stackoverflow.com/questions/11676291/zend-framework-db-complex-where-or-condition
 

AmdY

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

Отличный повод перейти от теоретических рассуждений к практике.
Вот тебе пример классического случая ручной склейки.
PHP:
$where = $db->parse("month(`date`)=?i and year(`date`)=?i", $data['month'], $data['year']);

if ( $point_id ) {
	$where .= $db->parse(" AND point_id=?i",$point_id);
}
if ( $source ) {
	$where .= $db->parse(" AND source=?s",$source);
}
$sql = "SELECT *, day(date) day, price*num as sum FROM history WHERE $where ORDER BY date DESC";
$res = $db->query($sql);
приведи, пожалуйста, примеры возможных ошибок и реализацию того же самого с помощью билдера.
И посмотрим, сколько тут где ручного труда и возможных ошибок :)

no pseudocode, please.
Поздравляю, Фанат только что реализовал мой Frm\Db\Where, только придётся вручную доставлять скобки на случай OR и вложенные условия. Я так понимаю основная проблема этого подхода для тебя - это неумение пользоваться чужим высокоуровневым кодом.


--------
И давай вернёмся к отправной точке, когда ты ловко разделил темы. Вот пост через четыре минуты после которого ты открыл новую ветку. http://phpclub.ru/talk/threads/Подскажите-задания-для-новичков.73672/page-5#post-658250
Как видишь, это не подход из моего фреймворка, а общепринятая практика, которой разработчики пользуются уже не один год.
 
  • Like
Реакции: scb

cDLEON

Онанист РНРСlub
AmdY
Так весь твой фреймворк - это "общепринятая практика" из Коханы. Зачем было городить ещё один фреймворк, если он имеет минимум отличий от какого то другого ? Почему не навесить надстройки над тем фреймворком, по "общепринятой практике" которого ты делаешь свой? Или задам вопрос по-другому: какие проблемы твой фреймворк решает лучше коханового ? Бандлы с лапшой внутри?
 

флоппик

promotor fidei
Команда форума
Партнер клуба
cDLEON, ты бы лучше что-нибудь по теме дискуссии написал.
 

AmdY

Пью пиво
Команда форума
cDLEON
собственно, там и есть кусок роутинга вытянутый и дописанный из коханы, обрезка слоя работы базы из основного фреймворка и локатор. Так что ты абсолютно прав, он никому не может быть полезен и не дай бог кто-то нашёл в нём пользу. Это просто высер из-за наличия кучи свободного времени. Как-то мы с коллегой обедали, он рассказал что послушал доклад папы php, где Расмус критиковал современные толстые фреймворки, поэтому коллега набросал свой микрофреймворк. Соответственно в тот же день я соорудил этот фреймворк, чтобы показать как круто это всё будет на php 5.4 c использованием bindTo для замыканий роутеров.
так что твоя оценка абсолютно верная, бесполезный высер из-за наличия лишнего времени.

Сейчас убегаю, вернусь прикреплю реальный пример того как работает мой настоящий фреймворк, которым я пока не готов делиться.
 

Ragazzo

TDD interested
Фанат настолько умеет тонко троллить, хотя я бы даже не назвал это троллингом, какое-то особое мастерство развести срач на кучу страниц между топ-кодерами)
 

MiksIr

miksir@home:~$
Да понятно что он пытается сказать. Не понятно одно - почему у него все или черное или белое. Меня совершенно не напрягает использовать ORM и одновременно в случае сложных запросов - писать SQL. Почему я должен всегда писать SQL - я не понимаю. Равно как не понимаю - почему я должен писать все обязательно строчкой, а не использовать какой-нибудь билдер, в котором по сути будет тот же SQL, только чуть более структорированный.
Берем пример:
PHP:
        $crit = new CDbCriteria(array(
            'select' => 'bi.brand_id, mi.model_id, t.KPP, t.hppower, t.fuel, t.body, MIN(t.price) as price, GROUP_CONCAT(t.id SEPARATOR ",") AS ids',
            'join' => 'LEFT OUTER JOIN '.$db->quoteTableName("brand_import").' AS bi ON t.brand=bi.name AND bi.brand_id IS NOT NULL '
                . 'LEFT OUTER JOIN '.$db->quoteTableName("model_import").' AS mi ON t.model=mi.name AND bi.brand_id=mi.brand_id',
            'condition' => 'mi.id IS NOT NULL AND bi.id IS NOT NULL',
            'group' => 'bi.brand_id, mi.model_id, t.KPP, t.hppower, t.fuel, t.body'
        ));
Ну да, SQL. Ну да, завернут в обертку. Ну да, особых плюсов не дает, но мне так нравится. Фанату не нравится. Меня это волнует? Нет.

Хотя, дает плюсы, немнго, но дает.
PHP:
if (is_array($ids) && !empty($ids)) {
   $crit->addInCondition("t.id", $ids);
}
И никаких склеиваний.
Или более простой пример - условие на id c учетом того, что оно может быть NULL. Как решаем в склеивании? Правильно, if-ом с is_null. Как решаем с билдером? Да никак, даем в addCondition, а что уже добавить в SQL - id=5 или id IS NULL решает библиотека.

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

AmdY

Пью пиво
Команда форума
Как обещал, выкладываю пример стандартного бандла с фронэндом и админкой с фреймфорка из которого вырезаны куски для SimplePHPframework, чтобы было понятно, до какого уровня можно развить функциональность.
исходные коды https://github.com/AmdY/phpkiss/tree/master/vendor/Bundle/News
как это выглядит https://github.com/AmdY/phpkiss/wiki

Теперь топикстартер может рассказать мне как я неправильно продумал работу с бд, и как мучаюсь нерасширябельностью данного решения, и плачу по ночам от хардкординга SQL
 
Сверху