It-компот 32

Начало

netandreus — Конфа была вообще очень интересной, то есть, сначала меня поразило то, что ребята почему-то выложили поздно программу, вот, то есть в принципе я не был в курсе, что она будет по ZF2, вот я просто знал, что она будет, некоторые в Twitter’е были анонсы, все дела, но я не думал, что она полностью по ZF2 будет. Естественно, мне это интересно, так как каждый день работаешь с ZF, так или иначе и всякие вот эти модные тенденции, их надо знать, что делается и что как пилится.

hackPNZ — Ну конечно, чтобы не отставать, чтобы быть в теме, чтобы использовать самые последние, хорошие и полезные инструменты, а не сидеть на привычном framework, который устарел уже на пять лет.

netandreus – По поводу конфы. Да, нельзя сказать, как-то, что ZF1 слишком отстал да там, что он устарел, нет, почему, вполне хорошая штука, вот. Дело в другом.  То есть все косяки, все проблемы известны, о них все знают, куча есть всяких обходных путей, если где-то что-то, все знают, как подпилить, то есть штука всем известная. Вот, это хорошо. Да, потому что не надо тратить время, с другой стороны ZF2 — это вещь в себе в некотором роде, потому что, во-первых, ребята взяли там поменяли архитектуру. Ну, то есть, если коротко, то все сделали на event’ах вообще. То есть если раньше у нас в первом ZF’е все было на MVC, то есть привычные контролеры наши, там routing, виды, layout’ы там все понятно; то тут вдруг вместо там процесса routing’а он как бы остался, но с другой стороны, он весь из себя на event’ах. Вот, кстати, как и в Symfony 2. И это надо пробовать, да, к этому надо привыкать. И… самое главное, вообще зачем я туда поехал, я же не просто так туда поехал, а с весьма корыстной целью. Узнать, что же делать с производительностью, как же с ней обстоят дела, потому что ровно год назад тоже на ZF Day 2011 не помню имени докладчика… но он как раз вот исследовал… это была третья бета ZF’а, он исследовал производительность, и он, можно сказать, всех ошарашил. Потому что…

hackPNZ – Она была, мягко говоря, не очень?

netandreus – Она была совсем не очень, да и как бы доклад кончился тем, что он показал графики сравнения там первого и второго ZF’а Hello World там какой-то, и практически вот минута молчания была, когда все втыкали в тесты и просто офигевали. Ну, он как-то сказал «Ребята, ну это еще Бета, да, там еще продукт недоделанный, сыроватый, ну я как бы сейчас в production его не использовал». Ну, Бету и так никто не собирался использовать, я так думаю. Но тем не менее…

hackPNZ – Кстати, Андрей, смотри, вот на предыдущих конфах много было topic’ов о таких типа базовые features ZF 2 рассказывали, знакомили с особенностями его устройства, и так далее, какие-то такие штуки рассказывали, это было понятно, потому что продукт, по сути, еще не вышел тогда. Сейчас же интересно, конечно, практический опыт. То есть я так понял, что там доклады все именно в сторону практики использования, то есть не было там таких докладов типа…, я не знаю «Как устроен тот же самый routing» или так вот на event’ах в ZF2, то есть совсем уж таких простых базовых там совсем, наверное, не было?

netandreus – Ну, понимаешь, были! Были, то есть. Вот первый доклад как раз, который был на конференции, про event mananger. Вот вообще по идее он должен был всем, так сказать, раскрыть глаза да на вот эту вот новую парадигму и архитектуру. Ну, новые вы знаете события. И вот как раз был такой базовый, постановочный. То есть все очень хотели каких-то конкретных примеров, опять тех же самых тестов, елки-палки, да, вот этих всех событий, но их не было. Был один такой постановочный, вот я еще не договорил про тот доклад с прошлого ZF’а, позапрошлого.., основная тормозная часть там была Dependence Injection, докладчик говорил, что это самое узкое место, пока не знаю, что с ним делать. А на этой конфе, что самое интересное, мы узнали, что вот этот вот DI он компилируется, и в production’е он вполне себе нормально работает. Вот это главная мысль вообще всей конфы, и я рад, что я ее узнал, я потом почитал в мануале там действительно, да все это компилируется, тестов там не было, но, судя по всему, это некое движение в сторону Symfony, когда у тебя приложение долго грузится, и кто-то попытался тестить, сказал: «А! Symfony фигня, у вас тут тормозит», его там засмеяли все на форуме после этого, сказали Вася, ну как же ты в деве ты не тести, тести уже в production’е…

