Zend Framework Day 2012. Слайды, фото и немного мыслей.

Совершенно неожиданно, уже в третий год подряд я отправился на конференцию Zend Framework Day 2012. В этом году она полностью посвящена выходу Zend Framework 2. Последние несколько лет народ живо интересовался, когда же выйдет новый фреймворк, и вот случилось чудо. Такое событие как конфа по новому ZF не могло не привлечь меня и я направился в Киев.

 

Интро.

Утро. Киев. Хрещатик. 8:30. Народу мало, я сижу в кафешке и смотрю в окно. Чувствую себя как коллега Янг Ли (мы работали вместе в Екатеринбурге). Он тогда говорил, глядя на улицу: “вот, если бы мы были в Китае, то сейчас тут было бы уже человек сто, на этом месте”. Так и я  сейчас думаю про Москву. Машин и людей на Тверской было бы больше раза в три.

  

Хрещатик в тумане очень красивый, как будто это не Киев, а Вена или Стокгольм. Какая-то зимняя сказка. Чувствую спокойствие и умиротворение, давно такого не было. А фоном играет Limp Bizkit – Behind Blue Eyes.

У меня появилось свободнео время. Аж 2 часа. Ну правда из них осталось уже 20 минут. И… я не знаю, что делать. Я… просто сижу, и пью горячий чай в этом холодном городе. Не надо никуда бежать, торопиться. 2 дня я сам с собой. День конференции, сегодня будет много всего интересного, и день… просто свободный день. Я наедине с городом. Конечно, планы есть, но разве это планы? Ведь меня никто не будет ждать к назначенному времени, мне некуда не надо… Я понял. Я так медитирую… когда мегабайты информации не проносятся через мой разум, когда нет этих skype-звонков, рабочих писем и тикетов. Я просто сижу и вижу, как просыпается древний город…

Отель Казацкий нашел сразу, хоть вначале и удивился такому количеству тумана. На входе в зал уже хозяйничали Степан, Евгений и Александр.

     

После того, как все собрались, Саша объявил конференцию открытой, представил одного из спонсоров – компанию Gorilla Group, которая занимается поддержкой и разработкой интернет-магазинов на Magento. Она даже старше самой Magento. Ну что-ж, Magento – это пожалуй 1C мира eshop-движков, и не удивительно, что вокруг неё уже давно выстроился рынок разработки. Зато клиентам есть к кому обратиться. Компания находится в Минске, и нам предложили перехать туда поработать (ну для тех, кому это интересно). А был ли народ из Белоруссии? Кстати, один мой товарищ меня усердно туда зазывает (привет Саш!). Переезжать работать я туда пока не собираюсь, но вот если представится случай – обязательно съезжу в Минск.

Событийная модель Zend Framework 2, EventManager // Александр Вронский, Smile Ukraine

После спонсоров Александр представил первого докладчика. Сразу скажу, на конфу я приехал в основном из-за двух докладов, этого и про модули Zend Framework 2. Этот доклад меня разочаровал. Думаю тут нет вины докладчика, просто материал у него был сыроватый, и это было видно, плюс ко всему он изрядно нервничал. Очень знакомое чувство, вроде уже столько опыта публичных выступлений, а всё равно когда выхожу на сцену – почему-то переживаю каждый раз, но потом каждый раз успокаиваюсь. Ничего, тут главное – опыт.

Александр сразу предупредил, что конфа у нас первая по ZF2 собственно после его релиза, поэтому никто ещё детально не изучил все внутренности нового фреймфорка, его темой были события. События это унифицированный способ взаимодействия компонент, по сути обратные вызовы вместо прямого перехода на участок кода. Основное преимущество такой архитектуры – декомпозиция кода. Событийная модель в Zend Framework 2 построена по паттерну “subject-observer” (кстати, кто-нибудь может мне внятно объяснить, чем он отличается от паттерна “signal-slot”?). Архитектура описывается триадой (Event – Handler – Trigger). Основное управление реализовано в классах *EventManager. Докладчик привел пример с системой плагинов при формировании значения в базе данных, но он показался мне не особенно удачным. Наименование событий в ZF’е следует структуре ПРЕФИКС.ФУНКЦИЯ. Например pre.save для определённого контекста. Важно заметить, что события могут иметь одно и то же название, но срабатывать в разных классах. MVC архитектура также построена на базе событий (в слайдах выше есть схема событий).

