Введение
Я уже писал подобную статью, но она была очень не полной и не снабженной примерами, поэтому я решил взять вторую попытку и попытаться раскрыть данный вопрос наиболее полно!
В данной статье, не будут рассматриваться все тонкости разработки на фреймворках, поскольку это не возможно уложить в рамках одной статьи. Однако, можно достаточно подробно разъяснить те нюансы, которые помогут в выборе для изучения или реализации конкретного проекта. Сравнивать будет Yii2 и Laravel. Я понимаю, что это достаточно холиварная тема, результат которой обычно гласит, что каждый хорош по своему. Я, как человек работавший с обеими, попробую разъяснить свой подход к выбору фреймворка, и постараюсь наиболее объективно показать их минусы и плюсы.
Сразу предупрежу вопрос о том, почему не рассматриваем Symfony.
Дело в том, что Symfony более низкоуровневый фреймворк, который чаще берут для основы в крупных проектах, например таких, как написание собственного фреймворка для разработки. Его в принципе нельзя сравнивать с Laravel и Yii2, так как они используют его компоненты в своих реализациях. Symfony — это очень мощный продукт, позволяющий гибко настраивать практически любую систему под потребности, но в нем мало чего можно использовать в качестве готовых решений для мелких типовых задачек. На GitHub можно встретить множество библиотек или расширений написанных для того же Yii2 или Laravel как раз на Symfony.
Yii2
Начнем с Yii2, так как это мой первый фреймворк, который я изучил. Надо сказать, что изучается данный фреймворк очень легко, при минимальных знаниях ООП.
Плюсы
- Легко изучается, низкий старт разработки
- Имеет множество встроенных решений для интерфейсов
- Отличный генератор моделей, контроллеров И CRUD
Минусы
- Не очень гибкое формирование роутов
- Плохо развивается (выход новых версий)
- Слишком склеенные библиотеки для frontend'а с backend'ом
Теперь расскажу о каждом более подробно. Последний из минусов вообще мне кажется не понятным на первый взгляд, но я не знаю как сказать по другому, чуть ниже подробно объясню, что я имел ввиду.
Легко изучается. Фреймворк действительно легко изучается, и посидев день два, над небольшим проектом, вы уже начинаете спокойно кодить на нем. Для начала изучения маловато хорошей литературы на русском языке, но это хорошо компенсируется благодаря хорошему справочнику на английском. В крайнем случае Google-переводчик. Сейчас обрадую, так было раньше. Совсем недавно, они обновили свой сайт с гайдами и документацией, и теперь есть гайды на русском языке, находятся они здесь. Информация по API пока не переведена, но там ничего сложного. Даже с небольшими знаниями технического английского, все довольно просто, поскольку там просто описываются методы, что они принимают, отдают и что вообще делают, информация тут.
Встроенные решения для интерфейсов можно описывать целой небольшой книжкой, но я постараюсь кратко. В систему встроен Bootstrap, к сожалению пока третий, и кучка собственных модулей, которые с ним связаны.
Можно даже плохо владеть версткой на bootstrap, и при этом с помощью встроенных в Yii2 методов сделать всплывающие модальные диалоги, окошки, выпадающие списки, спойлеры и т.д.
Вот небольшой пример, который можно встретить на целой куче сайтов, и даже в официальной документации Yii2:
Пример модального окна
use yii\bootstrap\Modal;
Modal::begin([
'header' => '<h2>Hello world</h2>',
'toggleButton' => ['label' => 'click me'],
'footer' => 'Низ окна',
]);
echo 'Say hello...';
Modal::end();
Данный пример как раз создает модальное окно, с заголовком <h2>Hello world</h2>, кнопкой click me, которая открывает этот дилог, с телом «Say hello...» и футером «Низ окна».
Не нужно писать всякие там 'data-target="#id-modal"' или подобное, система расставит все это сама. Такие вещи в Yii2 — называются виджетами, которые может делать вообще любой программист, и тащить любой фронтенд на свою backend — сторону. Но это на самом деле и минус, самый последний о котором я говорил выше. Почему это минус разберем чуть позже, пока об удобстве этого всего.
Любой подобный виджет может вызываться как обычный класс со статическим методом, принимать параметры, от которых будет что-то зависеть в виджете и закрываться. Есть еще способы реализации виджетов, которые не требуется открывать и закрывать, они сами это сделают, им нужно только передать параметры, от которых будет что-то зависеть, приведу пример из сторонней библиотеки
Пример стороннего виджета
// Multiple select without model
echo Select2::widget([
'name' => 'state_2',
'value' => '',
'data' => $data,
'options' => ['multiple' => true, 'placeholder' => 'Select states ...']
]);
Это пример из библиотеки, позволяющей вызывать в представлениях виджет Select2, от kartik-v, ссылка на GitHub.
Вот такой виджет подключает все скрипты, размечает input и select и обрабатывает их библиотекой Select2.
В общем, с помощью таких вот решений, которые уже кто-то написал, или вы напишите сами, можно складывать представления сразу с интерфейсом и это позволяет разрабатывать очень быстро.
Генератор моделей, котроллеров и представлений — это отдельная вещь, но связана с предыдущей частично. В Yii2, есть некая GUI область, для выбора различных генераций. Обратите внимание, у других фреймов, если и есть генераторы, то, как правило, только консольные. Здесь есть и интерфейс и очень удобно пользоваться, называется эта прелесть gii.
Вот как она выглядит: ![image](https://habrastorage.org/r/w1560/webt/ck/bz/ev/ckbzev0gybyvlonqdhdqclhyy88.png)
![image](https://habrastorage.org/webt/ck/bz/ev/ckbzev0gybyvlonqdhdqclhyy88.png)
На картике видно что она может. Генератор моделей и CRUD самые частопригождающиеся вещи в ней. Модели генерируются не как в laravel, в интерфейсе указывается таблица, название и расположение класса для модели, с учетом пространства имен, программа сама подтягивает все зависимости (можно отключить, если не нужны), если расставлены foreign key, и «выкатывает» модель, со всеми свойствами взятыми по колонкам таблицы и методами для связки с другими, если они есть.
Признаюсь честно, такого генератора, я больше не видел нигде.
CRUD генерирует готовые интерфейсы, контроллеры к ним, для управлениями данных в указанной ему модели. Т.е. Сначала нужно создать модель, а потом делать CRUD генерацию. На выходе, вы получите сразу готовый интерфейс с определенным адресом, в котором можно заводить новые записи таблицы, редактировать и удалять их.
Очень удобно использовать для создания панелей администраторов или каких-нибудь дашбордов. Быстро генерируется готовый интерфейс, который потом можно отредактировать, и пользоваться, назначив защиту роутам путем авторизации или иначе. Сам интерфейс использует множество встроенных виджетов для этого, которые тоже можно перенастраивать по своему усмотрению. Это действительно быстрая разработка систем с интерфейсами управления данных. Можно достаточно быстро сделать дельную CMS для нужд конкретного проекта. Мое мнение, что это, самый главный плюс Yii2 в сравнении с другими фреймворками.
Теперь поговорим о минусах. О них достаточно коротко, чтобы не раздувать статью до небывалых размеров.
Не очень гибкое формирование роутов. В контроллерах классов для Yii роуты указываются следующим образом:
Пример создания маршрута в контроллере
/*----*/
/**
* Your Annotation
* @return mixed
*/
public function actionIndex()
{
return $this->render('index', []);
}
/*----*/
Любой путь в контроллере должен начинаться со слова action и с заглавной буквы указывается его адрес, например Index. Если написать из двух слов, например actionArticlesList, то путь получится следующий: /название_контроллера/articles-list. Если нам нужно как то по своему организовать формирование роутов, есть два способа:
- Задать правила в конфиге
- Написать свой класс для конкретной группы роутов, и указать его в конфиге.
Подробно останавливаться на конфиге не буду, но выглядит это примерно так:
[
/*---*/
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'<module:\w+>/<controller:\w+>/<action:(\w|-)+>' => '<module>/<controller>/<action>',
'<module:\w+>/<controller:\w+>/<action:(\w|-)+>/<id:\d+>' => '<module>/<controller>/<action>',
],
],
/*---*/
]
В rules, как раз указываются правила. Там и можно указать свой класс, или придумать свое выражение для роута, об этом можно почитать более подробно в официальной документации.
Второй пункт минусов, думаю пояснять особо не стоит. Следует обратить внимание, что Yii2 до сих пор использует bootstrap-3, и нового за последнее время в нем прибавилось достаточно мало.
Ну и последний пункт, который я обещал пояснить — это слишком большую склеенность фронтенда с бекендом. Как и писал выше, множество виджетов и других решений, сразу делают генерацию готовых решений в представлениях (views). Это хорошо и быстро, но многие из них, выбрасывают скрипты прямо в тело страницы, в коде этих виджетов перемешан php и html, что не очень хорошо выглядит и достаточно проблематично поддерживать такой код.
Такой метод разработки не позволяет пользоваться сборщиками типа WebPack, Gulp или другими. Точнее пользоваться можно, но придется отказаться от основного преимущества Yii2 — не пользоваться генераторами и готовыми решениями для интерфейса. Не использовать классы, которые позволяют собирать скрипты и css в assets и тому подобные сложности.
В современной разработке все идет к тому, чтобы как можно дальше отделить frontend от backend, и в этом плане Yii2 устаревает. Надеюсь этот минус достаточно понятен.
Laravel
Поскольку мы достаточно подробно познакомились с Yii2, здесь можно привести плюсы и минусы для сравнения с предыдущим фреймворком Yii2
Плюсы
- Имеет встроенный сборщик скриптов и scss
- Встроенный шаблонизатор Blade
- Очень гибкое формирование Роутов
- Очень гибкие возможности для написания REST API
- Быстро развивается
Минусы
- Большой функционал работает через фасады и IDE-системы не видят методов и свойств в некоторых классах, показывая предупреждения
- Изучается немного сложнее Yii2
- Нет официальной документации на русском языке
- Нет встроенных генераторов интерфейсов
Встроенный сборщик основан на WebPack, по сути это надстройка над ним, которая позволяет легко начать работу, и собирать frontend не копаясь в тучных мануалах по WebPack и его настройке.
В системе он зовется laravel mix, и это по сути WebPack, уже настроенный под большинсво задач, где мы просто указываем откуда берем исходники, и куда ложим результат.
Пример mix'a
let mix = require('laravel-mix');
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
В примере стандартная конфигурация, которая у вас появляется сразу после инсталляции фреймворка. Таких миксов там можно создавать сколько угодно много, если у вас есть разделение нескольких frontend приложений.
В примере стандартная конфигурация, которая у вас появляется сразу после инсталляции фреймворка. Таких миксов там можно создавать сколько угодно много, если у вас есть разделение нескольких frontend приложений.
Микс сразу умеет собирать scss, однофайловые компоненты Vue, а так же в новых версиях Laravel, Vue.js идет сразу в поставке фреймворка.
Шаблонизатор Blade, чем то сильно напоминает Twig, но синтаксис и принцип работы немного другой. Какой из них лучше не знаю, но я пока не столкнулся с такими задачами, которые можно реализовать на Twig и нельзя реализовать на Blade. Едиснтвенный минус Blade, который я пока вижу, это то, что Twig известен многим, а Blade только разработчикам Laravel.
Очень гибкое формирование роутов. Механизм очень похож на symfony, только вместо аннотаций, используется отдельный файл и фасадный класс Route, с набором статических методов.
Плюс по сравнению с Yii2 в том, что в контроллерах методы могут называться как угодно, и сами роуты тоже. Мы пишем их в отдельной дирректории, и указываем текущий роут, какого он типа-запроса (POST, GET и т.д.), и указываем на какой он идет контроллер и метод в контроллере. Так же можно задать имя, для вывода по нему ссылки через шаблонизатор Blade.
Пример назначения роутов
/*---*/
Route::get('/dashboard/newsList', 'DashboardController@newsList')->name('dashboard/newsList'); //Запрос GET, его адрес, вторым параметром указывает на контроллер и метод
Route::middleware('auth')->delete('/dashboard/newsList/news/{uuid}', 'APINewsController@DeleteNews'); //Запрос DELETE, требующий авторизации, передающий последним параметром в URL uuid, И направленный на соответствующий контроллер и метод.
/*---*/
В роутинге удобно использовать middleware, которые перед тем как отправить запрос на обработку контроллера могу проверить какие-то данные и в зависимости от них отправить контроллеру на обработку или нет. Одним из таких проверок может быть авторизация пользователя в системе. Причем сами middleware можно использовать как в контроллере, так и при объявлении маршрута в routes.
Система получается очень гибкая. Можно на один маршрут, в зависимости от метода передачи HTTP-запроса назначить разные обработчики одного контроллера.
Я не указал об этом в Yii2, но там тоже есть система управления такими запросами, но как и все другие роуты, настраивается или через собственный класс или через конфиг, что не всегда удобно. В Yii2 есть yii\rest\ActiveController — который позволяет быстро настройить REST FULL API, но он тоже не так гибок, как хотелось бы.
Благодаря такой системе роутов, я бы выбрал именно Laravel для построения проекта работающего на REST API. Таким образом, в данном пункте я ответил и на следующий плюс «Очень гибкие возможности для написания REST API»
Laravel очень быстро развивается. Постоянно выходят новые версии, которые исправляют ошибки и недоработки предыдущих, быстро повышая эффективность фреймворка. Он наверное самый быстроразвивающийся фреймворк из тех, что я знаю.
Переходим к минусам.
Работа через фасады, большинства обширных классов Laravel. Такое сложное предложение, я поясню! Дело в том, что во многих классах фреймворка используется динамическое создание свойств и методов, в зависимости от каких-то условий.
Проще привести пример. Мы объявляем класс модели работы с базой данных, которая является расширением стандартного класса Illuminate\Database\Eloquent\Model, в котором нет статических методов where, select и т.п., но на самом деле они есть и ими можно пользоваться. Вот такие чудеса. Дело в том, что такие методы образуются из так называемых фасадов, которые считывают обычные методы класса и превращают их в статические. А свойства получаются путем обращения к базе данных. Конечно удобно, что можно с одними и теми же свойствами работать и статически и динамически, но таким образом, получается что IDE не видит данные методы и показывает предупреждение о вызове несуществующих методов. Правда для этой проблемы уже есть решение — использовать IDE-helper, который решает проблему. Даю ссылку на GitHub. На GitHub довольно подробно расписано как с ним работать и устанавливать.
Пункт «Изучается немного сложее Yii2» нельзя считать объективным, так как это лично мое мнение. Мне было достаточно сложно перестроиться после Symfony и Yii2 на эту магию с фасадами. Однако, если хорошо подумать, я посидев пару дней над гайдами и мануалами, тоже начал потихоньку писать на нем, совершенствуя свои знания и навыки.
Мне кажется, что если бы я начал изучать сначала Laravel а потом Yii2, я бы сказал, что Yii2 было сложнее изучать, так что тут дело каждого и субъективно. В любом случае, изучать их довольно просто оба.
Нет документации на русском языке. Да, это печально, не не так уж плохо. Большинство разработчиков владеют хотя бы техническим английским, а официальная документация снабжена хорошими примерами, почти на любой случай. Кроме того, есть сторонние сайты, ссылки приведу в конце статьи.
Нет встроенных генераторов интерфейсов. Да, это большой минус в сравнении с Yii2, но и одновременно являющийся плюсом. Не получится быстро, нажатием трех кнопок сделать готовый интерфейс для работы с данными, зато легко отделить фронтенд от бекенда и собирать фронтенд, как это теперь принято в современной разработке.
Генераторы в Laravel вообще далеки от Yii2, но кое-что они всё-же могут. Есть генераторы консольных команд, которые дают готовый каркас для работы с консолью, генераторы моделей, контроллеров и другие. Но в отличии от генераторов Yii2 — они пустые. Т.е. Если мы генерируем модель, она будет пустая. Нужно самим указывать какое поле будет являться первичным ключом, к какой таблице она относится, какие имеет связки и т.д. Некоторые говорят, что это добавляет гибкости, но ведь в Yii2 вы тоже можете удалить стандартную генерацию и написать свою. Не думаю, что это тема для споров. Тут Yii2 определенно победитель.
Заключение
Итак, мы подобрались к главному вопросу этой статьи «Какой фреймворк выбрать?». Как видно из данного массивного описания основных отличий — оба фреймворка хороши и действительно хороши по своему.
Yii2 мы можем использовать в тех случаях, когда нет особо больших требований к админке фронтенда, а проект нужно сделать красиво и в сжатые сроки.
Laravel — когда у нас есть особые требования к фронтенду и чуть побольше времени на разработку интерфейсов. А так же при необходимости полного разделения frontend'a от backend'a.
Какой фремворк изучить первым, выбирать вам, по этому поводу я написал свое мнение. Надеюсь столь подробная информация позволит вам сделать правильный выбор! Желаю всем удачи в разработке и интересных проектов!
Ссылки
Официальный сайт Symfony
Официальный сайт Yii2
Официальный сайт Laravel
Ссылки из статьи:
Yii Select2 от kartik-v.
Официальный сайт Select2.
Гайды на русском языке для Yii2 (официальная документация)
API Yii2 (официальная документация)
То что обещал дать в тексте статьи:
IDE-helper для Laravel (GitHub)
Русскоязычная документация Laravel с примерами (не официальная, но хорошая)