antonkopylov – Учи матчасть.

netandreus – Да, учи матчасть, вот, так сказать, засмеяли, а тут вот нет еще такого момента, ну как-то мы не привыкли. У нас обычно это все.., ну, понятно, есть какие-то там компилирование стилей, JS’ов, да, но так, чтобы брать его и серьезно переключать режимы, у нас такого нет.

hackPNZ – А как это, кстати, происходит, расскажи, как происходит эта самая компиляция, потому что я так что-то не очень представляю, честно говоря. Сходу так.

netandreus – Ну, есть как бы два таких подхода противоположных, есть метапрограммирование, что называют, супер-супер гибкость, а есть кодогенерация. Вот. И все больше и больше я сейчас вижу, что внедряются в разные проекты именно кодогенерация. Естественно, для скорости. Вот, зачем еще она еще она нужна? Потому что код там вообще не читабельный, совершенно, зато он быстрый. И компилируется именно Dependence Injection, то есть приведу пример из Java-скрипта. Когда у нас есть там куча зависимостей, а как можно описывать? Можно динамично записывать, ну и в PHP, в принципе, тоже. Можно зависимости динамически описывать, да, скажем, теми же docblock’ами, и в рефлексии читать. Но, кстати, там, по-моему, так оно и есть, то есть одно дело их читать в рефлексии, в момент работ, это одна будет скорость, и другая совершенно будет, если все это записано в виде Plain PHP массива, это будет несравнимо. И отсюда и вытекает разница в производительности.

hackPNZ – Обычно, да, если используется рефлексия, то такие вопросы сразу всплывают в плане производительности, вот сразу повод для того, чтобы тесты провести какие-нибудь, очень хорошо.

netandreus – Часто да, но с другой стороны, дев он на то и дев, что ты меняешь и тут же все и видишь. Я уже привык.

antonkopylov – Нет, это не вопрос, просто да, я тебя поддерживаю, нужно на деве быть к этому готовым, учитывать, что есть production, есть дев, соответственно, то есть…

netandreus – Наоборот, в плане дева нужно наоборот, чтобы минимум всего кешировалось, минимум всего компилировалось, потому что очень сложно ловит bug’и, которые связаны, скажем, с кешированием на деве.

hackPNZ – Я тут внезапно подумал, в тот раз мы с Антоном обсуждали тему, как же правильно нам настраивать development-окружение в таких сложных системах, там, где у тебя слоев много, всяких компонентов. Мы как-нибудь с тобой еще на этот счет поговорим, потому что возникли определенные мысли, конечно, что можно делать так, делать сяк, можно полностью воспроизводить, можно нет, но тем не мене такого какого-то, скажем так, решения или серебряной пули, ясное дело, здесь нет, поэтому всякий опыт, он будет интересен, потому что у себя эту проблему мы пока что не совсем эффективно решаем.

zhorzh – Ребята, по поводу компилирования, вот, насколько я слышал, также была возможность компилирования вообще всех исходников в один файл, чтобы можно было грузить его…

netandreus – Да, да.

zhorzh – Это тоже включает в себя компилирование или как?

netandreus – Это немного, другой вопрос, Георгий. Значит, по поводу компилирования в один файл, значит, у нас есть такая замечательная штука, PHP 5.4 с чем-то там, да, она называется Phar-архив, вот. И связано это с тем, что да мы можем взять весь Zend Framework ,засунуть его в один файл, Phar-архив, взять весь наш application, засунуть его во второй Phar-архив и взять индекс PHP, где все это будет подключаться, и у нас , как красиво. У нас будет три дисковых вызова, все замечательно. Я, естественно, обрадовался, тут же начал все это дело применять и наткнулся на неприятный bug. На тот момент, когда я это пробовал, это было, по-моему, где-то больше, чем полгода назад, файл один загружался, но там была проблема с тем, APC ну и байт-код, конечно, он не кэшировал этот Phar-архив. Из-за этого там по производительности выигрышей не было. Вот, к сожалению. Сейчас, на данный момент, насколько я знаю, уже исправили этот bug в APC и действительно, можно взять весь ZF, засунуть его в Phar и подключит его как один файл. То есть, сейчас вам Composer вам поставляется в виде Phar-архива, вот, и все это замечательно работает, то есть, то почему многие не любят PHP – вот, у вас там сто тысяч пятьсот require’ов, куча дисковый операций, это все уже мы давно проехали. Это решается.

