LINUX.ORG.RU

Пыхотред

 


1

5

А чего это у нас, в нашем загончике, нет закрепленного пыхотреда?

Вот теперь есть(надеюсь, его закрепят).

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

В тред приглашаются все пыхобоги, пыходемоны, пыхофрилансеры, простые пыхари, и даже пыхоненавистники.

Обсудить есть много чего, начиная с различий версий, особенностей языка, CMS-ок, фреймворков, и заканчивая говнокодом.

<?php

Целая куча событий происходит за сценой. Взять хотя бы вот этот код, откуда-то из PHP-документации:
@fopen('http://example.com/not-existing-file', 'r');

Что он будет делать?

Если PHP скомпилирован с --disable-url-fopen-wrapper, он не будет работать. (Документация не говорит, что означает «не будет работать»; вернёт null, бросит исключение?) Заметьте, что этот флаг убрали в PHP 5.2.5.
Если allow_url_fopen выключен в php.ini, он тоже не будет работать. (Как не будет? Нет идей.)
Из-за @, предупреждение о несуществующем файле не будет выведено.
Но будет выведено, если scream.enabled установлен в php.ini.
Или если scream.enabled вручную установлен через ini_set.
Но не в том случае, если не установлен корректный error_reporting.
Если оно будет выведено, куда оно будет выведено зависит от display_errors, снова в php.ini. Или ini_set.
LongLiveUbuntu ★★★★★ ()
Ответ на: комментарий от cab

Если ты об этом

SELECT * FROM auth_user u
JOIN business_entity_users b ON u.id = b.user_id
JOIN entity e ON b.entity_id = e.id
WHERE e.name='ЯНДЕКС' AND u.username = 'ph'

то это мало того что многословно, но я ещё и не разглядел ни подготовку параметров, ни разбор ответа.

Когда я пишу
$res = ORM::factory('RentContract', @$_POST['id'])
  ->values($_POST)
  ->save()
  ->as_array();
print_r($res);
// ['rent_id' => 25, ..]

то вообще-то я тебе показываю весь процесс. Ты же мне показал лишь часть решения. Давай эскейпинг, давай обработку результата, в том числе и пустого.

Пока что ты кода не привёл.
Немного формально:
покажи пожалуйста:
-- запрос на вставку
-- запрос на обновление
всё с подготовкой данных и обработкой результата

Хотелось бы сравнить вот с этим Пыхотред (комментарий)

AndreyKl ★★★★★ ()
Ответ на: комментарий от aiive

Если что, я не топлю за то что твиг весь такой идеал и нативный пхп говно. И в твиге хватает вещей, которые мне не нравятся. Но при этом в нем есть и вещи, которые в нативном пхп делаются довольно неудобно

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

Эта тема с твигом и т.п. пришла из-за подражания джангам и рельсам, но там-то просто нет альтернативы, а зачем это тащить в пых который и так сам-себе шаблонизатор?

no-such-file ★★★★★ ()
Ответ на: комментарий от aiive

В алхимии это есть.

реализуют только вещи, которые общие для разных баз

Я выше кидал пример для оракла, аналогичные штуки для других баз.

Даже в django orm есть вещи типа https://docs.djangoproject.com/en/2.0/ref/contrib/postgres/

pawnhearts ★★★★★ ()
Ответ на: комментарий от no-such-file

Да ты просто лалка. Любой школоло прочитавший книжку «php за 24 часа» допетрит, что нужно сделать чтобы реализовать то, что ты хочешь за 5 минут.

Молодец, и все это станет выглядеть еще более хреново, чем было до этого. Зато не используем шаблонизатор, да.

Причем это всё будет уже в разы функциональнее твига, потому что $contents можно крутить как угодно средствами php, а не урезаным микроязыком шаблонизатора.

Про возможность расширения твига ты явно не слышал.

Я вообще нафиг с тобой спорить, твоя неадекватность понятна. Можешь не отвечать.

aiive ()
Ответ на: комментарий от cab

В больших проектах обычно не схема или запросы сложные(точнее большинство запросов простые), а очень много таблиц. Намного проще с этим работать единообразно через orm.

А сложные запросы можно вынести в хранимки, вьюхи и т.п. и работать уже с ними.

pawnhearts ★★★★★ ()
Ответ на: комментарий от no-such-file

Я не сторонник твиг, то чем я пользуюсь - это как раз чистый php + обёртка над ob_*. Но не могу не отметить что приведённого aiive кода данное решение с ob_start выглядит откровенно плохо, если честно.

