Комментарии 22
Чертовски много лишних телодвижений.
+7
Это вы о конкретно этом примере или о Zend-фреймворке в целом?
+1
После symfony 1.4 я вообще не могу понять курс современных фреймворков: что zf2, что sf2 — столько всего приходится писать руками, что, порой, задумываешься: «а надо ли вообще всё это?»
+2
Суть статьи — показать пример разработки готового модуля, а не написать полноценный блог.
Как опытный разработчик, вы должны понимать, что с ростом функциональности системы и объема кода она (система) становиться неуправляемой. При должной структуризации кода этот момент откладывается (почти) на неопределенное время, вполне возможно до конца актуальности самой системы.
Простой блог как в статье, на чистом PHP, где код написан в хардкорном стиле «здесь и сейчас» можно вложится в несколько экранов, но сопровождение кода в гораздо сложных проектах будет излишне дорого для бизнеса.
Курс современных фреймворков состоит в понижении сопряжения компонентов, из чего следует минимизация сложности, снижение количества ошибок, уже далее простота разработки и сопровождения ПО.
Поэтому ответ на ваш (может быть риторический) вопрос: да, надо. Но прежде всего нужно помнить: для каждой задачи должен быть осознанно применен свой инструмент.
Как опытный разработчик, вы должны понимать, что с ростом функциональности системы и объема кода она (система) становиться неуправляемой. При должной структуризации кода этот момент откладывается (почти) на неопределенное время, вполне возможно до конца актуальности самой системы.
Простой блог как в статье, на чистом PHP, где код написан в хардкорном стиле «здесь и сейчас» можно вложится в несколько экранов, но сопровождение кода в гораздо сложных проектах будет излишне дорого для бизнеса.
Курс современных фреймворков состоит в понижении сопряжения компонентов, из чего следует минимизация сложности, снижение количества ошибок, уже далее простота разработки и сопровождения ПО.
Поэтому ответ на ваш (может быть риторический) вопрос: да, надо. Но прежде всего нужно помнить: для каждой задачи должен быть осознанно применен свой инструмент.
0
Чего? Вы комментарий мой точно читали? А про symfony 1 что-нибудь слышали? Каким боком моё высказывание коррелирует с тем, что я не признаю и не понимаю назначение фреймворков?
Я где-то говорил о том, что кода слишком много? Я просто свято верю в то, что кодогенерация решает проблемы (особенно, крупных проектов).
В симфони 1.4 то, что вы написали на несколько экранов заключается в следующих действиях:
— описать (декларативно) схему модели
— сгенерировать модели, формы, фильтры, админку, роуты и sql несколькими консольными тасками
При этом, получившийся продукт не будет ни в чём уступать Вашему (в плане кастомизации или абстрактности), но ручного ввода текста (довольно подверженного ошибкам, к слову) будет в несколько раз меньше.
Вообще, если бы Вы внимательно прочли мой вопрос, то могли бы его свести к «где скаффолдинг? Неужели, этот код не мог сгенерировать компьютер?»
Я где-то говорил о том, что кода слишком много? Я просто свято верю в то, что кодогенерация решает проблемы (особенно, крупных проектов).
В симфони 1.4 то, что вы написали на несколько экранов заключается в следующих действиях:
— описать (декларативно) схему модели
— сгенерировать модели, формы, фильтры, админку, роуты и sql несколькими консольными тасками
При этом, получившийся продукт не будет ни в чём уступать Вашему (в плане кастомизации или абстрактности), но ручного ввода текста (довольно подверженного ошибкам, к слову) будет в несколько раз меньше.
Вообще, если бы Вы внимательно прочли мой вопрос, то могли бы его свести к «где скаффолдинг? Неужели, этот код не мог сгенерировать компьютер?»
0
а что, в sf1 сильно лучше скаффолдинг чем стоковая кодогенерация через SensioGeneratorBundle и sonata admin во второй симфони?
0
Вас интересовал курс современных фреймворков — я описал свое мнение. Прямых утверждений касательно ваших взглядов в моем комментарии нет, к чему негатив?
Кодогенерация как и в первых версия была, так и во вторых есть. Если вас интересует тема скаффолдинга в ZF2, увы, статья не про это.
А Ваш продукт на симфони 1.4 будет все же уступать аналогичному на sf2, как и продукт на zf1 будет уступать продукту на zf2 по причинам описанных мною выше.
Кодогенерация как и в первых версия была, так и во вторых есть. Если вас интересует тема скаффолдинга в ZF2, увы, статья не про это.
А Ваш продукт на симфони 1.4 будет все же уступать аналогичному на sf2, как и продукт на zf1 будет уступать продукту на zf2 по причинам описанных мною выше.
0
Соглашусь, пост читать тяжеловато, хотя тема интересная и полезная. Попробуйте куски кода убрать в раскрывающийся блок, тогда пост по размеру уменьшится на 30-50%. Так же читать просто порядок действий не очень интересно, можно сравнить, как это делается в других фреймворках и ваше субъективное мнение о том, что тут происходит и можно было бы это как то улучшить или вообще не использовать.
0
Вообще, цель статьи не в том, чтобы сравнить Zend с другими фреймворками, а в том, чтобы дать разработчикам, начинающим работать с фреймворком, ответы на вопросы: что такое ServiceManager, как работать с формами, БД и т.п. Соглашусь, читать лучше на свежую голову, но текста примерно с такой структурой мне не хватало когда я начал свое знакомство с этим фреймворком.
+1
1) Зачем в каждом экшене делать
В зенд же есть хуки перед вызовом экшена?
2) Почему в мире php не принято следовать REST? Ведь очень некрасиво выглядят эти постоянные проверки на то, что запрос POST?
3)
Разве это нельзя сделать в хуках доктрины prePersist?
4)
что это за магия?
5)
можно переписать как
Проверка на существование id не имеет особого смысла, обычно это просто 404 страница. Юзер не должен руками править урл.
6) EntityManager не кидает эксепшн, просто возвращает null. docs.doctrine-project.org/en/2.0.x/reference/working-with-objects.html#querying, если не найдена запись.
7)
Что за магическая 1?
$objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
?В зенд же есть хуки перед вызовом экшена?
2) Почему в мире php не принято следовать REST? Ведь очень некрасиво выглядят эти постоянные проверки на то, что запрос POST?
3)
$blogpost->setCreated(time());
Разве это нельзя сделать в хуках доктрины prePersist?
4)
$blogpost->setUserId(0);
что это за магия?
5)
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
$this->flashMessenger()->addErrorMessage('Blogpost id doesn\'t set');
return $this->redirect()->toRoute('blog');
}
$objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$post = $objectManager
->getRepository('\MyBlog\Entity\BlogPost')
->findOneBy(array('id' => $id));
if (!$post) {
$this->flashMessenger()->addErrorMessage(sprintf('Blogpost with id %s doesn\'t exists', $id));
return $this->redirect()->toRoute('blog');
}
можно переписать как
$objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$post = $objectManager
->getRepository('\MyBlog\Entity\BlogPost')
->findOneBy(array('id' => $id));
if (!$post) {
$this->flashMessenger()->addErrorMessage(sprintf('Blogpost with id %s doesn\'t exists', $id));
return $this->redirect()->toRoute('blog');
}
Проверка на существование id не имеет особого смысла, обычно это просто 404 страница. Юзер не должен руками править урл.
6) EntityManager не кидает эксепшн, просто возвращает null. docs.doctrine-project.org/en/2.0.x/reference/working-with-objects.html#querying, если не найдена запись.
7)
$posts = $objectManager
->getRepository('\MyBlog\Entity\BlogPost')
->findBy(array('state' => 1), array('created' => 'DESC'));
Что за магическая 1?
+1
1) Зачем в каждом экшене делать?.. В зенд же есть хуки перед вызовом экшена?
3) Разве это нельзя сделать в хуках доктрины prePersist?
Не готов ответить на вопросы, попробую изучить его и переделать этот кусок.
2) Почему в мире php не принято следовать REST? Ведь очень некрасиво выглядят эти постоянные проверки на то, что запрос POST?
Наверняка это возможно, изучу этот вопрос и переделаю этот кусок кода.
4) что это за магия?
Пока в проекте нет работы с пользователями, по этому тут хардкодится ноль, в третьей части я прикручу юзеров и эта строчка будет заменена на айдишник текущего пользователя.
7) Что за магическая 1?
Это статус. 0 — не опубликовано, 1 — опубликовано. У вас есть предложение как убрать эту магическую константу?
3) Разве это нельзя сделать в хуках доктрины prePersist?
Не готов ответить на вопросы, попробую изучить его и переделать этот кусок.
2) Почему в мире php не принято следовать REST? Ведь очень некрасиво выглядят эти постоянные проверки на то, что запрос POST?
Наверняка это возможно, изучу этот вопрос и переделаю этот кусок кода.
4) что это за магия?
Пока в проекте нет работы с пользователями, по этому тут хардкодится ноль, в третьей части я прикручу юзеров и эта строчка будет заменена на айдишник текущего пользователя.
7) Что за магическая 1?
Это статус. 0 — не опубликовано, 1 — опубликовано. У вас есть предложение как убрать эту магическую константу?
0
4) можно было пока вообще не думать о юзере, а добавить его в дальнейшем потому, что магический ноль смущает.
7)
Вообще, тут неплохо было бы вынести это в класс-репозиторий для BlogPost, чтобы было вроде:
7)
//class BlogPost
const PUBLISHED = 1;
const NOT_PUBLISHED = 0;
...
$posts = $objectManager
->getRepository('\MyBlog\Entity\BlogPost')
->findBy(array('state' => BlogPost::PUBLISHED), array('created' => 'DESC'));
Вообще, тут неплохо было бы вынести это в класс-репозиторий для BlogPost, чтобы было вроде:
$posts = $objectManager
->getRepository('\MyBlog\Entity\BlogPost')
->findPublished();
0
Привет старым друпалерам :)
не знаю как в zf, а в symfony2 в твиге очень даже возможно вывести сообщения без дополнительных плагинов:
symfony.com/doc/2.1/book/controller.html#flash-messages
Проблема в том, что неудобно (а в Twig-шаблонах, которые мы будем использовать позже, и вовсе невозможно) вызывать PHP-код для вывода сообщений. По этому мы напишем небольшой View-плагин, который сможет одной строчкой выводить на экран все сообщения.
не знаю как в zf, а в symfony2 в твиге очень даже возможно вывести сообщения без дополнительных плагинов:
{% for flashMessage in app.session.flashbag.get('notice') %}
<div class="flash-notice">
{{ flashMessage }}
</div>
{% endfor %}
symfony.com/doc/2.1/book/controller.html#flash-messages
0
Привет, Антон :)
Проверил, вот такая конструкция в Твиг шаблоне работает:
Но вариант с view-плагином мне все же нравится больше:
Проверил, вот такая конструкция в Твиг шаблоне работает:
{% for flashMessage in flashMessenger().getMessages() %}
<div class="flash-notice"> {{ flashMessage }} </div>
{% endfor %}
Но вариант с view-плагином мне все же нравится больше:
{{ showMessages() }}
0
Нервным не читать
У себя в проектах в скелет страницы вставляю шаблон
знаю что *овнокод, но работает и ладно.
В коде достаточно сделать так:
или так:
<span id="top-of-container">
{% if flash_error %}
{% include 'snippets/alert.danger.html.twig' %}
{% endif %}
{% if flash_warning %}
{% include 'snippets/alert.warning.html.twig' %}
{% endif %}
{% if flash_success %}
{% include 'snippets/alert.success.html.twig' %}
{% endif %}
{% if flash_console %}
<script type="text/javascript">
{% for flash in flash_console %}
console.info({{ flash|json_encode|raw }});
{% endfor %}
</script>
{% endif %}
</span>
знаю что *овнокод, но работает и ладно.
В коде достаточно сделать так:
ТО_ЧТО_УХОДИТ_В_ШАБЛОН_ТВИГА['flash_error'] = 'F*CK';
или так:
ТО_ЧТО_УХОДИТ_В_ШАБЛОН_ТВИГА['flash_error'][] = 'F*CK';
0
$blogpost->setCreated(time());Для этого есть Timestampable из DoctrineExtensions.
Конфиги в виде многомерного массива подбешивают, ну есть же yaml/xml, не удобно ведь такие конфиги использовать…
0
Николай, я правильно из вашего комментария понял, что в Zend'е при помощи классов Zend\Config\Reader можно не только читать настройки своих кастомных модулей, но и прикрутить как замену application.config.php, *global.php, *local.php и конфигов модулей?
0
zend-developer-tools можно и нужно использовать на проде, если нет нормального мониторинга (пинбы например).
Для этого достаточно сделать другую среду(набор конфигов, в котором будет zdt) и в public создать еще один скрипт, на который завернуть поддомен с http-авторизацией или доступ по офисному(домашнему) ip (ex. Zend\Mvc\Application::init(require_once 'config/app/dev.config.php')->run();)
Для этого достаточно сделать другую среду(набор конфигов, в котором будет zdt) и в public создать еще один скрипт, на который завернуть поддомен с http-авторизацией или доступ по офисному(домашнему) ip (ex. Zend\Mvc\Application::init(require_once 'config/app/dev.config.php')->run();)
0
Не используйте плз вызовы классов через глобальное пространство имен ($form = new \MyBlog\Form\BlogPostForm())
Сделайте импорт перед объявлением кода класса (use MyBlog\Form\BlogPostForm) и уже в коде класса используйте плз $form = new BlogPostForm().
Сделайте импорт перед объявлением кода класса (use MyBlog\Form\BlogPostForm) и уже в коде класса используйте плз $form = new BlogPostForm().
0
<?php
print $this->showMessages();
print '<h1>' . $post['title'] . '</h1>';
print '<div>' . $post['text'] . '</div>';
Что это? То есть либо twig, либо такая жесть?)
<?= $this->showMessage(); ?>
<h1><?= $post['title']; ?></h1>
<div><?= $post['text']; ?></div>
Поправьте плз, это же люди читают…
0
Не понимаю, что это у автора. Жесткая нехватка времени или лютое нежелание ответить кому-либо в лс? Раз 5 писал в ЛС, но человек не слышит.
Пока делал, наступил на грабли. В коде нужно кое-что поправить:
Когда мы создаем форму мы создаем поле с name = security:
В итоге страница перезагружалась, но форма не отправлялась, так как не проходила валидацию. Сообщение об ошибке удалось получить только после танцев с бубнами. В итоге поправил view, добавив:
Теперь все работает так, как нужно.
Пока делал, наступил на грабли. В коде нужно кое-что поправить:
Когда мы создаем форму мы создаем поле с name = security:
Кроме того, я добавил к форме Csrf-токен (поле security), который должен защитить форму от подделки.. В представлении нужном, это поле не выводится.
В итоге страница перезагружалась, но форма не отправлялась, так как не проходила валидацию. Сообщение об ошибке удалось получить только после танцев с бубнами. В итоге поправил view, добавив:
echo $this->formRow($form->get('security'));
Теперь все работает так, как нужно.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Пример разработки блога на Zend Framework 2. Часть 2. Модуль MyBlog