zhorzh – Это понятно про Phar. Я имел в виду немножко другое: чтобы вручную взять код весь классов и вручную их вводить… в один файл и сделать require одного такого большого класса.

netandreus – Понял, все, это было

zhorzh – Мэтью говорил, что они эту feature как бы встроят, чтобы там чисто компилировалось, весь код так вот, то есть можно Autoload так сконфигурировать, чтобы он подхватил такую конфигурацию. Об этом ничего не было сказано?

netandreus – Вот об этом не слышал, нет, вообще ничего не было, кстати, было бы здорово.

hackPNZ — Да и вот использование Yii-framework’а или Yii, если вам угоднее, так…

zhorzh – Кстати, как правильно?

netandreus — Я называю его Yii-framework, не знаю как, Yii так долго надо тянуть. Мы используем его в некоторых back end’ах, стаммах и есть такая штука как –Yii -light, по-моему, это собственно один файлик, этот как раз который подключается, и там вот куча классов запакована, но, как бы не соврать, не уверен, что там весь framework полностью, то есть, возможно, только базовые какие-то вещи, знатоки framework здесь меня смогут поправить, такая там возможность есть, она уже из коробки и хочешь use’ай так.

antonkopylov – Андрей, можно вопрос. Вот ты говоришь, сто в этой версии Zend Framework поменяли архитектуру внутри. На твой взгляд, оправдано такое было изменение подхода вообще к framework’у на событие?

netandreus – Ну, вообще говоря, что значит, оправдано, тут с каких сторон можно рассматривать…

antonkopylov – Ну, ты от этого получаешь там какие-то удобства, видимо, в этом оправданность, то есть мы переходим на систему и получаем за это там такие и такие плюсы

netandreus – Антон, смотри. У нас может быть оправдано с точки зрения нас как разработчиков, то мы скажем, что быстрее что-то делаем, то есть наша эффективность повысилась, какие-то удобства для нас появились, что-то яснее, что-то понятней. Или же это может быть оправдано с точки зрения той же производительности. Вот, что касается первого вопроса, то честно говоря, пока не попробуешь, не узнаешь, то есть, это надо брать работать. Тут видите в чем вся вещь, у нас есть парадигма в MVC, у нас есть контроллер, по сути, те же самые события, то есть там preDispatch, postDispatch, routeShutdown, они все были, да вот, в MVC, и мы, зайдя в код этих функций, могли посмотреть, что там вызывает. То есть, по сути ведь, мало у кого там был именно код, там были вызовы, то есть концептуально-то ничего не поменялось. То есть, это те же самые обработчики, которые были в postDispatch’е, и они станут там как слушатели события. И концептуально не изменилось ничего, вот если так вот разобраться, но изменилось с точки зрения именно расположения, то есть, где оно располагается. Теперь можно подключить.. да там раньше у нас там были всякие plugin’ы, еще куча всего там, всякие вот эти вещи action helper’ ы, еще там еще какие plugin’ы, helper’ы. Helper’ы остались, а подключаемые модули остались только там одни, plugin’ы и все, больше там ничего нет.

hackPNZ — Да, и мне кажется, еще такая особенность была первого ZF’а, что много путей было, как можно сделать одну и ту же задачу, то есть как-то вот, мне кажется, что ZF2, судя по вашим рассказам, пошел более по пути, когда тебе уже не говорят, как делать правильно – то есть, используй события, там listener’ы и так далее, что есть один, может два в каком-то случае способа сделать это так , чтобы это работало нормально и поддерживалось адекватно. Вот у первого ZF’а вот с этим я стакивался с такими проблемами, что не всегда понятно, как лучше сделать, и сам framework тебе не особо намекает на самом деле, то есть нужно всегда головой чесать. Вообще в принципе, это часто вызывало в дальнейшем какие-то сложности и неправильное решении, что тут скрывать, ты как-то сделал и думаешь, эх, надо было сделать так, а вот framework тебе вообще тебе никак не подсказывал, то есть нужно было самому кумекать, как компоненты связываются, во что потом может потом вылиться. То есть, мне кажется, что ZF2 в этом плане немного проработали, чтоб он стал и проще, и более понятней, как его использовать во многих типовых ситуациях, да?