По поводу эскейпинга - автоматическое решение конечно выглядит лучше. Зачем писать <?= e($var) ?> если его можно не писать?
Забывать вроде и не забудешь, но вот новички постоянно делают двойной эскейпинг.

AndreyKl ★★★★★ ()
Ответ на: комментарий от aiive

Про возможность расширения твига ты явно не слышал.

Сначала создаём себе проблемы (куцый язык), а потом их мужественно превозмогаем (пишем расширения). При том что уже есть готовый и быстрый встроенный шаблонизатор. Дебилы?

Молодец, и все это станет выглядеть еще более хреново, чем было до этого

И чем конкретно это хреново? Ну кроме того что тебя макнули в собственное невежество?

no-such-file ★★★★★ ()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

Эта тема с твигом и т.п. пришла из-за подражания джангам и рельсам

Ну в рельсах изначально был erb, тот же самый пых. И сейчас haml/slim это тот же руби с хитрым синтаксом. Это в питошке вечно страдают, превозмогая отступы.

anonymous ()
Ответ на: комментарий от AndreyKl

данное решение с ob_start выглядит откровенно плохо, если честно

Данное решение является proof of concept а не продакшен кодом, если кто-то не догадался. Поэтому обсуждать его красивость не совсем уместно.

Зачем писать <?= e($var) ?> если его можно не писать?

Ну вообще, так писать придётся всё равно ибо кроме такой банальности как эскейпинг, как правило нужна многоязычность.

no-such-file ★★★★★ ()
Ответ на: комментарий от no-such-file

Данное решение является proof of concept а не продакшен кодом, если кто-то не догадался. Поэтому обсуждать его красивость не совсем уместно.

Но ведь немного странно сравнивать proof of concept с продакшн кодом: пока ты накодишь продакшн, оглянуться не успеешь, твиг и получится, или что похуже.

Скажу прямо, мне не нравится идея встраивать движок шаблонов в php в том смысле что подменять условные операторы, вызовы функций (из подобного я знаком лишь со смарти). Но сам по себе php всё таки недостаточен для шаблонов, нужна какая-то организация этого всего: встройка шаблонов, подшаблонов, способы передачи параметров, пути поиска в конце концов.

Их решение (твиг) выглядит целостным и готовым, а твоё «а это можно сделать так, если потратить кучу времени». Ну можно, да. Но будет ли лучше? Смысл есть кмк только в сравнении готовых решений. В этом смысле чистый php на мой взгляд проигрывает твигу как шаблонизатор в том аспекте который приведён в треде уж точно.

Да, по эскейпингу, я пожалуй не буду спорить, не могу понять как лучше, сам так не делаю (автоэскейпинг).

AndreyKl ★★★★★ ()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от AndreyKl

Но сам по себе php всё таки недостаточен для шаблонов, нужна какая-то организация

Для этого и придумали фреймворки. Весь необходимый код просто подключается фреймворком, потом вызываешь методы, всё. Надо свои хелперы - пишешь в определенном классе и тут же их получаешь как есть. Думаешь почему был такой хайп по рельсам? Просто там впервые все вот это сделали, и сделали удобно для человеков. А так рельсовый шаблон - один в один PHP.

anonymous ()
Ответ на: комментарий от anonymous

Для этого и придумали фреймворки.

Вопросов нет, для этого. Но у no-such-file приведён код, а не показано как это сделать на том или ином фреймворке. Я б может быть не полез спорить если бы речь шла о лучшем решении, но речь идёт о наброске vs решение.

AndreyKl ★★★★★ ()
Ответ на: комментарий от AndreyKl

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

anonymous ()
Ответ на: комментарий от AndreyKl

пока ты накодишь продакшн, оглянуться не успеешь, твиг и получится, или что похуже

А зачем мне его кодить? Что мало движков использующих пых как шаблонизатор? Тот же Yii, CakePHP, да даже wordpress с которого началась тема и который я предлагал посмотреть aiive, но он отказался.

нужна какая-то организация этого всего

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

а это можно сделать так, если потратить кучу времени

Это ты уже сам себе нафантазировал. Я такого нигде не утверждал.

no-such-file ★★★★★ ()
Ответ на: комментарий от AndreyKl

Но у no-such-file приведён код, а не показано как это сделать на том или ином фреймворке

Желающие могут и сами посмотреть, как это можно сделать на том, или ином фреймворке где вьюхи пишутся на пыхе.

Только не надо разводить демагогию про то, что это «не чистый» пых.

no-such-file ★★★★★ ()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

Выглядит примерно так:

aiive

можно делать вот так и вот так, вот [реальный код]...