Меня в первую очередь интересовала производительность этой архиткетуры, поэтому я задал вопрос о порядке роста времени обработки событий при увеличении их количества на один HTTP запрос, ну что я получил ответ “ну на HelloWorld работает быстро :-)”. Соответственно исследований по этому видимо никто не проводил. Жаль. Но если событийный менеджер – действительно такой тонкий и без значительного overhead, как говорил о нём Александр, то использовать его стоит. Хотя куда мы денемся?! Ведь весь ZF2 построен на событиях. Надо как-нибудь на досуге протестить это дело.

Второй насущный вопрос, который меня интересует – это можно ли использовать фронт-контроллер отдельно от всего Application. Так, например, реализовано в одном из моих проектов (для увеличения производительности на высоких нагрузках), а коллеги частенько либо выпиливают этот компонент, либо очень хорошо его дорабатывают под свой проект. Докладчик ответил, что фронт контроллера больше нет, и использовать MVC+Routing+Dispatching+Application придётся вместе, но они прекрасные и легкие, и всё будет хорошо. Ну опять же, посмотрим на боевой задаче (не на большой конечно, а на маленькой). Буду экспериментировать на следующей неделе наверное, ещё напишу на эту тему.

MMS или как просто работать с моделями данных // Иван Кутузов, INTERKASSA

Второй доклад был посвящен т.н. системой управления моделями, или Module Managment System. Суть задачи такова: есть куча моделей с различными свойствами,  модели хранятся в NoSQL DB (MongoDB). Соотвественно схему данных достать трудно. Необходимо сделать гибкую админку по управлению моделями. В общем получился гибрид скаффолдинга и кодогенерации, построенный по паттерну “медиатор”. Получилось по меньшей мере красиво. Особенно мне понравилась идея кросс-базового компонента Select, в котором описывались условия выборки как для SQL, так и для NoSQL-хранилищ. Однако название выбрано было ну очень неудачно, т.к. не все сразу поняли, что этот Select не имеет отношения к Select-образу одноимённого SQL-оператора.

Из-зала кто-то спросил, юзал ли автор ExtJS для построения админки, докладчик сказал, что нет. Мне кажется, скрестить JS с Монгой и ExtJS – мечта каждого второго фронтэндера. Нельзя их в этом винить, но моё мнение по отношению к ExtJS уже давно определено.

Соблазнительные формы в Zend Framework 2 // Даниил Кожемяко, TulaCo

Доклад Даниила был, пожалуй, одним из самых интересных. Тут реь шла о формах в ZF 2.0. Узнал много нового и интересного. Раньше многие ругали Zend_Form за overengeneering, куча декораторов народу явно не нравилось. Я же написав как-то Zend_Form_Element_HtmlCode решил для себя эту проблему.

Новые формы довольно сильно переработаны. Теперь можно создавать коллекцию из элементов определённого типа. Например добавлять телефоны по одному input’у кнопкой “плюс”, или привязывать различные аккаунты для соц сетей в профиль юзера. Удобнейшая штука, надо сказать, т.к. задача это довольно частая, и каждый крутит свой велосипед под неё. А тут работает, и из коробки.

Дальше интереснее, Даниил рассказал про общение формы с моделью (на примере Doctrine 2 ORM Entity). Получается форму можно привязать к модели с помощью механизмов Hydrat’оров и Strateg’ей. Гидратор использует стратегию для двустороннего отображения полей объекта на форму и обратно. Интересный подход, но для случая когда одна форма = один объект. Для CRUD-админок каких-нибудь – вообще вещь. Если одна форма = много объектов, то видимо придётся выкручиваться саб-формами или fieldset’ами. А вообще мне это до боли напоминает мои методы $entity->toForm(), $entity->fromForm(), которые делают то же само, но “в лоб”. Нет, ну стандартизация всегда полезна, а то кто знает, я так делаю, кто-то по другому, а тут будет ZF-way вещь, совместимая с моим кодом и Васиным. На счёт многообъектных форм, Даниил предложил использовать многошаговые формы для этого. С производительностью сказал тоже всё ровно.

HighLoad не кусается // Антон Шевчук, NIX Solutions

Ну с Антоном мы (да и вы тоже) думаю уже знакомы. Доклад интересный. Не имеет отношения к ZF, но тем не менее интересный. Антон изложил свой практический опыт в построении одного высоконагруженного городского портала. Он выдвинул занятную идею, хранить в memcached не всю сессию, а только её хэш. Иными словами, при авторизации берем хэш от версии браузера, IP, заголовков и кидаем в memcache в качестве ключа, а значением будет user_id. При повторном заходе проверяем эти данные и получаем данные пользователя по user_id из базы.