netandreus – Да.. то есть там, в принципе, событий не так уж и много, там есть вот бутстрап-события, routeDispatch. То есть, в принципе, они взяли эту архитектуру и вои и переложили на события, концептуально все осталось на месте. По поводу того, что более правильный путь, я думаю, да, когда у нас есть некие обработчики события, когда у нас есть система, то, что в Ruby, за что вот я обожаю Ruby, там рельсы, тот как раз примат соглашения над конфигурацией; когда у нас есть путь, как надо это делать, и мы следуем этому пути и потом берем код какого-то Васи, если, конечно, он совсем там не раздолбай какой-нибудь, и мы быстрее в него въезжаем, да, то есть мы быстрее его понимаем, и это классно. Я думаю это то, к чему и надо стремиться, я вижу, что реально сейчас это два framework’а основных это Symfony и ZF, они идут к этому, причем они идут, так сказать, параллельными дорогами, очень много из ZF’а я вижу в Symfony, и очень много из Symfony я вижу в ZF’е. Да, мне это нравится, мне реально нравится, куда идет процесс. И нравится, что у нас есть стандартизация, что у нас как-то все не инфицируется, я вообще мечтаю об одном megaframework’е, “мега” в кавычках, то есть стандартно PHP вот как есть SPL, да вот никто же не спорит, почему в SPL W..Access метод так называется, а не иначе, все берут, и все используют. Вот если бы на PHP тоже один такой же единый framework с единым стандартным расширением, пусть это будут там банлы там, модули, plugin’ы, не важно. Он будет единым, у него будет community большой, реально он будет дорабатываться, то это будет просто будет мечта. У нас будет по сути там Ralils, я не знаю…

hackPNZ – Ты, хочешь, и я бы, наверное, бы хотел, но, тем не иене, есть такой же PHP way такой, что у тебя как раз выбор есть, выбор framework’ов, кто-то мутит микро framework’и, кто-то мутит какие-то MVC, ну такие замороченные framework’и, кто-то что-то передирает, как в Ruby, пытается в такую сторону смотреть, и так далее и тому подобное. То есть здесь у нас получается выбор, ну это опять же влечет за собой эти проблемы известные, выбор правильного инструмента, использование правильного инструмента… ну, это опять же тема такая для поспорить, надо ли вообще идти в сторону и стать, как Ruby.

netandreus — И в чем идея? Идея немножко не в этом. Это понятно – свобода выбора. Свобода выбора должна быть в чем? У тебя есть, ну представим себе, как мега framework, допустим, какой-нибудь, ты можешь его использовать, но у тебя есть возможность его кастомизировать на разных уровнях. То есть ты можешь спуститься ниже, ну как в Symfony, да там есть компонент какой-то HttpFoundation. На основе этого компонента построим совершенно другой framework Sliex.  Ну, то есть вот в чем свобода-то, то есть тебя никто не заставляет его использовать, ты можешь тот кусок, который тебе не нравится, взять и написать так, как тебе хочется. И ты не будешь уже изобретать велосипед в виде обработки http-запроса, получении там переменных из него. Вот эти «велосипеды» они будут стандартные. Получается, ты на базе стандартного «велосипеда», который уже обкатан и протестирован, что самое главное, пишешь уже свое. То есть, как бы базируясь на достижениях современной науки и техники, ты идешь дальше. Вот это, мне кажется PHP way, ZF way, не важно. Вот это круто, мне кажется, так надо работать, и в этом будет и свобода, и унификация, и рабочий код быстрого действия.

hackPNZ – Вообще мне нравится твой позитивный настрой, он такой… светлое будущее… рисует нам такую картину прекрасную, но на самом деле здесь, конечно, много проблем…и… что уж тут скрывать, я не особо верю, что это светлое будущее там в самое ближайшее время наступит; но то, что продукты развиваются, которые уже можно так сказать, похоронили типа ZF – это монстр, он не будет развиваться, там еще… и так далее… Я часто слышу такое, что все эти framework’и, они будут не туда, вот они такие становятся перегруженные…

netandreus – Java, кстати, тоже хоронили…

antonkopylov – Да-да-да… и все это хоронят и хоронят. И тут ты рассказываешь, что на PHP появляется в самом языке базовом на куче разных хороших вещей, и все это в принципе работает опять же… и здесь, и framework’и развиваются… Вобщем, хоронить пока рано, но это будущее мне видится дальше, где-то совсем далеко… поживем увидим… Еще знаешь что еще интересно по поводу конференции если говорить… Это опять же, мой уже какой-то интерес, внутренний что ли… Вот все эти NoSQL решения и прочие и прочие все эти классные штуки. Как вообще об этом, много ли на конференции говорилось, рассказывали ли о том, как с этими вещами и технологиями работать и вообще, то есть, framework что-то для этого стал поставлять большее для работы с той же MongoDB, как вообще, что про это рассказывали?

