Comments 32
Конечно можно, но… тогда Вы лишаете себя механизма placeholder`ов и вынуждены будете самостоятельно беспокоиться об экранировании переменных. А так же, raw-query сложнее расширить динамически (такое часто требуется, например, при написании фильтров или поиска по различным словиям).
ошибаетесь, у вас есть возможность писать так:
$query = «SELECT id FROM table WHERE id = :id»
$this->fetchAll($query, array(
'id' => 1
));
$query = «SELECT id FROM table WHERE id = :id»
$this->fetchAll($query, array(
'id' => 1
));
А в чем я ошибаюсь-то? Я же написал 2 условия. В Вашем коде выполняется только первое (про placeholder`ы), а второе (про удобное динамическое расширение) — нет. Так что так конечно писать можно, но для тех, кто не любит/хочет так делать — я и предложил свой вариант ;)
Привет из django-world.
model.objects.all().filter(sex__eq=«male»).filter(Q(age__gt=18)|Q(hobby__eq=«sport»)
Если надло расширить запрос, то:
q0 = model.objetcs....blalbalba… # все по запросу из поста
q1= q0.exclude(name__contains=«John») # все из прошлого запроса кроме Джонов
Все эти запросы превратятся в sql при первом обращении к результатам.
Извините за оффтоп. Требуйте расширения ORM у производителя вашего фреймворка.
model.objects.all().filter(sex__eq=«male»).filter(Q(age__gt=18)|Q(hobby__eq=«sport»)
Если надло расширить запрос, то:
q0 = model.objetcs....blalbalba… # все по запросу из поста
q1= q0.exclude(name__contains=«John») # все из прошлого запроса кроме Джонов
Все эти запросы превратятся в sql при первом обращении к результатам.
Извините за оффтоп. Требуйте расширения ORM у производителя вашего фреймворка.
Циклом прибавлять к переменной $select условия where — удобно.
Циклом конкатенировать к строке $select условия where — неудобно.
Такого примера достаточно или нужно кодом?
Циклом конкатенировать к строке $select условия where — неудобно.
Такого примера достаточно или нужно кодом?
Согласен. В плюсы можно так же добавить абстракцию от синтаксиса конкретной RDBMS, автодополнение в IDE.
можно еще попробовать через quoteInto()
$this->select()
->where( "sex = ?", "male" )
->where( $this->quoteInto("age > ?", 18) . ' or ' . $this->quoteInto("hobby = ?", "sport"));
Можно, но это уже извращение, как мне кажется. Если условий хотя бы три — строчка уже настолько длинная, что код становится очень не удобно читать.
С другой стороны этот код более прозрачный.
Ваш код похож на хак.
Ваш код похож на хак.
В моем коде используются только стандартные методы ZF. Но, как говорится, на вкус и цвет… Поэтому Ваше решение, равно как и моё, имеет такое же право на существование. Может стоит ссылку на Ваш комментарий скинуть в топик, как альтернативное решение — может быть кому-то оно понравится больше?
Давайте разберемся.
Для создания сложного ИЛИ вы добавляете, забираете, конкатинируете, ресетите и вставляете заново.
В то время, как discourage сразу вставляет конкатинируемое условие без лишних (путанных) манипуляций.
То, что это сложное условие нельзя втсавить в Zend_Db_Select так же как и простое — недоработка Zend Framework'a.
Для создания сложного ИЛИ вы добавляете, забираете, конкатинируете, ресетите и вставляете заново.
В то время, как discourage сразу вставляет конкатинируемое условие без лишних (путанных) манипуляций.
То, что это сложное условие нельзя втсавить в Zend_Db_Select так же как и простое — недоработка Zend Framework'a.
ваш код не читабелен и не понятен
код discourage понятен и короче
вердикт — ваш код на свалку (ну или на говнокод запостить), код discourage внести в ман
код discourage понятен и короче
вердикт — ваш код на свалку (ну или на говнокод запостить), код discourage внести в ман
Говнокод? Нда… Хорошо, пусть будет так.
В общем-то мне абсолютно все равно на многочисленные необоснованные минусы топика и кармы, топик добавило 4 человека в избранное, если им этот метод хотя бы 1 раз пригодится, значит я уже не зря старался. А Вы можете и дальше писать запросы в стиле raw-query и считать все иное говнокодом, дело Ваше.
У Вас была проблема
Вы ее решили
Но решили ее немного не через голову.
так делать нельзя по многим причинам. Самая главная причина — это то что потом этот код нужно будет сопровождать, либо Вам либо кому нибудь другому.
И уж поверьте через полгода Вы и сами вряд ли сходу поймете что там творится.
надо стараться всегда делать код простым и понятным.
ну а насчет говнокода — эт Вы зря обиделись. Все когда то писали/пишут говнокод.
отличительной чертой такого кода является то что он либо не читаем, не логичен, раздут, не оптимален или все сразу — но при этом всегда (внимание!) он работает
да Ваш код работоспособен. Да Вы разобрались с проблемой. За это вам плюс
но за то что вы показали плохой пример неокрепшим умам — за это минус.
Я б на вашем месте отредактировал статью, добавив те три строчки discourage
И кстати где это Вы в моих словах углядели призыв писать запросы в стиле raw-query?
Чувствую что бесполезно продолжать дискуссию. Вам тут подсказали элегантное решение, а Вы вместо того чтобы поблагодарить человека начали доказывать что Вы Д`артаньян
Вы ее решили
Но решили ее немного не через голову.
так делать нельзя по многим причинам. Самая главная причина — это то что потом этот код нужно будет сопровождать, либо Вам либо кому нибудь другому.
И уж поверьте через полгода Вы и сами вряд ли сходу поймете что там творится.
надо стараться всегда делать код простым и понятным.
ну а насчет говнокода — эт Вы зря обиделись. Все когда то писали/пишут говнокод.
отличительной чертой такого кода является то что он либо не читаем, не логичен, раздут, не оптимален или все сразу — но при этом всегда (внимание!) он работает
да Ваш код работоспособен. Да Вы разобрались с проблемой. За это вам плюс
но за то что вы показали плохой пример неокрепшим умам — за это минус.
Я б на вашем месте отредактировал статью, добавив те три строчки discourage
И кстати где это Вы в моих словах углядели призыв писать запросы в стиле raw-query?
Чувствую что бесполезно продолжать дискуссию. Вам тут подсказали элегантное решение, а Вы вместо того чтобы поблагодарить человека начали доказывать что Вы Д`артаньян
Воспользуясь законами алгебры логики, что мешало написать так?
Поскольку приоритет у AND'а больше следующий запрос выполнится так, как вам надо
$this->select()
->where( "sex = ?", "male" )
->where( "age > ?", 18, "INTEGER" )
->orWhere( "hobby = ?", "sport" )
->where( "sex = ?", "male" );
Поскольку приоритет у AND'а больше следующий запрос выполнится так, как вам надо
SELECT * FROM `table` WHERE `sex`= "male" AND `age` > 18 OR `hobby` = "sport" AND `sex`= "male");
Смотрю документацию Zend_Db_Select тут — framework.zend.com/manual/ru/zend.db.select.html, обратите внимание на Пример #19. Аналогичный запрос реализован иначе, наглядно, человекопонятно и универсально. Всё же не понимаю Ваше стремление добавить непрозрачный getPart с последующей обработкой, ресетом и опять же добавлением обратно в селект. Могли бы Вы привести пример бонуса, который получается в результате этих махинаций, той динамики, о которой речь, и которую никак не реализовать без Вашего метода? Если честно, пока видится только код, за который нужно отрывать руки, чтобы сократить время на чтение кода другими разработчиками.
Не аналогичный. Вопрос экранирования, в приведенном примере #19, не решается. В этом можно легко убедится, немного преобразим пример #19:
На выходе мы получим
Как можно заметить экранирование здесь не работает.
$maximumPrice = 500;
$prodGrade = 'A';
$prod = 'Apple';
$select = $db->select()
->from('products',
array('product_id', 'product_name', 'price'))
->where("product_grade = $prodGrade OR price > $maximumPrice")
->where('product_name = ?', $prod);
echo $select;
На выходе мы получим
SELECT `products`.`product_id`, `products`.`product_name`, `products`.`price`
FROM `products`
WHERE (product_grade = A OR price > 500) AND (product_name = 'Apple')
Как можно заметить экранирование здесь не работает.
Ох, Вы копаете гряблями уважаемый. Для решения вопросов экранирования есть специальные методы.
habrahabr.ru/blogs/zend_framework/111918/#comment_3575966
О которых говорилось выше :)
Здесь исключительно о «примере #19»
О которых говорилось выше :)
Здесь исключительно о «примере #19»
Не знаю, как у вас там в Зенде, но буду сильно удивлен, получив отрицательный ответ:
неужели нельзя расширить класс и дополнить его методами (and_)where_open, (and_)where_close?
P.S.: привет от Kohana.
неужели нельзя расширить класс и дополнить его методами (and_)where_open, (and_)where_close?
P.S.: привет от Kohana.
Согласен с высказавшимися выше, что пример похабный. Читабельность кода сильно страдает.
Справедливости ради надо отметить, что в ZF чрезвычайно дебильно реализован конструктор запросов. В том числе и расширять его неудобно.
Справедливости ради надо отметить, что в ZF чрезвычайно дебильно реализован конструктор запросов. В том числе и расширять его неудобно.
Приведенный в статье пример скорее тянет на хак, нежели на образец кодирования. Мне кажется, более правильным было бы написание своего объекта, позволяющего конструировать сборку OR-условий, и подставлять его в where(). Там кода-то с гулькин нос будет, можно даже вот это всё порно из статьи инкапсулировать и сделать код читаемым.
$this->select()
->where( "sex = ?", "male" )
->where( "(age > ?", 18, "INTEGER" )
->orWhere( "hobby = ?)", "sport" );
Sign up to leave a comment.
Составление запросов со сложными условиями