Ещё Антон рассказал про интеграцию VanillaPHP с сайтом, нескольких подводных камнях и чате. Для чата он пробовал использовать NodeJS+socket.io (websockets), но он у него не взлетел. Из доклада порадовала фраза Антона: “Это хардкор. Но весь хардкор у меня под контролем… в одном файле на 3000 строк” 🙂 Он показал статистику со словами “и всё это работает на моём велосипеде”. Мы с Антоном побеседовали перед докладом, когда он начал мне рассказывать про свой движок. Сам признал, что велосипед, я тогда ещё спросил, “а зачем велосипед – для учёбы или для скорости?”. “Для скорости” – честно признался он мне. Ну и во время доклада уже цифрами подтвердил. Вообще много практики было,  Антон рассказал о нескольких случаях. Например, вот видите этот спад на графике – это у нас пользователи админами становились :-).

Очередь задач и многопоточность с помощью Gearman и ZF // Станислав Прокопив, INTERKASSA

Вот тематика выполнения задач через очередь мне кажется – неиссякаемая на PHP-конференциях. Да, что уж греха таить, сам писал ZF-адаптер для одной забавной очереди не так давно. Станислав освещал тему работы с Gearman-сервером на PHP. Основные идеи в том, что к таким вот фоновым задачам надо относиться очень внимательно: не ронять воркер, использовать Garbage collector для освобождения памяти, перезапускать воркеры по достижении лимита по памяти. Да и вообще юзать supervisord. Докладчик рассмотрел пример реализации воркера, мониторинг очереди. Для себя я выяснил следующее, если надо делать BG-таски, то:

  • Хранить задачи в MongoDB. Народ кстати уже хочет хранить очередь в MongoDB.
  • Средство исполнения воркеров – Gearman
  • Исполнять воркерами на php, наследуемыми от Zend_Gearman_Worker
  • В воркерах контролировать память, возможно время работы. Если достигли лимита – перезапускать.
  • Для контроля за воркерами (Gearman это не делает) используем Supervisord.
После доклада, как всегда секция вопросов и ответов:
– Хранит ли Gearman очередь?
– Да, для этого он может использовать БД.
– Gearman может сам запускать AWS-инстансы?
– Нет.
– Как можно синхронизировать потоки?
– Делайте транзакции в воркере.
– Есть ли возможность узнать статус задачи (её выполненную часть)?
– Да, воркер может делать вызовы setStatus() по задаче. Однако кластера из Gearman не собрать. А вот из RabbitMQ можно.
Кстати, Ростислав заметил, что в воркере можно забиндить на register_shutdown_function() свой обработчик fatal error’ов через глобальную переменную, который будет корректно выгружать/перезагружать воркер с учётом текущей задачи (чтобы её не потерять).

Zend Cache – Evolution // Владимир Дубина, Speroteck

Доклад от Владимира был посвещён практическому использованию разных механизмов кэширования. Сфера применения – Magento. Докладчик рассказал о средстве статистического анализа php-кода Sonar. Говорит, что он может даже показывать стоимость рефакторинга! Надо бы попробовать как-нибудь. Ещё я узнал, что phpStorm поддерживает отладку вместе с xdebug (вернее понимает его файлы дампов).  В принципе, я частенько сталкивался с подобными задачами, и по опыту соглашусь с Владимиров. Он рассказал про типы кэширования (страничное, блочное, выборок и т.д.), про то, что надо каждый раз исходить из задачи и оптимально строить кэш. Ведь иногда кэш может только замедлить работу сайта (!).

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

Модули в Zend Framework 2 // Ростислав Михайлив, oDesk

Доклад Ростислава по своему наполнению субъективно был эквивалентен трём другим докладам. Честно говоря, мне кажется, надо было ставить его в середину дня. А то вечером уже все втыкали, и было сложновато врубиться в него. Но, слушать однозначно стоило. Я в основном приехал ради этого доклада, т.к. как раз назрела необходимость на работе заниматься с модулями. Интересного я узнал много.

Во-первых DI Container компилируется! Это меняет всё, ведь на прошлой конфе один из докладчиков профилировал ZF2 (тогда ещё бету) и получилось, что он аццки тормозит. Тормозил по его заявлениям именно DI-контейнер. А теперь оказывается, что на продакшене можно его спокойно компилить и всё будет летать. УРА! Живем, траварищи!