netandreus – Слушай, вот да, действительно, это такая тоже очень интересная тема. Был там доклад про кэширование, и почему-то, уже не помню, что там был за вопрос, но народ начал спорить о том, что как бы нам сделать такой кэш с тэгами и в памяти. Типа, что можно делать на файлах с тэгами, но это работает очень долго, потому что файловая операция, там, тэги хранятся . Второй там кто-то из зала предложил использовать мем-кэш для этого, там кто-то третий сказал, нет он не поддерживает тэги, там какой-то холивар разразился . Потом я расскал, ребята, у нас же есть замечательная база MongoDB, у нас есть замечательный адаптер для кэша Zend_Cache_ Backend_ MongoDB, который, во-первых, сидит в памяти, во-вторых, поддерживает теги нативнo. И не надо вот все эти «велосипеды» громодить вообще друг на друге там и хранить таблицу, ну, хэш-таблицу с тэгами, потом залезать туда, там смотреть, какие ключи, эти ключи удалять – все это есть в Mongo, NoSQL в данном конкретном случае это реально рабочий вариант. Я к нему пришел по двум причинам. Первая причина: это опять же эти вот тэги мне были нужны в памяти, естественно, для cach’а. Вторая причина, у меня почему-то сессии вываливались, которые в моем cach’е хранились. То есть юзеры заходили, и их выкидывало.

antonkopylov – Вопрос – их в Mongo хранить? В Мongo класть стал, да?

netandreus – Конечно, я стал класть сессии в Mongo, cach – в Мongo, и ты знаешь, я забыл об этих проблемах. Вот, конкретная задача – результат меня очень порадовал, вот, и продолжаю хранить. Это первый момент, и второй момент – у нас как бы вообще есть модный тренд с этим, с новым NoSQL, и многие ребята говорят, что куда, зачем в MySQL все это есть, в Handler Socket то же сааме. Я, кстати, работал с Handler Socket, хорошая вещь. Но тут дело немного не в этом. То есть у нас есть концепция SQL, кстати, ты читаешь мои мысли, я как раз хотел об этом сказать. Есть концепция у нас SQL, вот, если коротко отбросить, вот, какая вообще основная идея SQL? Вот как вы думаете? Такой вопрос к залу.

antonkopylov – Это модель языка запросов к данным, которые могут быть совершенно различными, я зык унифицированный. Суть к этому сводится. И плюс реляционная алгебра, которая есть математический аппарат определенный, вот она поддерживается этим языком запросов.

netandreus – Да, основная идея – это реляционная алгебра, нормализация данных, то есть у нас все данные в идеальной нормализованной базе, мы стараемся делать хорошие базы, они хранятся в одном месте, то еcть, нет дублирования информации. Данные нормализованы, у нас есть к ним запрос, и основная идея это превалирование количества информации… мы жертвуем вычислениями в угоду месту на диске. То есть информация хранится компактно в одном месте, но когда мы делаем запросы join’ами, select что-то, join вторая, третья, четвертая таблица, то у нас очень плохо дела обстоят с CPU, то есть у нас много вычислений тратится. Естественно, мы все это кэшируем, чтобы не делать тяжелые запросы. Понятие «тяжелые запросы» появилось потому, что у нас куча join’ов. Есть NoSQL. Там концепция совершенно противоположная. Мы наоборот ускоряем вычисления, мы делаем, чтоб максимально быстро все считалось, но мы жертвуем местом на диске, то есть у нас данные хранятся в двух-трех экземплярах, у нас данные денормализованы, и это хорошо! Потому что в любых high-load проектах как правило, основное узкое место – это распределение  по записи. То есть мы можем взять NoSQL, сделать ему кучу slave’ов, все будет замечательно, по чтению мы это все распараллелим. Но как мы будем параллелить запись? Да никак.

antonkopylov – Да, с записью – это проблема стандартная, а с Моngo мы взяли одну нашу табличку MySQL с кучей записей и просто поместили е на одну машину в Моngo без всяких replica-сэтов и прочего, шардинга и прочего. И нас удивило, насколько это там все быстро работает, причем, что тогда Мongo была ниже 2.0 версии. Те есть все эти локи глобальные, сейчас они локи оптимизировали уже при записи, а тогда это было еще хуже, все ругались, но, тем не менее, у нас это работало на ура. Данные были не очень критичны, мы жили и радовались, потом начали уже полностью мигрировать, и надо сказать, сейчас уже все супер, все замечательно, и я поэтому эту тему и поднял, что нам все это близко, ты знаешь, мы так с этим работаем.