no-such-file

да это говно, можно гораааздо круче, поглядите [посылает не по ссылке на код], а ещё я могу вот так [приводит микрокусок псевдо-кода]

Конструктивненко, уважаю. Главное, не перетрудился.

AndreyKl ★★★★★ ()
Ответ на: комментарий от AndreyKl

Конструктивненко, уважаю. Главное, не перетрудился

А теперь приведи ссылки на сообщения где были слова

да это говно

можно гораааздо круче

а ещё я могу вот так

?

То что это ты так воспринял, говорит только о том, что у тебя пригорает. Но тут я ничем не могу помочь.

И да, приведённый мной код делает ровно то, что просил aiive.

no-such-file ★★★★★ ()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

И да, приведённый мной код делает ровно то, что просил aiive.

Да, я не разобрался, если не придираться к синтаксису, разницы нет вообще. Я не прав в данном вопросе.

AndreyKl ★★★★★ ()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от lovesan

Во-первых, не в любом. Не все проекты так разрастаются. Во-вторых всякие instagram и disqus написаны на джанге и им норм. На рельсах тоже много проектов и тоже с orm. В-третьих в первую очередь заботятся о эффективном кэшировании. В-четвертых накладные расходы orm не такие большие, тормозить начинают сами запросы. В пятых всякие шаблонизаторы это тоже расходы, можно конечно вообще всё выкинуть.

Ну и вообще просторов для оптимизации масса. Можно выносить что-то отдельные сервисы. Или, например, у нас было много запросов на чтение, мы сделали модуль для nginx, который дергал базу напрямую и выплевывал json. Из остального проекта орм убирать не пришлось.

pawnhearts ★★★★★ ()
Ответ на: комментарий от pawnhearts

Тормозить в вебе всегда начинает база. И ровно потому что средний пыхоплеядник вообще не понимает как с ней работать и куда жать. Потому и втыкает орм.

lovesan ★★ ()
Ответ на: комментарий от pawnhearts

На рельсах тоже много проектов и тоже с orm.

Рельсы славятся как раз проблемой n+1 select. Не сами рельсы конечно, а пыхеры на рельсах. Потому что никто об этом не думает, более того жадная загрузка в их букварях не приветствуется, типа зачем усложнять, и так сойдет. Потом когда проект вылазит из подгузников люди заламывают руки: руби тормозит! Срочно переписать на $новомоднаяхипстня. Тут приходит опытный дядька, подкручивает им настройки (уменьшая в 1000 раз количество запросов), и внезапно оно начинает шевелиться. А если на дядьку зажали денег, так оно и тормозит вечно пока хипсторы таки не перепишут на новый язычок, где у них конечно же снова все тормозит и жрет память.

anonymous ()
Ответ на: комментарий от AndreyKl

он банально удобнее, вообще то.

Что удобнее? В уме все время компилировать туда-сюда, чтобы понять какой SQL вылезет или как вот этот запрос впихнуть в орм? А если это не делать, будет жопа (см. выше). Для примитивнейшего круда удобнее, да. Но масштабируется плохо.

anonymous ()
Ответ на: комментарий от cab

Например у меня есть сущность class User extends Model и я могу манипулировать с ней как с объектом языка на котором ведётся разработка: передовать в качестве агрумента функциям/методам, клонировать, делать отложенные изменения, расширять функционал по работе с данной сущностью и много всего другого. Ключевое здесь это то, что мой класс User (который маппится на бд) и его экземпляры которые являются представлениями реальных строк в таблице являются частью системы (это просто объекты) и для них доступны все операции что и для любых других объектов. Опять же если это просто запрос из серии, что ты приводил в примеры, то тут ORM не нужно, потому что оно совсем о другом, а если у тебя сложная бизнес логика в проекте, то ты либо утонешь в своих SQL запросах, либо долгим путём велосипедостроения придёшь к собственной реализации ORM

Lancelot ()
Ответ на: комментарий от AndreyKl

Так выкидывать орм когда прижмет это нифиговая задачка, особенно если горепыхеры раскидали свои нескучные запросы по всем слоям вплоть до шаблонов. Тем более в модных фреймворках принято все прибивать к орму. Переписывать придется все. Или с самого начала нужно разделять: тут у нас круд, а тут выборки. Но тогда быдлокодеры взвоют, они то мечтали, что sql больше не увидят.

anonymous ()
Ответ на: комментарий от anonymous

