Удивительный фреймворк phalcon
Недавно в нашей компании было решено попробовать фреймворк phalcon c целью в перспективе кое-что отрефакторить и в новом коде использовать именно его. Причины банальны — скорость работы, симпатичный orm.Но вот в процессе тестирования фреймворка у меня в голове все чаще и чаще стал всплывать термин «Принцип наименьшего удивления». И именно потому, что я все больше и больше удивлялся.
ORM и пустые строкиВозьмем стандартную ситуацию. Табличка Users (id int, name varchar, comment varchar not null default ''). Создадим модель User для работы с этой табличкой и попробуем создать нового пользователя: $user = new User (); $user→id = 1; $user→name = 'Robot'; $user→save (); И… пользователь не создается. Если посмотреть ошибки для модели увидим такую: «comment is required». WTF скажете вы и будете правы:) Баг? скажете вы и будете не правы.Смотрим Issue 440 от 22 февраля прошлого года и видим, что это фича.
Причины этой фичи — модели часто создаются и сохраняются после отправки пользователем данных из формы, многие функции, которые программист _может_ использовать для валидации (strip_tags, filter_var) при подаче им NULL на выходе выдают пустую строку. Поэтому программист гипотетически может получить случай, когда поле comment не будет отправлено через форму ($_POST['comment']==null), но программист использовал $user→comment = strip_tags ($_POST['comment']); и получил вместо null значение '' в поле comment.
Удивительно? По мне так очень.
Решения, кстати, приводятся. Но из-за этой странности приходится переопределять стандартную валидацию.
Ну и еще один пример из той же области:
$user = User: findFirst («name='robot'»); $user→name='robot2'; $user→save ();//!!! WTF? Папки для views Шаблоны в проекте могут лежать в нескольких местах, например отдельно шаблоны для каждого модуля, отдельно базовый шаблон проекта.Что делать, если хотим в шаблоне модуля сделать {% extends base.twig %}? Правильно, добавить в настройках view дополнительную папку для поиска базового шаблона. Но View: setViewsDir принимает в качестве параметра только одну директорию!
New feature request на это был отправлен 15 декабря прошлого года
В качестве частичного решения можно указать в качестве пути к шаблонам папку с модулями и потом указывать в контроллерах полный путь к шаблону от папки с модулями ($this→view→pick («clients/views/index»);). Или отключить автоматический вызов рендеринга при настройке приложения ($application→useImplicitView (false);), в качестве View использовать Phalcon\Mvc\View\Simple и рендерить шаблоны вручную print $this→view→render ('clients/views/client_view', []);
Вот, кстати, еще одно удивление — стандартный View не умеет рендерить шаблоны по пути, только по имени контроллера/действия ($this→view→render ('controller', 'view', []);), поэтому в данном случае нужно использовать Simple.
Странный синтаксис insert/update DBAL Я настолько привык к синтаксису insert/update Doctrine DBAL, что и подумать не мог, что можно сделать как-то по другому. Оказывается можно.Синтаксис phalcon DBAL и Doctrine DBAL:
$success = $connection→insert ( «robots», array («Astro Boy», 1952), array («name», «year») ); и $success = $connection→insert ( «robots», array ( 'name' => «Astro Boy», «year» => 1952 ) ); $success = $connection→update ( «robots», array («name»), array («New Astro Boy»), «id = 101» ); и $success = $connection→update ( «robots», array («name» => «New Astro Boy»), array («id» => »101») ); По мне, так однозначно синтаксис Doctrine DBAL удобнее за счет унификации.
Я отправил pull request с концептом в phalcon incubator. Может быть добавят когда-нибудь:)
В целом, несмотря на некоторые неудобства, от идеи использовать phalcon не отказываемся, продолжаем тестировать.