netandreus – А сейчас рассказ про Mongo..

antonkopylov – Да, вобщем, и причем он будет не совсем в общих чертах, о какой-то конкретике поговорим, о каких-то хороших решениях, могу тебя позвать.

netandreus – Я с удовольствием послушаю.

antonkopylov – Да, OK. Давайте потихоньку переходить к реальной задаче. Сегодня у нас такая задачка, о которой мы обстоятельно поговорим, — как вообще на таком большом проекте, который у нас есть, который растет и развивается и который уже давно, в принципе существует. Как нам делать миграцию с ZF1 на ZF2? Эта тема, как я понимаю, животрепещущая для Георгия, у тебя много всяких вопросов по этому поводу и мыслей.

zhorzh – Проблема так и есть, проект на ZF1, и соответственно, есть такое личное впечатление или эмоциональное состояние, что кодовую базу нужно продвигать чуть-чуть, он написан на ZF1, пишется на версии PHP 5.2, сейчас идет ZF1 тоже не самой новой версии, это 1.9; и чтобы пользоваться всеми новыми возможностями и ZF 2 и PHP 5.3, есть такое вот желание потихоньку перевести этот проект на ZF Но проблема в том, что этот проект очень живой, постоянно от заказчика формируются задачи, которые нужно дорабатывать на проекте, то есть проект постоянно должен апгрейдиться, и жить своей жизнью, приносить доход заказчикам. При этом очень большое требование к стабильности работы проекта, к отсутствию простоев проекта, потому что сам проект из себя представляет бизнес-систему, систему, на которой основаны бизнес-процессы компании; и, соответственно, отсюда вопрос как рациональнее провести миграцию с ZF1 — ZF2, как это сделать так, чтобы простои были минимальными, простои в добавлении новых features в проект.

antonkopylov – Я так понимаю, Андрей, эта тема была затронута на конференции тоже, потому что у людей были похожие вопросы, правильно?

netandreus – Да, у людей были похожие вопросы, и передо мной стоит такая же задача, как и перед Георгием, немного другого ракурса, но смысл тот же. У нас в кулуарах состоялась беседа с Ростиславом на тему как же все-таки мигрировать с ZF1 на ZF2? Ростислав – это Ростислав Михайлев, это разработчик O-Desk и постоянный докладчик на конференции, и мы с ним обсуждали такие варианты. У меня была такая идея можно ли использовать ZF2 без этого объекта application? То есть взять FrontController, взять контролеры, маршруты и все. И не надо bootstrap’а, не надо будет application. Но, к сожалению, как я понял из доклада, такого сделать нельзя. Потому что все эти события, они пронизывают все приложение, и отдельно нельзя. И мы думали, как же все это мигрировать. И у нас сложился такой вариант, не знаю, насколько он рабочи, — на первом шаге нужно в проект ввести event manager из ZF 2, потому что без ивентов никуда, какие-то event’ы поотрабатывать, чтобы они не работали, на втором шаге ввести dependence injection, чтобы уже в обработчиках этих event’ов можно было бы получать классы-сервисы, и с ними уже что-то делать. И на третьем этапе ввести собственно сам MVC application, чтобы уже все это обрабатывать. Это все красиво звучит, но я точно пока не знаю, как это сделать на практике. Потому что на практике получается что? Представим себе, что у нас есть существующий проект, у нас есть существующие маршруты, layout’ы, виды, view helper’ы, у нас второй объект application ZF 2, dependence in the action все у нас есть, и мы начинаем сам процесс миграции. Что нам делать, например, с view helper’ами? То есть мы ему передаем название маршрута, он делает url, получается как минимум, у нас есть две таблицы маршрутизации, одна старая, одна новая, у нас будет два пространства контролеров, модули тоже, если они были раньше. И view helper должен также как и роутер, то есть у нас пришел url на вход, мы должны будем как-то сначала пройти по одной таблице, потом пройтись по второй таблице. И что самое интересное, что тот, кто первым будет обрабатывать, а это, скорее всего, будет новая наша подсистема, допустим, ZF 2, то ему еще как-то нужно выпилить обработку ошибок, потому что он url по своей таблице может не найти. У него сработает событийный error и так далее. И туда нужно вешать или свой обработчик, чтобы как-то это дело прекращать, либо делать некое глобальное исключение, которое всплывало бы в наш условный индекс PHP и перехватывалось, и в этом случае шла бы обработка запросов второй подсистемы, то есть старой. Это первый нюанс. С другой стороны view helper, который формирует url, у него примерно то же самое, то есть он должен сначала пытаться сделать url по первой таблице маршрутизации, новой, в случае, если это не прошло, он тоже не должен вываливаться с ошибкой, надо подавлять это поведение, и потом работать по второй таблице маршрутизации. И если во второй нет ничего, только тогда какую-то ошибку отображать. А сам процесс миграции будет заключаться в переносе маршрутов и соответствующих action’ов из второй части подсистемы в первую. Вот я как-то это так вижу, но опять же, общие части все равно будут. Допустим, поступила задача сделать какую-то новую feature в старой системе, и мы понимаем, что мы ее делам, а потом мы должны ее переносить. И мы должны будем как-то сократить издержки на перенос. А это все превратится, скорее всего, в какой-то статический метод класса, в какой-то single tone, что не очень хорошо, ну или же мы должны будем в новой части сразу использовать dependence injection сервис локатор и делать это все из старой части, вызывать уже новый код потихоньку. Ну а про поддержка у этого дела я, пожалуй, молчу, потому что надо, чтобы в проекте человеку знал, что, куда и когда. Иначе это все рискует покрыться…

