Zend Framework, субъективные впечатления

Недавно мне было поручено разработать некое веб-приложение. Не буду вдаваться в подробности, а лишь скажу, что приложение связанно с планированием перевозок. Есть общедоступная часть, воспользоваться которой может любой посетитель сайта. Есть внутренние интерфейсы для операторов системы. Есть информеры для размещения на сторонних сайтах. С технической точки зрения это несколько десятков экранов, множество различных форм, табличек. Часть экранов используют ajax, кастомные компоненты, написанные на javascript, и всякие красивости типа drag-and-drop. Данные, как обычно, хранятся в реляционной БД в виде полутора десятков таблиц. В общем не совсем примитивное приложение, но и очень сложным назвать его тоже не могу.

По работе мне, мне достаточно часто приходится проектировать или лично кодить подобные приложения. Однако в данном проекте было одно важное требование. Приложение должно быть разработано на базе серьезной и проверенной платформе, а именно на Zend Framework. Использование самописных “велосипедов” — недопустимо. Скажу честно, опыта реальной работы с Zend Framework у меня до сих пор не было. Но платформа известная и за ней стоит известный разработчик. Многими разработчиками Zend Framework вообще рассматривается как стандарт веб разработки. Так что, тем более, есть повод освоить что то новое и солидное. Поэтому я с энтузиазмом взялся за этот проект.

Далее пойдет описание моих личных эмоций и впечатлений, поэтому, возможно, не стоит их воспринимать слишком близко. Это именно некий эмоциональный остаток, оставшийся после завершения работы над проектом. Zend Framework в коммерческом проекте был использован мной впервые.


Zend Framework позиционируется как отличная, продуманная и удобная платформа для разработки веб-приложений. Что же такое типичное веб приложения по моему личному мнению? Ну, это много разнообразных экранов, много форм, много табличек. Все это активно работает с базой данных, обычно с реляционной базой данных. Ладно, буду конкретнее, в 95% случаев именно с MySQL. Итак, от платформы для разработки веб приложений я как минимум ожидаю хороших возможностей по созданию форм, разных экранов и удобную работу с реляционной базой данных. И вот я приступил к освоению.

Первым делом мне потребовалось изучить основы самого Zend Framework. Мною была прочитана книжка посвященная этой платформе “Zend Framework. Разработка веб-приложений на PHP. Автор: Викрам Васвани”. Похоже что на данный момент это чуть ли не единственная русскоязычная книжка в печатном виде посвященная подобным фреймворкам. В принципе книжка вполне неплохая. После прочтения у меня появилось общее понимание как работать с фреймворком. Дальше я приступил к изучению официальной документации, чтобы заполнить пробелы и вообще понять, что еще может предоставить мне это фреймворк. Ведь книга рассматривает далеко не все возможности движка. Исчерпывающая и доходчиво написанная официальная документация находится здесь framework.zend.com/manual/ru Примерно через неделю я решил что можно приступать к разработке приложения.

Мое мировоззрение на кодинг


Пару слов о моем персональном мнении, как должны писаться продукты. Упомяну здесь и те вещи, за которые меня иногда критикуют.

Я уважаю ООП и применение ООП-патернов. Но применение должно быть обоснованным и реально упрощаться читабельность кода или его дальнейшее совершенствование. Патерны ради патернов — это плохо.

Хороший код — это понятный код. Понятный код — это лаконичный код. Если можно написать код короче, то как правило он будет понятнее. Чем больше логически связанных кусков кода помещается на одном экране монитора — тем лучше.

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

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

if(@$_POST[‘action’] == 'done') {
   $dbi->exec(“UPDATE bug SET status=’done’ WHERE id=:bugId“, array(‘bugId’=>$bugid));
   $message = “Status changed to <b>Done</b>”;
}
elseif(@$_POST[‘action’] == ‘delete’) {
   //  ….
}
//…. плюс еще 20-30 других простейших действий...


Да, я здесь смешал Модель, Контроллер, Раутер и Представление. Вполне похоже на фрагмент говнокода. Однако, в некоторых, осознанных случаях, я напишу именно так, если это будет оправданно с точки зрения временных затрат, объема кода и возможности дальнейшей поддержки. В общем, я против ярого mvc-фанатизма, и я за здравый смысл и обдуманность подходов.

В проекте о котором идет речь в статье, разумеется, такого кода нет. Я не считаю что у меня уже достаточно опыта, чтобы осознанно отступить от подхода диктуемого в Zend Framwork, поэтому я старался полностью следовать его концепции.

Теперь немного о шаблонах в веб-проектах. Я не понимаю когда используются шаблонные языки типа Smarty. Ну зачем выдумывать новый и в общем то ограниченный язык, когда есть полноценный язык PHP? Неужели верстальщика тяжело научить использовать PHP-шные if(...) и foreach(...)? Это не сложнее чем в Smarty, но зато мы не добавляем в проект новый экзотический язык.
Кстати, бывает что шаблоны (или Представления) настолько сложные, что в них приходится использовать не только if и foreach, а и весьма сложные конструкции, включая классы и объекты которые наследуются друг от друга. Хотя при этом, задача преставления остается прежней — сформировать HTML кода по сухим данным.

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

function renderTemplate($file, $vars) {
    foreach($vars as $_name => $_var) {
        $$_name = $_var;        
    }
    require $file;
}

// Пример 
renderTemplate(“page.tpl.php”, array(
   ‘menu’ => array(‘/about’=>’О нас’, ‘/contacts’=>’Контакты’)
   ‘title’ => ‘Заголовок’
));


Плюс конечно простейшая обвязка для экранирования, для кэширования. Вроде больше ничего и не надо для счастья.

Пожалуй я еще ничего не имею против XSLT в качестве шаблонного языка. Но только для случаев когда вариантов представления информации не очень много и они относительно простые. Ну не сделаете вы легко на голом XSLT шаблон для какой-нибудь адской формы структура и геометрия который полностью зависит от поступивших данных. Здесь потребуются и циклы и объекты и полиморфизм и наследование.

Установка Zend Framework


Фрейморк, как оказалось весит около 25МБ и содержит почти 3000 файлов. Неслабо, подумал я! Видимо там реализовано все, о чем только можно мечтать!

Для начала меня немного расстроила структура директорий приложения на базе Zend Framework. Она предполагает весьма большое количество директорий. При работе над проектом я постоянно терялся в этой структуре. Также немного перемудерными мне показались правила названия создаваемых классов, правил для именования файлов и путей их размещения. Логика в них есть, но честно говоря, можно было все это сделать более интуитивно понятным. И особо сильно утомляет путешествия по директориям скриптов представления. Хотя, видимо если долго работать с этим фреймворком, то привыкнешь.

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

Оказалось, что Zend Framework не рассчитан на работу с shared хостингом, т.к. для запуска требует прописать в VirtualHost директорию отличную от корня вашего проекта. Так что у вас должен быть как минимум VDS сервер. Ну да, я слышал мнение, что если вы разрабатываете что то, что работает на shared хостинге, то вы не крут, и вам не место среди профессионалов. Хотя я всегда считал что 95% все веб проектов крутятся именно на shared хостингах. Ладно, в любом случае после нескольких взмахов напильника, я все же заставил проект подняться на shard хотинге.
Работа с базами данных

Сначала мне потребовалось создать модели данных (в рамках концепции MVC). Как выяснилось, Zend Framework не предоставляет ничего готового для создания моделей. По сути надо просто написать собственный класс, методы которого будут выполнять ту или иную операцию по работе с БД. Т.е. в ряде случаев, класс модели, это всего лишь обертка над SQL запросом, а иногда SQL запросы с некой дополнительной обвязкой на PHP.

Для работы с БД во фреймворке используется компоненты Zend_Db. Он позволяет работать с большинством распространенных СУБД через SQL.