Во-вторых констант environment больше нет. Используется config merging механизм для файлов global.php и local.php В третьих не используёте цифровые ключи для конфигов, сливаться они будут криво. Используйте только строковые ключи. В четвертых, если есть в контроллере команда return $response, то он уже готов и потом его поменять будет нельзя.

Вообще в новом зенде добавили таки паттерн ViewModel. Скжу честно мы у себя его давно уже используем так или иначе. Тем более это удобно, когда сайт имеет несколько видов (для браузеров, для мобильных клиентов, pda, API-версию).

Поговорили с Ростиславом о переходе Zend Framework 1 -> Zend Farmework 2. Миграцию надо делать примерно так: сначала внедряем автозагрузку через composer, потом Event Manager, затем DI, ну и после Application с маршрутами. Composer кстати умеет делать симлинки.

Розыгрыш лицензий на phpStorm

В конце конференции, как и обещали разыгрывали лицензии на phpStorm. Великий рандомизатор определил имена победителей.

  

Мне же досталась симпотная майка с логотипом ZF! Кстати, реквестирую розыгрыш кружек с ZF-символикой на следующую конфу!

 AfterParty

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

      

      

Очень хорошо посидели, потравили байки из нашей IT-шной жизни. Может нам и в Москве как-нибудь организовать такие посиделки, а? В общем было классно.

Outro

Ребята, Саша, Степа, Женя – спасибо вам за конференцию! Было классно. Сказать, что мне понравилось – ничего не сказать. Хоть и не без косяков (поздно объявили программу, быстро кончились бутерброды) – но по-моему провели всё отлично. Большой шаг – что сделали видеотрансляцию! Это по-моему обязательное условие для конфы. Повесили хэштег сразу на стену, тоже здорово. Ну вообще ставлю твердую пятерку ZFDay 2012. Рад был увидеться с теми кого уже давно знал, и познакомиться с новыми людьми! Молодцы!

  

  

Цитаты конференции

  • Helpers sometimes doesn’t help
  • Строчка КЭШа = -10 к рефакторингу
  • Менеджер событий… управляет событиями!
  • Были ли тесты производительности? – Ну да, мой HelloWorld работает очень быстро.
  • Первый был хорош, второй – ещё лучше. // Про Zend Framework 2
  • Гидратор порождает гидратор… получается гидра, а не гидратор.
  • О, на хабре пост опубликовал, трафик пришел, сервак упал – у меня радость.
  • Весь хардкод у меня под контролем… в одном файле на 3000 строк.
  • У вас есть 15 дней, чтобы оптимизировать код. // О trial периоде в NewRelic
  • Чтобы написать Highload сайт – не обязательно знать advanced фичи, ваш HelloWorld выдержит HighLoad. // ага, HighloadWorld
  • У нас есть выбор фреймворков (в отличии например от питонистов, где только GAE или Django). Подбирайте инструкмент под задачи, у вас есть из чего выбрать.
  • Сделать приложения маленькими у меня не получается, жалко свой код удалять, он же мой.
  • Те, кто с Magento сталкивались – не удивляются, и не смеются. // Про время генерации страницы в 15-45 секунд.
  • Плохой код? Но у них же три сертифицированных индусских разработчика!

Ссылки

Этот раздел будет пополняться, отписывайтесь в комментах о других фотообзорах и репортажах про ZFDay 2012,

Фотографии Евгений Македона.
Официальные слайды от организаторов (кликаете на доклад, там лежат слайды к нему).
Highload не кусается. Слайды Антона Шевчука.