antonkopylov – Ну, вообще жестоко тогда, конечно, получается. У меня внезапно возникла такая мысль — ведь если мы будем полностью переходить на ZF2, у нас же будут переписываться, я так понимаю, и модели, и helper’ы. Что именно в неизменном виде нам удастся выдернуть структурно из того, что есть на ZF1? Много ли будет такого? Потому что, если не очень много, то, может быть, просто сделать по-другому, сделать проект точно под структуру, под event’ы, под все в ZF2; и свой костыльный написать роутер, который будет старые запросы какие-то для одного контроллера полностью redirect’ить на бутстрап и точку входа первого ZF, чтобы он полностью его отрабатывал, а новый функционал и тот, который мы уже начали переводить на второй framework, чтобы он сразу redirect’ил на точку входа для второго ZF и, когда он полностью перейдет, просто первый берем и выкидываем, костыль мы тоже отбрасываем и сразу точку входа указываем второго ZF . Насколько такие пути вообще реальны?

netandreus – у меня вопрос – а чем это отличается от моего пути-то? То есть у нас есть некие url’ы, которые наш условно его назовем Proxy, он смотрит и говорит, вот этот url из первого списка, кидаем его на новый framework, этот url из старого списка, кидаем его на старый framework. Так это и есть диспетчер.

antonkopylov — то есть у тебя именно код будет совмещаться в проекте в нескольких местах, а я предложил все это вообще отделить. Чтобы у нас был свой какой-то диспетчер, который поймет, что этот контроллер у нас будет обрабатываться пока первым ZF, но при этом мы будем понимать, что этот код, он станет таким немножко, как в камне in stone…

netandreus – Да, его нужно замораживать…

antonkopylov – Да, и мы пуляем этот запрос к индекс PHP первого ZF, там нет никаких вставок от второго вообще, то есть там проблем с этим нет, с совместимостью и еще с какими-то вещами. Часть запросов мы пуляем полностью новую в структуру, которая у нас под вторым ZF. Возможные проблемы – если нужно переписать модели, у нас и там и там будут дубли, то есть мы для нового framework’а все это скопируем, положим. Просто смысл в том, что мы планируем постепенно перейти на второй, а первый проект просто потом выкинуть. Вот такое видение у меня в голове сложилось. Это сложно будет сделать, я так думаю.

netandreus — Это хорошо, когда у тебя некая такая одна линия миграции. То есть с первой перейти на вторую и все. А когда у тебя несколько линий миграции, то есть с первого ZF на второй, допустим с MySQL на Mongo, с Doctrine ORM на Doctrine ODM; и когда это все идет в параллель и плюс у тебя текущие какие-то задачи, то, как мне кажется, если есть на это ресурсы, — отлично, но если их нет, то это будет сложно, потому что нужно поддерживать две ветки. Вопрос ресурса.

antonkopylov – Да, здесь не просто поддерживать две ветки. С Mongo, кстати, сейчас есть какие-нибудь адаптеры нормальные для всего этого дела в Zend’е встроенные? Классы или модели Mongo’вские?