Он также позволяет делать запросы без использования SQL, а конструируя некий хитрый объект, который внутри фреймворка все таки превратиться в SQL. Вот только мне кажется что для написание более-менее сложного запроса, все равно удобнее и понятнее написать SQL запрос, чем конструировать эту обертку, которая, как выясняется, позволяет создать далеко не любой сложный запрос. В общем я считаю что лучше хорошо изучить сам SQL, чем пытаться заставить его сформировать фреймворк, и надеяться, что он это сделает оптимальным образом. Нативный SQL намного лучше читается, понятен всем программистам и позволяет использовать все возможности конкретной СУБД. Вы скажете, что использование объектного конструктора запросов позволяет абстрагироваться от диалекта конкретной БД? При сложных запросах — далеко не всегда удается абстрагироваться, даже имея крутой конструктор. Ну и еще один аргумент — я не помню ни одного проекта, где бы потребовалось сменить СУБД, и при этом не предполагалось глобальной переделки всего проекта, бизнес логики и модели данных, т.е. написание полностью нового проекта по мотивам предыдущего. Сохранение кусочка класса модели данных от предыдущей версии на общем фоне не сильно облегчит жизнь.

Итак, как выглядит работа с SQL в Zend Framework? Ну вот примерно так:
$result = $db->fetchAssoc('SELECT * FROM items WHERE age>18');

И далее с $result можно работать как с ассоциативным массив в виде таблицы (хоть это и не совсем массив), что весьма удобно. Можно передать массив на дальнейшую обработку, а можно и напрямую передать его в представление для вывода на экран.

Есть еще несколько удобных методов, которые извлекают результаты SQL запросов:
fetchCol() — извлекает одну колонку. Удобно когда надо получить список ID-шек
fetchRow() — извлекает первую строку. Удобно когда надо выбрать одну запись по первичному ключу.
fetchOne() — Извлекает только одно значение. Тоже удобно, когда реально надо получить одно значение и не хочется писать код для выковыривания одного элемента его из массива.
fetchPairs() — извлекает пары значений в виде ассоциативного массива. Создает хэш типа ключ-значение. Очень полезно создания разных словариков.

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

Метод fetchPairs() это хорошо. А теперь, как на получить чуть более интересный и нужный словарь, где в качестве ключа идет первичный ключ БД, а в качестве значения массив-запись БД? Очень распространенная задача. Ответ — а никак! Делай руками, вызывай fetchAssoc(), потом крути цикл и генерируй новый массив-словарь. Обидно!

Ладно, идем дальше. Надо извлечь из таблицы данные и построить из них древовидный массив. Оказывается эта распространенная операция тоже никак не реализована. Т.е. нет ничего типа:

$hierarhy = db->fetch_tree(“SELECT id, parent_id, title FROM tree‘, ‘id’, ‘parent_id’);

Идем дальше. В SQL надо передавать параметры. Ну да, на первый взгляд все просто. Делается это так:

$result = $db->fetchAssoc('SELECT * FROM news WHERE id = ?', 7);

Можно даже несколько плейсходлеров поставить.

$result = $db->fetchAssoc('SELECT * FROM news WHERE chapter=? AND type=?', array(2, 8));

Только вот когда программа становиться сложной, то и сложность запросов растет, и параметров могут быть уже десятки. Нужны именованные плейсхолдеры. Считать плейсхолдеры по их порядковому номеру — далеко не располагает к понятности кода. Как выяснилось, Zend Framework их не реализует! Они работает, но только если выбранная БД их поддерживает. Например если вы выбрали MySQLi то с именованными плейсходерами вы работать не сможете. Неужели было так сложно было сделать эмуляцию именованных параметров?! Ладно, эта вещь оказалось решаемой. Оказывается если в качестве адаптера выбрать Pdo_Mysql вместо Mysqli, то именованные параметры начнут работать, т.к. они эмулируются внутри самого PDO. Признаться, я дошел до этого не сразу. Обида стихла, но неприятный осадок остался.

Частенько в SQL запросах приходится использовать код типа такого

SELECT * FROM items WHERE id IN(1,3,5,8,12)

где список id-шек, динамически генерируется из массива.
Я лично не нашел способа сделать это на Zend Framework красиво. Есть некий метод quoteInto(). Использовать можно так

$sql = $db->quoteInto(«SELECT * FROM item WHERE id=IN(?)», array(1,3,5,8,12)));

Смиряемся с невозможностью использовать именованные параметры в запросе, с составлением сложного запроса из нескольких кусков, но зато получаем нужный SQL код. Только мы еще получим синтаксичекую ошибку, если массив окажется пустым, потому что SQL получиться такм SELECT * FROM item WHERE id=IN().
Так что или заворачиваем все в if(count($idList) > 0), или к массиву каждый раз добавляем заведомо недопустимый идентификатор, например -1. Кривенько, но решение. Но все равно, получается? что составить сложный SQL запрос можно только путем конкатенации строк. А я предпочитаю видеть любой SQL запрос в виде одного куска кода, без какого либо вкрапления PHP. А то блин, смешивать HTML и PHP считается плохо, а вот SQL и PHP, видете ли, нормально.

В общем, не сильно мне порнавился Zend_Db. Какой то большой выгоды или сильного удобства от его использования я не заметил. Кстати Zend_Db весит больше 500КБ.

Вообще, для работы с БД я предпочитаю использовать самодельный маленький класс со следующими публичными методами:

connect($config) — Соединяется с БД
fetchTable($sql, $params) — Возвращает массив записей
fetchRow($sql, $params) — Возвращает одну запись
fetchCol($sql, $params) — Возвращает одну колонку
fetchOne($sql, $params) — Возвращает скаларное значение
fetchPairs($sql, $key, $value, $params) — Возвращает массив ключ — значение
fetchDict($sql, $key, $params) — Возвращает массив ключ — запись
fetchTree($sql, $key, $parent, $params) — Возвращает дерево
exec($sql, $params) — Выполняет не select запрос
getInsertId() — Возвращает последний сгенерированный автоинкремент
getAffectedRows() — Возвращает число измененных записей

Результаты выполнения — обычные ассоциативные массивы логичной для каждого из случаев структуры. Параметры — всегда именованные, можно передавать числа, строки, а также списки. Класс кидается исключениями, если в SQL допущена синтаксическая ошибка. Этот “велосипед” весит в районе 10КБ, и честно говоря мне его всегда хватает. Другим программистам на его изучение требуется 10 минут, а для изучения Zend_Db — часы внимательного штудирования мануалов, и все равно остаются вопросы. Путем расширения класса и переопределения нескольких виртуальных методов, можно добавить поддержку любой другой БД.

Формы


Следующая важнейшая вещь для веб-приложения это формы. Обычно их весьма много. Структура и внешний вид тоже очень разнообразны. Для работы с формами в Zend Framework используется Zend_Form.

Чтобы создать форму надо сконструировать объект формы. В него надо добавить объекты каждого из полей. В полях можно настроить разные параметры. Указать валидаторы и т.п. Вот пример создания поля

$username = new Zend_Form_Element_Text('username');
$username
         ->addValidator('alnum')
         ->addValidator('regex', false, array('/^[a-z]+/'))
         ->addValidator('stringLength', false, array(6, 20))
         ->setRequired(true)
         ->addFilter('StringToLower');


Создав все поля — добавляем их к объекту формы

$form
      ->setAction('/somepath')
      ->setMethod('post')       
      ->addElement($name)
      ->addElement($company)
      ->addElement($email)
      ->addElement($phone)
      ->addElement($action);


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

$form->addElement(new Zend_Form_Element_Text('username'))
    ->setRequired(true)
    ->addValidator('regex', false, array('/^[a-z]+/'));


Но так нельзя!

Как вы заметили, тут можно использовать готовые валидаторы полей. Неплохо. Давайте попробуем сделать поле для ввода e-mail и введем кривой адрес электронной почты. Для этого используем стандартный валидатор EmailAddress.