Ты его весь не выкидывай сразу, просто начни с тех мест где тормозит, и будет проще. Для этого конечно придётся померить что тормозит,но что делать. Если проект дошёл до стадии когда тормозит (ну, и вы поставили индексы, да.. а то всякое бывает), то надо профилить. Причём желательно это делать чуть заранее, благо что то вроде нагиос позволяет видеть нагрузку в ретроспективе и даже без расчётов понимать что через месяц теми же темпами приедем. При этом обычно можно сменить сервер и это даст ещё пару месяцев. Или пофиксить самые первые боттлнеки, и это обычно тоже быстро и недорого и тоже даёт запас времени.

Ну и лучше знать раньше чем за месяц, что обычно тоже вполне возможно.

AndreyKl ★★★★★ ()
Последнее исправление: AndreyKl (всего исправлений: 2)
Ответ на: комментарий от AndreyKl

то вообще-то я тебе показываю весь процесс.


Вообще-то я из твоего кода не понял ничего. Ни как выбираются данные, ни в каком виде возвращаются, ни как происходит их обработка, ни управление транзакциями.
Приведеный мной кусок кода - это SQL без лапши в противовес сгенерированному ORM-ом. На практике выбирается примерно так:

logonQuery = UsersInfo.getQuery(Queries.LOGON_QUERY)
# logonQuery
# """SELECT * FROM auth_user u
# JOIN business_entity_users b ON u.id = b.user_id
# JOIN entity e ON b.entity_id = e.id
# WHERE e.name=? AND u.username=?"""
result = cursor.execute(logonQuery, (entityName, userName))
sendResult(recipient, Utils.Handlers.toJSON(result))

Вообще инструментарий для автоматизации всяких модификаций и т.д. давно написан, просто ориентирован на SQL.

cab ★★★★ ()
Ответ на: комментарий от pawnhearts

В больших проектах обычно не схема или запросы сложные(точнее большинство запросов простые), а очень много таблиц

Большие проекты - это сборная солянка технологий. И получать выборки для них лучше всего централизовано в стандартном формате. А такой формат - это SQL.

cab ★★★★ ()
Ответ на: комментарий от Lancelot

а если у тебя сложная бизнес логика в проекте, то ты либо утонешь в своих SQL запросах

Приведенный выше

Entity.objects.get(name='ЯНДЕКС').users.filter(username='ph')

это тупо более компактный SQL. Ключевое во всем то, что твой класс мапиться в БД. Все равно ты, в своей реализации, не ограничишься абстрактными классами, БД сущности все равно вылезут и придется их как-то обрабатывать.
Грубо говоря я предпочитаю использовать SQL, как достаточно удобный стандартный инструмент и не доверяю ORM-му генерировать часть запросов.

либо долгим путём велосипедостроения придёшь к собственной реализации ORM

Собственные инструменты под задачу в порядке вещей. Понятно, что они частично перекрывают функционал ORM-а, но заточены под SQL.

cab ★★★★ ()
Ответ на: комментарий от AndreyKl

Давай эскейпинг, давай обработку результат

Ты хочешь либу для запросов? Поищи, наверняка такое есть уже. У меня лично самописная. Это очень тонкий слой поверх стандартной DB либы. Привязка параметров для простых случаев через искоробочные bind variables, для более сложных - макросами (крошечный шаблонный движок). API генерируется по декларативному описанию, где запрос отображается в метод с соотв. аргументами. Результаты выгребаются в структуры, доступ через итератор (курсор). Кодеры довольны, они работают со своими объектами (структурами, но можно и оборачивать) через плоский API, и вообще про специфику хранилища не задумываются.

anonymous ()
Ответ на: комментарий от anonymous

У меня вот в ОРМ в модели есть EmailField, InnField. В бд это varchar, но прежде чем попасть в бд они валидируются на соответствие формату(валидность инн провеляется по формуле специальной, там есть контольные цифры). Соответственно формы или сериализаторы для json api которые генерируются из этой модели будут содержать такие валидаторы тоже.

Или вот JSONField мапится на json поле postgres. Возвращает мне объект уже десериализованый json и наоборот. И я могу через orm искать по каким-то вложенным полям в json типа MyModel.objects.filter(jsonfield__something__something='foo')

pawnhearts ★★★★★ ()
Ответ на: комментарий от anonymous

доступ через итератор (курсор)

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

cab ★★★★ ()
Ответ на: комментарий от cab

Да причём здесь констуирование обычного запроса? Я о другом, вакумный пример:

// class User extends Model
// class Post extends Model
// class Comment extends Model

$user = User::getUser($session);

$post = new Post();
// Сигратура: public function setAuthor(User $user)
$post->setAuthor($user);
$post->save();