18 Comments

  1. Отличный отзыв! Жаль мне не удалось съездить 🙁
    Очень “вкусно” все расписал 🙂 и коменты дельные!

    Кста, у тебя кажется описка в имени переменной “return $respinse”

    1. Спасибо!) Ну весной по Symfony будет, если тебе это интересно. Ну а следующий ZFDay через год только. Думаю уже успеем с ним поработать как следует. Я кстати поправил опечатку, сенкс!)

  2. Как раз сейчас веду проект на ZF2, исключительно из-за того, что моей компании требуется Zend Partnership.
    Что я могу сказать, с моей точки зрения – это фейл.

    Использование events, конечно. выглядит круто, и наверное для маркетинга это хорошо, но с точки зрения разработчика, натыкаться посреди императивного кода на событийное программирование выглядит несколько уродским. Поймите меня правильно, я сам люблю event driven development и javascript, но зачем так жёстко смешивать подходы?

    Насчёт форм. Я и раньше не использовал декораторы, достаточно было только валидации данных в форме, так что это проблемой не было. Но сейчас… Формы можно конфигурировать в файлах конфигурации, но чтобы понять как – нужно просмотреть всю реализацию \Zend\Form\Factory, и я бы не назвал это приятным занятием. Предложенный официальным guide вариант injection фильтров и валидацией также не выдерживает критики. Это работает для связи форма-модель 1-к-1, но что делать с формой аутентификации, например? Мне что – заводить для неё отдельную модель только ради того, чтобы передать фильтр в форму?! Внезапно, фильтр можно передать в форму через спецификацию, но где это в документации?

    Zend Framework предлагает два подхода к управлению зависимостями: DI контейнер и Service Locator. В какой-то бете у них был пример сайта с использованием DI, сейчас же они полностью переключились на Service Locator. Но что, если вы захотите использовать DI? В документации – только куски кода, реальный пример конфигурирования – в истории github, удачи в поиске! И внезапно, вы не можете инжектить сконфигурированные инстансы из service locator в DI! Отдельная песня – packages, в одних есть factory для service locator, в других – нет. Например, из коробки вы authentication service не сконфигурируете, придётся писать свою factory, а вот translator – пожалуйста.

    Наследования конфигов из ZF1 уже нет, вместо этого используется концепция локальных файлов конфигурации. Отлично, но что делать, например, с юнит-тестами? У нас, аутентификация проходит через LDAP, и для тестов вместо LDAP адаптера используется mock объект, который загружается вместо адаптера. Вообще эта проблема решается, но в документации такой тривиальный случай не рассмотрен вообще никак.

    И так во всём, одним глазом в документации, вторым в исходниках ZF2.

    1. А мне понравилась событийная модель и на мой взгляд писать стало проще. Но такой подход требует большей дисциплины и хорошего документирования проекта (я говорю о спецификациях, а не о коментах в коде).

      По остальным вопросам – это издержки начального этапа, документации мало, компоненты еще обкатываются “на кошечках”. Со временем все устаканится. В 2.1, например, конфигурировать формы станет проще – сегодня опубликую обзор, можно будет почитать.

      1. Простой пример – приведите конфигурацию master / slave адаптеров из коробки.

          1. Он-то умеет это делать, но для гибкой настройки нужны хинты драйверу. Как их передать в решении из коробки. А если я не хочу использовать mysqlnd, а хочу классические read/write адаптеры?

  3. > … Иными словами, при авторизации берем хэш от версии браузера, IP, заголовков и кидаем в memcache в качестве ключа …
    Жесть, UUID использовать не судьба?

    > а значением будет user_id. При повторном заходе проверяем эти данные и получаем данные пользователя по user_id из базы
    А это вообще не нужно делать. Предыдущий хеш можно использовать как authentication token с заданным TTL.

  4. > Ещё Антон рассказал про интеграцию VanillaPHP с сайтом,
    > нескольких подводных камнях и чате. Для чата он пробовал
    > использовать NodeJS+socket.io (websockets), но он у него не
    > взлетел. Из доклада порадовала фраза Антона: «Это хардкор.
    > Но весь хардкор у меня под контролем… в одном файле на 3000 строк»

    Ну что можно сказать, три года назад связка node.js + websockets + rabbitmq у меня взлетала как реактивный самолёт 😀 Вот только текла память в самом node.js, так что пришлось перейти на jetty + jms. Сейчас вроде в node.js такой проблемы нет, так что это фейл Антона. В конце концов, если linked взлетел, а чат Антона – нет, чьи это проблемы 😀

    1. Ну с нодой сейчас очень и очень неоднозначно. Потенциально – да, реальная неблокирующая событийная архитектура. НО:
      1. Надо сломать себе мозг, чтобы писать асинхронный код. Примерно так же, как пересесть с SQL на NoSQL.
      2. На многих задачах накладные расходы на смену контекста могут быть больше чем профит.
      P.S. Асинхронный чат – да 🙂

    2. Насколько я помню доклад Антона, он уточнил, что с node.js и socket.io он тогда только-только начал работать, вот потому, возможно, оно и не взлетело. Не стоит быть столь категоричным))

  5. Отличный пост, прочитал на одном дыхании! Возникло много вопросов по ZF2, жду тебя в подкасте чтобы задать их )))

  6. Освоили программные возможности Zend_Translate и научились их использовать. Рассмотрели узкие места и нюансы программирования мультиязычного веб-сайта с помощью Zend Translate

  7. 21 апреля в Москве пройдет очередная ежегодная конференция для веб-разработчиков ZFConf 2012, посвященная популярной платформе Zend Framework.

Leave a Reply to Andrew Cancel reply