Попробуем указать кривой емейл “xxx”. Получаем сообщение о некорректности:

'xxx' is no valid email address in the basic format local-part@hostname

Нормально. Разумеется надо бы перевести сообщение на русский, но там это можно легко сделать. А теперь давайте попробуем еще более кривой адрес “я@_domain.xx”.
И вот что мы получаем:

'_domain.xx' is no valid hostname for email address 'я@_domain.xx'
'_domain.xx' appears to be a DNS hostname but cannot match TLD against known list
'_domain.xx' does not appear to be a valid local network name
'я' can not be matched against dot-atom format
'я' can not be matched against quoted-string format
'я' is no valid local part for email address 'я@_domain.xx'


6 сообщений! Кому это надо? Неужели рядовой пользователь вообще поймет что такое TLD, quoted-string или dot-atom? Рядовому пользователю нужно только одно единственное сообщение — “Некорректный E-mail” и все! Но стандартные средства этого не позволяют. Чтобы избавиться от вывода этой кучи сообщений — предлагается написать свой собственный класс валидатора.

Ну допустим сделали мы форму, настроили все поля, все валидаторы. Теперь выведем ее. По умолчанию HTML код форма будет выглядеть примерно так:

<dl class="zend_form">
    <dt id="phone-label">
        <label for="phone" class="required">Телефон</label>
    </dt>
    <dd id="phone-element">
        <input type="text" name="phone" id="phone" value="">
        <ul class="errors"><li>Введите значение</li></ul>
    </dd>
    ...
</dl>


Причем в DD элементы буду заворачиваться даже hidden поля! А потом мы начнем удивляться, что за странные пустоты образовались в форме. В общем интеллекта для особой обработки hidden полей у фреймворка нет.

А что если меня простейший DL список не устраивает? Вдруг мне надо сделать форму со сложной структурой? Тут предлагается использовать классы декораторы. Декораторы, это такие классы которые позволяют заворачивать элементы формы в определенные HTML теги, например можно завернуть элемент не в тег DT, а например в DIV. О ужас! “Правильный” MVC фреймворк вынуждает нас заниматься версткой прямо внутри контроллера, причем самым нечитабельным способом!

На мой взгляд, версткой нестандартных форм должен заниматься исключительно верстальщик. Он должен просто сделать скрипт представления который содержит все верстку формы. А использовать десяток классов декораторов внутри контроллера — это, мягко говоря, криво.

Позвольте привести пример простейшего “велосипеда” для работы с формами, который позволяет лаконично и удобно создавать формы.

Конфигурирование формы:

$form = new UniversalForm(array(        		
    'name'  => array('label'=>'Имя', 'required'=>true),
    'email'  => array('label'=>'Имя', 'type'=>’email’),
    'birthday' => array('label'=>'Дата рождения', 'type'=>'date'),
    'sex'      => array('label'=>'Пол', 'type'=>'choice', 'items'=>array('m'=>'М', 'f'=>'Ж')),
    'code' => array('label'=>'Код', ‘regExp’=>’/^\d{6}$/’, ‘regExpMessage’=>’Неверный код’, ‘value’=>’000000’),
    'action'  => array('type'=>'hidden', 'value'=>'updateInfo'),                
)); 


Здесь, для уменьшение объема кода делаем возможность позволяем вместо явного создания объектов элементов формы, просто создать конфигурирующий массив. Хотя это и не исключает возможности создания объектов полей и валидаторов вручную. Ну а дальше, используем форму:

$form->setFromPost(); // Установить данные из POSTа
$form->isValid(); // Проверить что данные валидны. Если нет, то будут установлены сообщения об ошибках, которые выведет скрипт представления формы.
$data = $form->getValues(); // Получить значения
$form->setValues($data); // Установить значения полей. Хотя можно это же сделать через конфиругирующий массив в конструкторе
$form->render(‘form.tpl.php’); // Сформировать HTML. Если не указан шаблон, то будет использован шаблон по умолчанию.
$form->renderJs(); // Сформировать JavaScript валидаторы, которые дублируют PHP валидаторы на стороне клиента.

Ну а теперь несколько методов, неправильных с точки зрения MVC.
$form->getSqlSet(); // Вернет кусок SQL кода
Можно использовать так

$sql = “UPDATE account SET “.$form->getSqlSet().” WHERE id=777”;

Следующие методы используются для тех же целей.
$form->getSqlFieldsList();
$form->getSqlValuesList();
Да, это не совсем канонически правильное решение. Но зато набор полей надо описать только один раз в конструкторе формы. В случае его изменения автоматически изменятся и все SQL запросы.

Админки


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

В общем в этом фреймворке нет ничего готового для этого. Если надо, приходится реализовывать все самому вручную. Т.е. для каждого редактора создавать экран с таблицей, с формой, и практически вручную реализовывать CRUD операции.

Выводы и впечатления


Как вы поняли, этот “правильный” фреймворк произвел на меня не очень хорошее впечатление.

Но пожалуй что Zend Framwork все же можно освоить в следующих случаях:
1. Если у вас недостаточно опыта чтобы сделать сносный каркас для своего приложения.
2. Если вы вообще не умеете работать с MVC, но хотите прочувствовать эту идеологию
3. Если у вас нет хорошего представления об ООП и применении типичных патернов проектирования, то Zend Framwork покажет вам множество примеров. Там они использовали ООП везде где надо и не надо.
4. Так же Zend Framwork вполне сойдет, если вы делаете несложное приложение, работа которого больше сводится к извлечению данных из БД и выводу на экран. Например, какие нибудь новостные порталы или каталоги продукции.

Хотя, может все же лучше обратить свой взор на какой либо другой фреймворк? Zend Framework уже начал терять позиции, и возможно неспроста.

А лично я наткнулся на неудобства практически во всех компонентах фреймворка с которыми пытался работать. Регулярно ворчал себе под нос фразы типа “Это же можно было сделать удобнее!” или “Ну почему этого они не реализовали!”. У меня создалось впечатление, что главная задача разработчиков Zend Framwork была сделать все ООПно. Все что можно, все завернуть в враперы, адаптеры, и не важно, будет ли это удобно или нет. Уровень абстракции в библиотеке крайне высок, настолько высок, что в нем тяжело разбираться. И главное, практически любой компонент надо допиливать под свои потребности. В сыром виде все работает не так как хочется.

Да, я прекрасно осознаю. Наверняка я что то недопонял во фреймворке. Наверняка что-то пропустил в мануалах. И сейчас я получу замечания в стиле RTFM. Но и это тоже показатель. Хорошая платформа должна легко и быстро осваиваться, сразу показывать правильные и удобные решения. Здесь, я этого не почувствовал.

А еще мне вспомнился советский анекдот, когда собирая по чертежам самолет, получался паровоз. А в чертежах было написано — “получившееся изделие — доработайте напильником”. Я не хочу дорабатывать паровоз до самолета напильником. Я хочу чтобы все сносно работало прямо “из коробки”.

P.S.: Заранее прошу прощения, если я задел чьи то “религиозные чувства”.

P.S.2.: Статья писалась про Zend Framework. И это никак не попытка оспорить достоинства MVC, но к сожалению многие именно так ее и восприняли.
Поделиться публикацией

Похожие публикации