netandreus – Я, честно говоря, не видел таких адаптеров. Есть в Cach’е адаптеры, но он не встьроенный, там некий товарищ его презентовал, я потом допилил его, выложил сам себе и начал использовать. Мы use’ аем Doctrine и я не вижу, почему Zend’ е есть Zend DB, но что-то он мне давно и прочно не нравится уже.

antonkopylov – И, наверное, с выходом второго framework’а ситуация не очень поменялась?

netandreus — Нет, он стал лучше. Тот Zend DB, который сейчас, он лучше, чем, который был. Но он мне в принципе не нравится. Как есть люди, которым в принципе не нравится Zend-формы, они берут и делают формы совсем по-другому, с Symfony-компонентами.

antonkopylov – Это, наверное, как и я в свое время. Я с ним разбирался, кучу вопросов на форуме задавал, потому что мне нужно было делать сложные, сильно кастомизируемые формы. И все это пришло к тому, что я в итоге плюнул и стал делать со вставками и все.

netandreus — Значит, ты меня понимаешь.

antonkopylov – Да, так, а какие еще нюансы могут быть?

zhorzh — Вот вопрос. А вообще технически можно совмещать два framework’а, коды двух framework’ов в одном вызове? Там конфликтов c загрузкой не будет никаких?

netandreus – Ну, я их решил.

zhorzh — То есть ты пробовал уже?

netandreus — У меня оно работает. Это, так сказать, тестовая веточка, да у меня работает первый ZF с подстрочниками, и второй ZF с нейм Спэйсами и, соответственно, это все разруливается autoloader’ами Composer’а и все великолепно, все работает. То есть у меня загружаются части нового framework’а, старый framework работает в глобальном нейм спейсе живет, все хорошо.

antonkopylov – А ты второй ZF в Composer подрубаешь в соответствии концепции PSR-0, есть там у тебя такой ключик, да?

netandreus – Да. Composer тут, так сказать всех спас, потому что он и позволил все это разрулить. Помню раньше было очень много статей типа Как нам интегрировать вторую Doctrine и первый ZF?, Как нам интегрировать что-то с чем-то? И народ сидел, интегрировал, и я тоже. Это целая задача была, как вторую Doctrine с первым ZF связать. Это непросто, Георгий вот знает. Там надо запариться с autoloader’ами, более того, там будут всякие конфликты с Proxy-классами, которые там генерятся. То есть у меня, например, по непонятным причинам, и почему я вообще Composeк начал заниматься, у меня два автозагрузчика жили в стеке мирно и первый Doctrine’овский, и второй Zend’овский по SPL. Вдруг ни с того ни с его у меня Zend’овский autoloader начал грузить Doctrine’овские proxy. Естественно, он их не загружал, бывали bug’и, и причем плавающие, я начал с этим разбираться в который раз, мне это надоело все, и я взял и убрал все эти autoloader’ы, все эти костыли, поставил Composer, поставил пакет с первым Zend’ом, поставил пакет со вторым Zend’ом, один раз настроил composer.json , сделал Composer update — у меня все подключилось, и все заработало. И теперь нет таких задач, если мне нужно что-то подключить, и оно есть в Composer, я добавляю строчку в composer.json, делаю update, если у меня этот дев-пакет не старше полугода, то он у меня спокойно устанавливается, и все замечательно. И autoloader подгружается, все прописано. Георгий, таких проблем сейчас нет.

zhorzh – Ты в контексте чего объединял первый framework и второй framework? Для чего ты это делал?

netandreus – Я это делал в контексте эксперимента, будущей миграции. Мне было важно понять, во-первых, какая будет структура проекта, и как мне его грузить. И еще у меня стоит задача по модулям, то есть мне нужно как-то модульность внедрить, сделать нормальные независимый модули. И для этого я сначала избрал модули ZF 2 и пробовал их подключить к проекту. Первым шагом была автозагрузка, я как раз об этом рассказал, вторым шаги было их какое-то отдельное подключение с помощью модуль-manager, у меня это не получилось, потому что модуль-manager работает вместе со всем остальным. То есть тут ZF пошел в сторону Symfony – какой-то здоровый кусок, который работает вместе. И очень сложно, но наверняка можно как-то это сделать, пока еще не знаю как, и отдельно подключить модули, чтобы в проекте отдельно были event-manager, модуль-manager и все. Но до этого я не дошел пока.

Продолжение

Share