Pull to refresh

Удивительный фреймворк phalcon

Reading time 3 min
Views 15K
Недавно в нашей компании было решено попробовать фреймворк 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->comment= '';
$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 не отказываемся, продолжаем тестировать.
Tags:
Hubs:
+6
Comments 10
Comments Comments 10

Articles