Комментарии 91

    +1
    Если лень создавать руками воспользуйтесь zf cli tool.
      +1
      И, прошу прощения, для работы с большими фреймворками удобно использовать различные IDE, где нет необходимости искать файлы по директориям. Да и во всех уже средах переход к классу можно осуществить путем набора заглавных букв класса Zend_Form_Element > ZFE.
        0
        К сожалению он позволяет выполнить далеко не все действия. И вроде бы работает только при условии стандартной для него структуре директорий, которая для shared hosting не подходит.
          0
          Он работает на основании конфига, где у вас прописаны пути до основных директорий.
            0
            А у меня начал сыпать ошибками и падать. Видимо не хватило упорства заставить его работать.
            0
            Хм, у меня есть несколько реально работающих проектов написанных на ZF. Часть из них спокойно работает на shared-хостинге, т.е. все файлы лежат в публичной директории. Все что нужно сделать для этого — задать пути к папкам в конфиге.

            ZF очень гибкий фреймворк, его можно настроить как угодно и для чего угодно.

            P.S. Если вы в чем то не разобрались до конца (а судя по статье даже не хотели) не нужно писать статью с поспешными выводами.
          +15
          Если не желаете травмировать свою психику — лучше не читайте статью.
            –2
            >Только вот когда полей становится много мы обязательно какое нибудь из них забудем добавить в форму. Ну не люблю я до >ужаса, когда в коде надо чего нибудь перечислить, а потом где нибудь в другом месте опять это все повторно перечислять. >Причем здесь >надо каждый раз указывать имя переменной объекта поля и его название для вывода
            


            А что вам мешает сделать элементы формы ассоциативным массивом? и в конце все разом добавить в форму методом addElements?
            ... $elements['id'] = new Zend_Form_Element_Hidden('id'); $elements['id']->setRequired(true); .... $elements['title'] = new Zend_Form_Element_Text('title'); $elements['title']->setLabel('Title:')->setRequired(true)->addFilter('StripTags')->addFilter('StringTrim')->addValidator('NotEmpty'); ... $this->addElements($elements);
              0
              Я кстати, когда использовал ZF, любил формы классами объявлять. Тоже очень удобно.
                –1
                Собственно так я и выкручивался. Но не хочется делать лишних циклов там где можно обойтись без них.
              +2
              Я ещё не дочитал до конца. Но, сразу появились комментарии, поэтому я оставлю их здесь, чтобы не забыть.

              if(@$_POST[‘action’] == done) {
                 $dbi->exec(“UPDATE bug SET status=’done’ WHERE id=:bugId“, array(‘bugId’=>$bugid));
                 $message = “Status changed to <b>Done</b>”
              }
              elseif(@$_POST[‘action’] == ‘delete’) {
              //  ….
              }
              //…. плюс еще 20-30 других простейших действий...
              

              1. Это ведь switch… case?
              2. @ — Лично я никогда не использую погашение ошибок. Хотя, я знаю 1 сценарий, когда это может реально пригодиться и увеличить скорость приложения.
              3. $bugid — откуда взялась эта переменная? Тоже пришла из запроса? А как она прошла валидацию? Были ли фильтры? Всю функциональность выполняет фреймворк (не обязательно ZF).
              4. Книжка ни о чем. Я её купил один из самых первых (по предзаказу). Дочитать не смог. Пособие для секретарш, как печатать в word. К сожалению, эту книгу нельзя порекомендовать даже для первого ознакомления с ZF.
              5. Разобравшись с MVC и структурой файлов вы легко сможете работать на других MVC фреймворках — Yii, Symfony и т.д.
                –7
                1. Верно, это switch… case. Но я с детства не люблю эту конструкцию. if else с фигурными скобками чуть более читабельны.
                2. В данном случае скорость не критична. Ведь это выполняется даже не в цикле. Я согласен пожертвовать несколькими микросекундами в угоду простоте кода.
                3. Это же просто обрезок кода. Нет смысла приводить тут все целиком.
                4. Других печатных изданий в России не продается. А книга все таки общее представление дает. Вполне можно читать по диагонали.
                  0
                  Между if и switch обычно нет разницы по скорости, либо она незначительна, но если сравнение строгое, то if будет быстрее.
                    0
                    switch (true) { case $a == 1: break; case $a == 2: break; default: // else }
                      0
                      Прошу прощения, не тот тэг использовал в комментарии.
                        0
                        Ну это уже не совсем прямое использование switch'а. И опять же это будет медленнее аналогичного if'а.
                          0
                          Думаете вы хоть как то почувствуете разницу между switch и if, даже на hightload приложении, если они не крутятся внутри огромного вложенного цикла?
                            –2
                            Да, очень чувствуется. Как раз много сталкиваюсь именно с очень частым многократным выполнением кода. Возьмем простой websocket сервер на php. Сразу начинаешь чувствовать нехватку специализированных типов данных без которых память сжирается с бешенной скоростью, тормоза в каждой операции, накладные расходы на каждый лишний вызов функции.
                              0
                              Неужели вызов функции сравним с разницей выполнения if и switch?!
                              Мда… Надо будет посмотреть бенчмарки на основные языковые конструкции в последних версиях PHP.

                              Когда я что то оптимизирую по производительности, то обычно сначала это SQL, потом конфигурация сервака, потом алгоритмы на PHP, и уж языковые конструкции — в последнюю очередь. Мне кажется оптимизация языковых конструкций не даст выиграш более чем в пару процентов. А остальные виды оптимизации запросто дают 100 и 1000 и более процентов.
                                0
                                Вызов функции, конечно гораздо накладнее выполнения if/switch. Но когда необходима микрооптимизация чтобы выжать максимум, то даже отказ от if'ов может заметно повышать быстродействие. В данном случае нет SQL, алгоритмы уже максимально оптимизированы. Штатная ситуация :)
                                  0
                                  Значит у вас действительно жесткий highload в условиях ограниченных ресурсов. Тут уже стоит об отказе от PHP и переход, например на C.

                                  Но согласитесь, в 95% проектов такая оптимизация не нужна. Это будет лишь трата челевокочасов.
                                    0
                                    С этим не спорю, но факт в том, что и такие задачи бывают. Собственно и переход на другой язык уже рассматриваем. Был бы у Kotlin хотя бы один релиз стабильный, то сразу перенес бы все на него. На C слишком усложнится поддержка — сервер плотно интегрируется с самим приложением.
                                      +1
                                      Попробуй CAS от Rambler. Даже где-то на просторах сети натыкался на презентация и мануал от них по разработке приложения на оном.
                      +4
                      Ну уж извините, но я бы не стал брать Вас в команду, зная, что у меня в проекте появятся такие портянки из if\else вместо switch или разделения на экшены (что более предпочтительно, так как при изменении логики я буду ковыряться не в миллионе строк с If\else вспоминая какой action в посте что делает, а перейду на нужный экшен в контроллере, который задокументирую и создам автоматическую документацию). Да, избыточность строк кода, но я думаю о людях, которые будут это поддерживать, тем более, что этим человеком могу оказаться и я через годик.
                    +7
                    Если вы не любите собак, то возможно вы просто не умеете их готовить (с) Корейская мудрость
                      0
                      «Но и это тоже показатель. Хорошая платформа должна легко и быстро осваиваться, сразу показывать правильные и удобные решения.»
                      Да да именно по этому ZF занимает одну из лидирующих позиций среди php фреймворков.
                        +1
                        Прошу сразу не набрасываться на комментарий — пишу так же субъективно, как и автор статьи.

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

                        Вы привели пример с моделью BugModel — все вполне ясно, конечно кода больше, но и мы содержим все запросы для работы с БД в одном месте, в противном случае, когда будет схожая операция с БД — нам опять же придется писать запросы, где мы статически будем обращаться к таблице bug. Т.е. название таблицы будет забито в N местах.

                        Но бывают ситуации, когда проект является частью другого проекта, где таблица называется не bug, а bug_report, к примеру. И приходится делать Ctrl+F по проекту в поисках названия таблицы, заменять названия в N местах, а вместо того, чтобы в модели изменить название таблицы 1 раз.

                        Хотел написать, что модели на ряду с AR так же дают некую абстракцию над БД, но зачастую такая абстракция является избыточной, так что этот момент я опущу.
                          0
                          полностью согласна — посмотрите на .net — в 99% просто нет чисто C# или что там используется.
                          Framework`и такие фреймворки.
                          +13
                          Я бы не доверил автору проект, о котором он говорит.
                            +1
                            Уж на что я сам люблю делать хорошие велосипеды, но статья, на мой взгляд, не очень хорошая. Есть здравые мысли и не здравые, а по сколько все вперемешку, то печально. ZF не люблю, но изредка использую как базу готового кода.
                              0
                              Начинал изучение ZF вот с этой книжки(англ) http://www.amazon.com/Zend-Framework-A-Beginners-Guide/dp/007163939X/ref=sr_1_2?ie=UTF8&qid=1346676830&sr=8-2&keywords=zend+framework

                              Негативных эмоций фреймворк не вызвал
                                0
                                На русский ее через два года перевели (в 2012). Автор ее и читал.
                                +3
                                Сразу видно, что человек вникал в Zend Framework по недо-книге В.Васвани, которая имхо является вольным пересказом прекрасного zf-мануала.

                                На форуме zendframework.ru/ после выхода этой книги появилось огромное количество тем от новичков из серии «сделал как в книге — не работает» или «пара вопросов по книге».

                                При этом несложный поиск в гугле позволяет найти набор видео-уроков от Mr.Remchi, именно которые можно назвать пожалуй самым удачным руководством для быстрого старта (он там CRUD и рассматривает). Безусловно, эти скринкасты не исчерпывающие, но они указывают дверь в которую разработчику остается лишь войти (предварительно прочитав официальную документацию, которая также весьма и весьма хорошо написала, и даже сносно переведена на русский).

                                Кому мало — есть замечательный сайт www.zendcasts.com/ с расширенным набором видеоуроков для решения менее тривиальных задач на ZF.

                                Но рассказывать о том что ZF сделан неправильно, а вот мой велосипед — самый накатистый и с самыми круглыми колесами — это пожалуй неверно. Возможно стоит вначале разобраться в предметной области, а ругать уже потом.
                                  0
                                  Я лишь рассказывал о первых впечатлениях. От некоторые платформ сразу приходишь в восторг, а от некоторых эмоции менее радостные.
                                    +1
                                    Возможно, стоило вначале посмотреть фреймворк и оценить свои силы и(или) желание делать что-либо на нем. А потом либо согласиться, либо отказаться, либо уговорить заказчика обратить внимание на какой-то другой (не менее надежный и популярный) фреймворк.

                                    А то получается что Вы взялись за относительно сложный для новичка проект на не самом простом фреймворке (с точки зрения порога вхождения), наступили на грабли и вместо того чтобы курить маны пришли на хабр жаловаться что разработчики ZF сделали все слишком сложно для Вас. Как-то неправильно.
                                      +2
                                      По мануалам мне фреймворк показался очень хорошим. А на простых учебных задачках серьезного опыта не получишь. Чтобы оценить — надо выполнить реальный проект.
                                  +2
                                  В принципе поддерживаю автора, работал прежде с самодельным фреймворком и в реальной разработке требуется процентов 20 от того, что предлагает Зенд.
                                  Про формы, для сложных форм можно просто задать шаблон через viewScript и через переменные расставить элементы.

                                  По моему, большие фирмы или сторонние заказчики используют известные фреймворки для легкой замены разработчиков. Учить каждого своему фреймворку долго, плюс нужен активный разработчик фреймворка. А так указал в вакансии требуемую квалификацию и экономишь время и деньги.
                                    +1
                                    Только заказчик не подозревал, что вместо MVC у него будет один экшн с «20-30 простейшими действиями» определяемых if\else
                                      0
                                      заказчкику пофиг — почти всегда — если он сам не программист и не собирается поддерживать код в дальнейшем. Не знаю насколько часто это в россии встречается -
                                      0
                                      освоение любого фреймворка дело непростое — это как еще одни язык зачастую.
                                      использую yii — а я вообще программист(ка) самоучка. И программирую в свободное от основной работы время.
                                      мне потребовался год! что бы разобраться — а что бы свободно использовать еще пол года. и подозреваю что до сих пор не использую и 50% возможностей фреймворка.
                                      И дело не в пороге вхождения — а в том что ты постоянно учишься.
                                      но сейчас я уверена — хотя мой код далек от идеала — приложения, написанные мной, относительно безопасные — и это благодаря YII
                                      +5
                                      if(@$_POST[‘action’] == done) {
                                         $dbi->exec(“UPDATE bug SET status=’done’ WHERE id=:bugId“, array(‘bugId’=>$bugid));
                                         $message = “Status changed to <b>Done</b>”
                                      }
                                      elseif(@$_POST[‘action’] == ‘delete’) {
                                      //  ….
                                      }
                                      //…. плюс еще 20-30 других простейших действий...
                                      

                                      Дальше читать не стал. Типичный говнокод.
                                        –1
                                        Да. Код «не по понятиям». Но в некоторых случаях он выгоднее чем полноценный MVC.
                                        Вопрос в том, какие цели вы проследуете: скорость написания, понятность, возможность последующего рефакторинга, многолойность приложения.

                                        К примеру, я не стану использовать MVC структуру для создания простого скрипта, который решает простенькую задачку и явно никогда не будет модифицироваться в дальнейшем.
                                        А если мне необходимо создать сложную распределенное приложения, на которым будет работать много разработчиков и организаций, то это разумеется будет MVC.

                                        Но иногда, гордые программисты считает, что если не-MVC, то даже разговаривать дальше западло :-)
                                          +2
                                          Дело не в гордости. Даже для вашего небольшого проекта MVC подошел бы лучше ветвления.
                                          Что мешало сделать наподобие:
                                          class Controller
                                          {
                                               public function actionDone()
                                               {
                                                    $dbi->exec(“UPDATE bug SET status=’done’ WHERE id=:bugId“, array(‘bugId’=>$bugid));
                                                    $message = “Status changed to <b>Done</b>”
                                               }
                                          
                                               public function actionDelete()
                                               {
                                                    //  ….
                                               }
                                          
                                               //…. плюс еще 20-30 других простейших действий...
                                          }
                                          

                                          И при необходимости замкнуть на одно представление. Дело не только в красоте кода, но и в удобности его поддержки.
                                          Просто непонятно, зачем в проекте ZF, если он не используется.
                                            +2
                                            Ваш пример тоже не корректен по MVC идеологии. SQL запрос надо вынести в модель. А создание сообщения и заворачивание в >B< значения «Done» надо отдать в представление, куда будет отдельно передаваться фраза, и отдельно новое значение статуса.
                                              +4
                                              В том-то и дело что тут возможны компромиссы на разном уровне, а не только «все или ничего».
                                                0
                                                Абсолютно согласен!
                                                –2
                                                SQL запрос надо вынести в модель.

                                                Покажите любое более-менее формальное определение MVC, где это утверждается. SQL-запрос не имеет отношения к бизнес-логике в общем случае (есть исключения типа phpmyadmin), а в модель выносится именно она.
                                                  +1
                                                  с какого перепугу то?
                                                  я про SQL в модели?
                                                  в этом коде конечно должна быть мадель bugs или типа того, но запрос то в любом случае в контроллере выполняется. ORM это или что то другое
                                                    0
                                                    Это вы серьезно?
                                                      0
                                                      А вы? Какова ответственность ваших моделей? Работа с данными предметной области или их хранение? Две ответственности? А почему бы не три (ещё и представление данных)? А четыре (взаимодействие с пользователем)?
                                                        0
                                                        Бизнес-логика. Только у нас с вами похоже разное видение того, что же такое бизнес-логика. Честно говоря мне кажется, что разное понимание того, что такое бизнес-логика и является одной из ключевых причин холиваров на тему MVC. Похоже, моё и ваше представление о роли модели в MVC и её ответственности сильно разнятся. А судя по этому комментарию для того чтобы вас переубедить, нужно чтобы кто-то являющийся авторитетом для вас и большей части IT специалистов, сказал\написал в формальном определении, что модель приложения и модель данных того же приложения (включая интерфейс позволяющий выполнять простейшие манипуляции с этой моделью данных, типа CRUD) — это не одно и тоже. Пока такого авторитетного, формального документа нет, наше с вами общение на тему — просто холивар. А я не люблю холивары
                                                          0
                                                          Похоже на то. Для меня бизнес-логика — это логика бизнеса, логика в терминах которой ставится задача перед исполнителем (который будущий пользователь системы, а не который разработчик). Ставят задачу перед бухгалтером выписать счёт-фатуру, а не создать запись в БД, он слов-то таких не может не знать, а разработчик волен создавать запись моделирующую счёт-фактуру хоть в БД, хоть в файлах, хоть в памяти хранить постоянно, лишь бы соответствовало требованиям по надежности, скорости, стоимости и т. п.

                                                          Для меня модель данных приложения не ограничивается моделью предметной области, но вот интерфейс хранения данных, манипулирования ими в хранилище в эту модель данных не входит, это отдельный слой приложения уровня контроллера, ни модели, ни представлению о нём знать не нужно. Совмещать его с моделью — усложнять связи в приложении, введение нескольких причин почему может изменятся код, описывающий модель.
                                                            0
                                                            Как то вы так витиевато изъясняетесь, что я не могу быть уверен, что понимаю вас правильно.
                                                            Как я понял для вас все это выглядит как то так:
                                                            «Ставят задачу перед бухгалтером выписать счёт-фатуру»…
                                                            Контроллер получает зарос…
                                                            Проверяет, скажем, права доступа на выполнение запрошенных действий…
                                                            Проверяет «правильность» всех полей (те берет на себя логику модели)…
                                                            Знает, что дальше делать с ними (те берет на себя логику модели)…
                                                            Вызывает метод модели — создать новую, пустую счёт-фатуру, который возвращает объект -счёт-фатуру (или даже сам создает новый объект — счёт-фатуру)…
                                                            Заполняет все поля этого объекта…
                                                            Вызывает метод сохранить (или сам выполняет запросы к базе сохраняя и создавая все что нужно)…
                                                            По результатам этого вызова делает что-то ещё\отдает в вид ответ…

                                                            Я вижу это так:
                                                            Контроллер получает зарос…
                                                            Проверяет права доступа на выполнение запрошенных действий…
                                                            Знает какой метод какой модели отвечает за обработку этого запроса…
                                                            Оформляет параметры запроса и грузит ресурсы необходимые для инициализации модели…
                                                            Инициализирует модель\Создает экземпляр модели (или как то так)
                                                            Вызывает метод модели — создать счёт-фатуру, со всеми нужными параметрами… А может и не со всеми…
                                                            Предает ответ модели в вид.
                                                              0
                                                              Для меня так:
                                                              — проверяет права доступа (обычно на уровне базового класса)
                                                              — создаёт объект модели, возможно передавая параметры в конструктор/фабрику
                                                              — заполняет поля, если конструктора недостаточно
                                                              — вызывает валидатор
                                                              — сохраняет объект в хранилище, если всё ок
                                                              — генерирует представление, передавая сам объект (или view model объект, которому объект передан в качестве параметра конструктора или сеттера), если не нужно что-то банальное типа «Счёт-фактура создана».

                                                              При этом при разработке контроллера мне нужно знать о модели только как создать и проинициализировать её объект (для запросов на изменении состояния — какой метод с какими параметрами вызвать).

                                                              Хранилище и валидатор могут быть жёстко статически привязаны к модели в своём коде, но чаще получают данные о правилах валидации в рантайме из конфигов или аннотаций, в том числе о правилах, анализирующих результат вызова произвольного метода валидируемого объекта, или правилах, вызывающих кастомные функции.
                                                +1
                                                Как вы своё решение покрыли тестами?

                                                Обычно фреймворки предлагают возможность генерации кода для таких тривиальных задач.
                                                Вы уверены, что написание вашего «решения» действительно быстрее, чем мелкие правки под себя сгенерированного контроллера?
                                                  0
                                                  Обычно фреймворки предлагают возможность генерации кода для таких тривиальных задач.
                                                  Никак. Если бы требовалась разработка через тестирование, пришлось бы делать все по MVC.

                                                  Вы уверены, что написание вашего «решения» действительно быстрее, чем мелкие правки под себя сгенерированного контроллера?
                                                  В зависимости от конкретной задачи. С накоплением опыта начинаешь чувствовать на этапе проектирования, какой из подходов лучше в данном месте.
                                                    +4
                                                    Никак. Если бы требовалась разработка через тестирование, пришлось бы делать все по MVC.

                                                    т.е. мало того что ваш код — именно то, от чего люди пытались избавиться, когда начали писать фреймворки, так вы еще и без понятия, работает ли он вообще?

                                                    В зависимости от конкретной задачи. С накоплением опыта начинаешь чувствовать на этапе проектирования, какой из подходов лучше в данном месте.

                                                    А почему вы решили в примерах вместо этих задач показать типичные use case для генераторов?
                                              0
                                              Оказалось, что Zend Framework не рассчитан на работу с shared хостингом, т.к. для запуска требует прописать в VirtualHost директорию отличную от корня вашего проекта. — да ладно. Я успешно запустил на шаред хостинге ZF + Doctrine. В VirtualHost конечно же ничего не прописывалось.
                                                –1
                                                Вы правы. Я же писал что запустить удалось. Просто он не будет работать прямо «из коробки».
                                                +4
                                                Zend Framework юзер врывается в тред.

                                                Статья полный бред, если хотите что-нибудь, простите, обосрать — делайте это тоньше.

                                                Ваш «код» в начале меня очень сильно удивил.
                                                Перечитайте пару книжек, поймите прелести ООП и возвращайтесь с новым постом.

                                                Если хотите деталей — обращайтесь.
                                                  +8
                                                  Бро, не переживай. Пока пишут такие статьи, у нас будет работа.
                                                    0
                                                    Я не переживаю, просто понедельник, устал… :D
                                                  +3
                                                  Простите, но я бы вас не взял на работу. В вашей статье говнокод и говнокодом погоняет. Я помню таких же, как и вы «не любителей готовых штук», видел я уже в index.php switch...case на 250(двести пятдесят!!111) условий.
                                                    –8
                                                    Простите, но я не ищу работу. Обычно работа ищет меня.
                                                    помню таких же, как и вы «не любителей готовых штук», видел я уже в index.php switch...case на 250(двести пятдесят!!111) условий.
                                                    Я не пишу в index.php switch...case на 250 условий, а также не поклоняюсь дьяволу. Но вы это уже видимо представили, просто увидев в тексте с десяток строчек специально утрированного кода.

                                                    А также я помню «крутых» специалистов по ООП и «готовым штукам», которые на решение задачи тратят несколько дней. А задача может быть полностью решена за пару часов.
                                                      +3
                                                      чтож вы его уртрировали-то до говнокода?
                                                        +3
                                                        Простите, а сколько времени и невров вы потом тратите на поддержку этого «решения за пару часов»? Самолет тоже можно собрать из бумаги за пару дней. Как на нем летать — вопрос другого порядка, правда?
                                                          0
                                                          Когда я делаю «решения за пару часов» я иду на это осознанно. Я всегда анализирую вероятность того, придется или не придется это решение поддерживать в дальнейшем, оцениваю сложность поддержки. Изредка прогнозы оказываются неверными, и тогда иногда приходится тратить нервы.

                                                          А вообще в последнем комменте я имел ввиду, что за свою практику наблюдал специалистов по ООП и «готовым штукам», которые вцелом работают гораздо менее производительно чем «любители решений за пару часов». И это включая дальшейшую поддержку.
                                                            +3
                                                            Все зависит от того, как вы эту «производительность» измеряете. Если в объеме кода, написанного в день, тогда вы действительно сильно быстрее любого программиста с серьезным опытом, включая меня. Если же мы начнем измерять объемы 100% рабочего, протестированного и расширяемого кода, который не стыдно передать другому разработчику, сравнение будет сильно не в вашу пользу. Всегда.
                                                              0
                                                              Есть 2 вида заказчиков:

                                                              1. Заказчики, которым нужен красивый код. Код должен иметь возможность расширяться до бесконечности. Релизы должны быть без багов. Сроки — нормальные. Финансирование — большое.

                                                              2. Заказчики, которым надо запустить проект в эксплуатацию завтра! Если будет немного подглючивать, не страшно, главное чтобы разработчик потом поправил. Сильное и постоянное развитие проекта — маловероятно. Финансы строго ограничены.

                                                              Если с заказчиком типа 2 пытаться работать по схеме 1, то вы его просто потеряете.

                                                              Если все ваши заказчики относятся к тип 1, то вы работаете в тепличных условия. Я вам завидую.
                                                                +2
                                                                ИМХО работать с заказчиками типа 2 (денег мало, сделайте что-нибудь, потом видно будет) — себе дороже. С такими принципиально не работаю, чтобы потом не было стыдно за решения «из говна и палок».
                                                                  +3
                                                                  Вы же должны понимать, что заказчики 2го типа существуют только потому, что есть «разработчики» вроде вас, которые соглашаются «запустить проект в эксплуатацию завтра» со «строго ограниченными финансами». Тепличные условия — это нормальный рынок, который вы сознательно обходите стороной по своему собственному решению.
                                                                    0
                                                                    Да, я иногда соглашаюсь «запустить проект в эксплуатацию завтра» если очень просят. Но обычно работаю где то посередине между типом 1 и 2.

                                                                    Знаете, иногда бывает трудно объяснить клиенту. Почему надо сделать проект дорого и медленно, вместо быстро не дорого, когда конечный результат почти одинаков. Частенько все умные и правильные объяснения заканчиваются фразой клиента "Понятно. Вы нас тупо на бабки разводите." И идут такие клиенты уже к истинным говнокодерам, студентам-любителям или к демпингующим индийцам.
                                                                      +1
                                                                      Знаете, иногда бывает трудно объяснить клиенту. Почему надо сделать проект дорого и медленно, вместо быстро не дорого.

                                                                      Вся проблема как раз в том, что у вас:
                                                                      результат почти одинаков.

                                                                      Если вы не можете писать качественно, значит вы просто не можете писать качественно. Поверьте, у меня есть достаточно большой опыт общения с различными клиентами, чтобы сказать — клиент всегд отличит качественное от некачественного.

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

                                                                      И идут такие клиенты уже к истинным говнокодерам, студентам-любителям или к демпингующим индийцам.

                                                                      То есть вы спасаете своих клиентов от говнокодеров, соглашаясь писать говнокод самостоятельно? В чем разница?
                                                                        0
                                                                        вы спасаете своих клиентов от говнокодеров, соглашаясь писать говнокод самостоятельно

                                                                        Разница в том, что я готов отступить от полного соответствия MVC там где это допустимо. Не более.

                                                                          0
                                                                          Исходя из написанного в статье, для меня ваше «не более» уже черезчур.
                                                            +3
                                                            В текущей организации, где я сейчас работаю был человек, который был примерно Вашего мнения (он любил оставлять подобные портянки в коде и писать свои велосипеды). Так как заказчик не понимал в коде ничего, а лишь видел, что все работает, то был доволен. Оно и логично. Заказчику главное чтоб работало. Но через месяца 4, при увеличении нагрузки в десяток раз начались лаги, все начало отваливаться. И самое умное что сделал этот горе разработчик после написания сотни костылей, которые не спасали — свинтить по-быстрому. В итоге сейчас мы переписываем проект фактически второй раз, а заказчик платит за него второй раз. Но сейчас мы пишем с MVC (и не потому что это круто. Просто так мы лучше контролируем код), покрываем тестами и документацией (хотя нам за это не доплачивают, но это экономит нам время). А вот про «работа находит меня» — Вы правы ) Заказчик видя 2 предложения выберет более дешевое, но только скупой платит дважды.
                                                              0
                                                              Значит или разработчик — был плохой.
                                                              Или до него не довели информацию о перспективах развития проекта.

                                                              А про «портянки». Я уже много раз пожалел о том что показал пример этого кода в статье. Дальше почти никто не читал, и все заранее решили, что я пропогантирую именно такой стиль кода. Жаль.
                                                                +1
                                                                Да, разработчик был плохой. А Вы, когда делаете проект, то всегда точно знаете, что посещаемость будет 30 человек и заказчик не захочет впилить сюда «вот такую фичу»? Какой-то сферический зказчик в вакууме. А суть в том, что получив такую портянку в коде (которую Вы именно пропагандируете, так как говорите, что MVC здесь не подходит по причине увеличения кода, а switch Вам просто не нравится) Вы не сможете ее поддерживать адекватно. Рано или поздно она разрастется до сотен строк кода, в которых даже Вы будете путаться. И тут Вы вспомните про MVC.
                                                          +5
                                                          Сам не люблю ZF (именно как фреймворк), но вот с выводами категорически не согласен.
                                                          1. Если у вас недостаточно опыта чтобы сделать сносный каркас для своего приложения. то возьмите какой-нибудь фреймворк попроще, благо несть им числа
                                                          2. Если вы вообще не умеете работать с MVC, но хотите прочувствовать эту идеологию аналогично
                                                          3. Если у вас нет хорошего представления об ООП и применении типичных патернов проектирования, то Zend Framwork покажет вам множество примеров. Там они использовали ООП везде где надо и не надо. Symfony 2 покажет больше примеров, а главное намного чаще они к месту
                                                          4. Так же Zend Framwork вполне сойдет, если вы делаете несложное приложение, работа которого больше сводится к извлечению данных из БД и выводу на экран. Например какие нибудь новостные порталы или каталоги продукции. Оверхид, Yii или symfony подойдут для этого куда лучше, если вообще оптимальным выбором не окажутся микрофреймворки

                                                          Мое мнение: ZF надо изучать, если: надо писать под ZF (требования работодателя или заказчика); хотите знать индустриальный стандарт; хотите расширить кругозор и знаете уже пару MVC-фреймворков хотя бы на уровне создания «бложика»; хотите ознакомиться как пишется индустриальный код. Начинать изучение ООП, «тру» архитектуры, MVC и других паттернов с ZF это способ погрязнуть в деталях и абстракциях, не уловив главного.

                                                          P.S. Всё вышесказанное к ZF 1.x относится, ZF 2 ещё не крутил.
                                                            +4
                                                            ZF 1.x был оч неплох для времени когда он появился (Лет 5 назад?). Болезней у него хватает — это тоже правда (Те же формы, реюз кода и многое другое). Однако:
                                                            1. Часть проблем решается вполне элегантно, просто надо было покопать/почитать другие ресурсы.
                                                            2. Если использовать ZF «промышленно», то он очень неплохо тюнингуется, что дает возможность создания набора своих библиотек.
                                                            3. Простота хороша, пока вы уверены на 150%, что логика останется прежней, хоть какую-то возможность кастомизации нужно закладывать (приведенные примеры простого кода расширяемы только в сторону еще большего говнокода и костылей).
                                                              –3
                                                              Уважаемый ТС, хочу поблагодарить вас за отличный топик, который ярко выделяется своей искренностью. Да, у вам там есть несколько спорных моментов, но тем не менее основная мысль ясна. Могу добавить, что ваши выводы схожи с теми, которые можно услышать в крупных кампаниях (уровня Яндекса, Mail.ru и так далее). Дабы подбодрить вас в виду нападок со стороны многих, скажу, что уважаемых ораторов, которые «не взяли бы вас на работу», самих бы не взяли в действительно сильную кампанию.
                                                                +3
                                                                А можно перенять и нам опыт «крупных кОмпаний»? На полном серьезе. Интересно почитать каких стандартов придерживаются в Яндексе, Mail.ru и так далее
                                                                  0
                                                                  1) Конференции 2) Личный опыт работы в двух крупных кОмпаниях :) 3) Знакомые

                                                                  Обратите внимание когда какой-нибудь mail.ru рассказывает про свой веб-сервер или про свою БД или Яндекс про свой мониторинг, обязательно найдутся хомячки с батхертом из зала, которые обязательно зададут вопрос «а зачем изобретать велосипед?».

                                                                  На текущем месте — Deutsche Bank политика партии примерно такая: прикладное программирование состоит из слишком частных решений, что бы пытаться применить какие-то универсальные компоненты.

                                                                  На предыдущем — HeadHunter как-то так: делаем все основательно, все что не нравится — переписываем, людей, которые могут осилить только стандарные решения на работу не берем.
                                                                +5
                                                                Где-то на 1/3 части текста статьи достаточно четко прогнозируются комментарии.

                                                                Уважаемый, tushev. Полностью (я подчеркиваю это) прочитал статью о вашем опыте использования ZF. Вам уже сделали и дельные замечания и, на мой взгляд, не очень, и даже неуместные, поэтому я скажу то, что я лично увидел в вашем тексте, так сказать, между строк:

                                                                — Вы замахнулись на достаточно серьезную тему (осознаете вы это или нет) путем выражения собственного мнения в тексте статьи. Не все могут понять мотивы, к тому же и вы сами, вполне вероятно, не достаточно лаконично через ваш личный опыт можете выразить свои домыслы, или проще говоря — ту совокупность мыслей и стремлений, которые вас сподвигли на написание статьи. Я это понимаю прекрасно, к тому же особенно ярко это подчеркивают ваши слова о ваших собственных решениях и наработках для аналогичных задач.

                                                                — С вашей позиции вы совершенно правы, кто бы что вам ни говорил. Дело в том, что ваше мнение полностью основано на очевидных для вас решениях, т.е. вы искренне видите те или иные конструкции проще нагляднее и эффективнее, чем те, которые формировались при написании ZF для стандартизации разработки средних и крупных проектов с критерием на долгосрочную поддержку. Сейчас я вижу в вас, уж простите мне мою нескромность, эдакого бунтаря, который позволил себе взглянуть по-своему на «стандартизированные решения», подвергнув их личной критике. Это похвально. Вы импровизируете с собственной логикой и собственным восприятием — это говорит о том, что вы развиваетесь. Разница лишь в том, что вы импровизируете и не формируете стандарты, для вас ваши решения, как я уже говорил, наиболее оптимальны. Не обманывайтесь общественным мнением, разница исключительно в подходах.

                                                                — Как я уже говорил вопрос достаточно сложный. Когда мы решаем задачу по принципу «необходимости и достаточности», программный код минималистичен, он не обладает избыточностью и крайне высоким уровнем абстракции, он строго подходит под типичную задачу. Это хорошо. Но если пытаться унифицировать решения при этом внедряя какие-либо разработанные стандарты и критерии разработки масштабных проектов, неизбежно начнут возникать ситуации повышения уровня абстракции как логики в частности, так и архитектуры в целом.

                                                                Чем жестче правила, тем «правильнее код», без импровизаций (читайте «велосипедов»). Стандарты нужны, они необходимы. Вопрос лишь в том, что если вы работаете сами, если вы не нуждаетесь в том, чтобы передавать ваши труды кому-то еще, кто с трудом усвоит чуждые общепринятым стандартам принципы разработки, то ваш код окажется «поделкой сомнительного качества» в глазах того, кто принимает эстафету. Важно понять, что разница не в том, что кто-то прав, а кто-то нет. Ваши маленькие решения действительно могут быть многократно проще и доступнее стороннему наблюдателю, но я почему-то склонен считать, что эти решения априори не являются частью чего-то большего, чего-то грандиозного, о чем вы скромно умолчали в статье, т.к. для решения ваших задач более абстрактные подходы избыточны. Помните об этом и не останавливайтесь ни в коем случае, экспериментируйте с подходами и решениями, делайте не так как все, будьте индивидуальны в своих проявлениях, improveзируйте! Для вас лично — это бесценный опыт, ни одна книга, ни один FW, и никто в принципе не смогут дать вам то, что вы можете осознать сами в процессе.

                                                                P.S. Вы молодец! Не принимайте критику близко к сердцу. Мне понравилась статья вашей искренностью и некоторой неловкостью перед публикой. Не смущайтесь замечаниям, люди не рождаются со знаниями, люди приобретают их в течение жизни.
                                                                  0
                                                                  Краткое содержание статьи для тех кто неосилил:
                                                                  Нуб, говнокодящий сайты-однодневки жалуется на то, что ZF для него слишком сложен и не понятен.

                                                                  Совет автору:
                                                                  Говнокодте спокойно свои 30 сайтов в месяц и не парьтесь. А серьёзные проекты и не менее серьёзные технологии вроде ZF оставьте взрослым дядям, они не для вас.

                                                                    0
                                                                    >Я не хочу дорабатывать паровоз до самолета напильником. Я хочу чтобы все сносно работало прямо “из коробки”

                                                                    Я посмотрю на вас когда к вам внезапно придет 50к пользователей.
                                                                      0
                                                                      Насчет построения древовидной карты моделей.

                                                                      Мне кажется данный функционал можно реализовать через зависимости framework.zend.com/manual/ru/zend.db.table.relationships.html
                                                                        0
                                                                        Прочел с большим интересом вашу статью. В качестве резюме могу сказать, что первые месяца 4 знакомства с ZF 1 я наступил на все вышеописанные грабли и получил массу неприятных впечатлений от работы.
                                                                        В ZF есть только один серьезный недостаток — высокий порог вхождения. Для того, чтобы действительно эффективно его использовать, придется покопаться в коде фреймворка и разобраться во всем. За то потом работа с ним — это сплошной кайф.
                                                                        Во втором ZF немного иная парадигма. Кстати, говорят, там в бандлах есть уже готовые разнообразные решения для скаффолдинга и прочих кайфов типа тех, что есть в ROR.
                                                                          0
                                                                          Вы по всей вероятности не до конца разобрались с этим инструментов
                                                                          в Zend_DB вполне себе есть метод fetchPairs(), который вернет именно то что вам надо, для этого вам всего лишь надо указать два поля. Первым будет ключ вторым значение.
                                                                          С формами у них конечно не все интуитивно, но ваши претензии опять же далеки от истинности. Первое, вы сами можете указывать текст выводимой ошибки при задании валидатора. Более того можете использовать либо встроенный переводчик для ошибок либо использовать свой адаптер. И с ошибками, вы можете указать один текст ошибки для всех валидаторов поля.
                                                                          По всей видимости вы просто немного не «дотерпели» в изучении. Возможно это можно записать в минусы фрэймворку что на первоначальном этапе он кажется крайне запутанным и сложным.
                                                                            0
                                                                            Да, fetchPairs() возвращает именно ключ -> значение.
                                                                            А я хотел ключ->запись. Ну типа того:
                                                                            array(
                                                                               7 => array('name'=>'Andrey', 'age'=>25),
                                                                               8 => array('name'=>'Helena', 'age'=>19),
                                                                            )
                                                                            
                                                                            0
                                                                            function renderTemplate($file, $vars) {
                                                                                foreach($vars as $_name => $_var) {
                                                                                    $$_name = $_var;        
                                                                                }
                                                                                require $file;
                                                                            }
                                                                            

                                                                            Т.к. вы указали, что любите лаконичность, то хочется посоветовать extract.

                                                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                            Самое читаемое