$comment = new Comment();
// Сигратура: public function setAuthor(User $user)
$comment->setAuthor();
// Сигратура: public function setPost(Post $user)
$comment->setPost($post);
$comment->save();

Что мы здесь имеем:

  • Мне не важно какая бд под капотом и вообще что там, хоть число PI для представления данных, для меня это объекты реального мира и я решаю контретную задачу, а не её реализацию
  • Благодаря аннотациям типов мне язык гарантирует, что я не добавлю коментарий к несуществующему посту (для языков со сатической типизацией плюшек будет больше)
  • Код проще отлаживать и дебажить, я легко могу проследить цепочку вызовов для любого из этих объектов. Например у меня где-то в коде меняется значения поля 'status' в таблице 'posts' и если всё в SQL запросах,то я потрачу много времени на просмотр каждого из них, а для ORM я просто сделаю 'Find Usages' для метода setStatus() класса Post или повешу обсервер на этот метод

А вот что в ORM действительно плохо, так это отсутствие гарантии на корректность реализации, я не могу наверника знать, что построенный ORM SQL запрос будет корректен (или хотябы оптимален) (но тут ситуация как с языками программирования, гараний, что 2 + 2 = 4 в общем-то и нет, мир не идеален, а энтропия растет)

Lancelot ()
Ответ на: комментарий от anonymous

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

как вот этот запрос впихнуть в орм

В основном претензии бывают к тому, что на orm не ложатся сложные запросы, типа подсчёта статистики, сводных отчётов и т.п., но это только потому, что люди не владеют инструментом в полной мере. Причем нередко бывает, что вообще никаких особых телодвижений делать не надо, а просто создать в БД view и к нему обычную модель штатными средствами ORM.

no-such-file ★★★★★ ()
Ответ на: комментарий от pawnhearts

Валидация - забота бизнес-логики. На уровне хранилища есть констрейнты, по которым будет отлуп при несоответствии. Ты тесно связываешь сущности хранилища с сущностями бизнес-логики, это на мой взгляд антипаттерн. Впрочем, ActiveRecord не единственный вариант орма. Но мне не нравится сама идея генерации запросов. Это не то место, которое можно отдать на откуп автоматике.

anonymous ()
Ответ на: комментарий от Lancelot

Мне не важно какая бд под капотом и вообще что там

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

no-such-file ★★★★★ ()
Ответ на: комментарий от anonymous

Для крудошлепства, которого большая часть запросов всегда orm идеальна. Какую-то аналитику ты можешь явно на sql написать.

Многие считают что анти-паттерн засовывать бизнес логику в базу в т.ч. валидацию данных. Модель это не просто хранилище, там часть бизнес логики.

pawnhearts ★★★★★ ()
Ответ на: комментарий от no-such-file

Я хотел сказать, что работаю с пользователя, постами и их сообщениями в данном случае, а не с конкретными строками в таблице, это позволяет сосредоточиться на решении конкретной задачи, а не над её реализацией

Lancelot ()
Ответ на: комментарий от Lancelot

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

С этим согласен. ORM добавляет очень полезный слой абстракции.

no-such-file ★★★★★ ()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от Lancelot

Примерно такой же код будет и без ОРМ. Разве что выборки будут стандартным SQL вместо API запросов ORM. Поверь, абсолютно нет проблем ни с верификацией, ни с целостностью (за этим следит сама БД), ни с цепочкой запросов.

А вот что в ORM действительно плохо, так это отсутствие гарантии на корректность реализации

И это тоже. У меня к ним еще пара претензий - ORM недостаточно абстрактен. Все равно БД вылазит и дает о себе знать. А, значит, лучше с этим работать посредством терминологии и инструментария ее стандартной поставки.
Второе, что у меня нет части логики в ORM, части в хранимках, все централизовано и задокументировано в одном месте.
Третье, SQL не ограничивает меня конкретным языком, под который реализован ОRМ. Т.е. что-то отдается в виде json, что-то вносится по cron-у простым скриптом на python, а что-то реализовано на java или delphi.

cab ★★★★ ()
Ответ на: комментарий от pawnhearts

Модель это не просто хранилище, там часть бизнес логики.

Да, но она прибита гвоздями к таблице БД. Получается очень хрупкая сильно связанная архитектура. Да и сам маппинг реляционной системы в иерархическую сомнителен. Множество классов будут служить только для удовлетворения структуры хранилища, а вовсе не для бизнес-логики. Получается канонический пример сильно текущей абстракции, хоть в учебники пиши.

anonymous ()