actions, subactions уже пользую без перехода на архитектуру порто. Полезная тема. Старый проект сложно перевести на порто. Лучше новый проект начну с порто. Спасибо за детальный разбор. Очень полезно.
Как же вы любите сами себе жизнь усложнять, посмотрел эту порту-аорту и понимаю, что или от скуки или от того что жизнь проста через чур и скучно становится, не понимаю зачем всё на столько усложнять? когда же люди начнут отталкиваться от того: - чем проще, тем лучше?.. за материал спасибо, теперь буду понимать как называется такое произведение искусства
32:10 и до 40 секунды этой же минуты. Вопрос (может быть глупый 🙈): т.е если task, который мы написали нигде не используется повторно, ненужный? т.е обращаться к модели тогда прямо из Action?
Отличный обзор, спасибо автору за труды. Входе просмотра и обсуждения с коллегами появилась идея: интересно было бы сделать адаптеры на слое корабля которые реализовывали бы интерфейсы бизнес логики компонентов на слое контейнеров, тогда можно не тянуть кучу зависимостей фреймворка а реализовывать функционал который нам был бы не обходим, тогда мы реализовываем идею Роберта Мартина из книги чистая архитектура, и можем менять фреймворк если захотим. Но делать это очень долго, да и вопрос целесообразности, если мы можем использовать микросервисы )
Почти 9 лет в коммерческой разработке. За это время только две задачи по переходу на другой фреймворк было: переписывал проект с Yii1 на Yii2, и ещё один проект на достаточно ранней стадии переводил с CodeIgniter на Laravel. Поэтому задачу абстрагироваться от фреймворка вообще не ставлю. Хотя читал всякие рекомендации, типа, используешь коллекции Laravel - напиши адаптер, потом поменяешь фреймворк - будешь свою реализацию писать (радость какая). Я не хочу писать адаптеры к ларавелю, я хочу задачу решить и деньги получить :)
Видно, что Рождественские каникулы дали возможность и время записать значительную часть материала. Спасибо! Но Apiato при установке с обновлённым композером, просит пользоваться 1-й версией. Поставил, с 1-й версией.
Спасибо за старания, эти детальные разборы много о чем заставляют задуматься! Про джобы непонятно. Зачем они, если есть экшоны и таски? И про сервис провайдеры непонятно - они вообще отсутствуют на схеме, хотя в составе контейнера фигурируют. Интересно, какая роль им отведена согласно философии Порто. Что в них нужно выносить, откуда можно вызывать, и что можно вызывать из самого сервисного слоя. В целом касательно Порто - меня воротит от идеи плодить сущности. Допустим, есть контроллер с 5 методами. Следуя философии Порто, мы ДОЛЖНЫ создать минимум 5 классов с 1 методом run, а в худшем случае еще классы тасков на каждый экшон. Если я буду что-то подобное внедрять, то буду группировать сущности одного порядка в 1 классе, потому что мне эстетически не нравится идея создавать класс ради одного метода, или файл ради маршрута. Иначе, по самым скромным подсчетам, в проекте, который я сейчас делаю, будет явно больше тысячи файлов. Я считаю, это слишком много для проекта, который разрабатывается одной парой рук. Для меня это как использовать 5 коробок вместо одной, чтобы сложить 5 разных отверток (или 10 свёрел, или 20 бит для шуруповерта)... В общем, я за классы-наборы, или классы-мультитулы) Ещё можно было написать каждый абзац этого текста в виде отдельного комментария, утеряв при этом общую идею и последовательность повествования) Вообще, я отношусь к классам "с увожением") Прежде чем вынести что-то в отдельный класс, я 10 раз думаю - а настолько ли это обособленная штука, чтобы быть удостоенной отдельного класса. Как будто класс - это дом, и не оптимально селить каждого человека в отдельный дом. Так же как не оптимально строить туалет в отдельном здании, чтобы следовать логике "люди отдельно, говно отдельно") Вообще, согласно идее Порто, каждый человек должен жить на отдельном участке земли с отдельными зданиями кухни, столовой, хранилища продуктов, туалета, душевой, спальни, офиса и т.д. И перемещаться между зданиями в DTO-мобиле) Я бы так жить не хотел. Как минимум, можно зимой отморозить яйца, перебегая из туалета в душевую. Про "репозитории" вообще продолжаю находиться в диссонансе. Я помню ролики про репозитории, мне сам подход нравится. Но, по сути, это классы, генерирующие селекты, зачем их называть именно репозиториями? Ради дани моде? Это название не отражает суть. Я у себя в проекте решил назвать их селекторами, и вообще делать в виде трейтов, подключенных в модель, а не в виде отдельных классов... Но это уже вкусовщина, каждый называет как хочет, репозитории - значит, репозитории. Отдельное спасибо за "пхпШторм открывает навсегда"))
А что с джобами не понятно? Их таски, сабэкшоны - это не альтернатива. Джобы - это задачи ОЧЕРЕДИ. Сервис провайдеры зачем - смотрим апиато. По остальному скажу кратко - все выводы ложные из рубрики - "я буду херачить все в моделях и контроллерах - они для этого и созданы". Если я не смог увести от этих мыслей в карс по ларе-шаблоны-порто, то в тдном комментарии точно переубедить не выйдет. Это яркий пример упёртости. А проходит это и с опытом и после прочтения книги "Чистый код", освоения solid, kiss, dry.
@@DmitryAfanasyev хотел бы я увидеть человека, которому не присуща упёртость после 10 лет в профессии) У меня просто значительная часть опыта была связана с Битриксом (к сожалению), и теперь мозг сопротивляется очень многим правильным вещам. Я всего год назад начал Гит использовать, до этого все правки прямо на продакшене херачил) В любом случае, я из тех, кому надо пройти определенный путь, чтобы найти для себя решения, которые покажутся наиболее правильными. Идеальной архитектуры не существует - значит, хороших архитектур может быть сколько-угодно, в зависимости от ситуации... Ещё раз спасибо за труды, такого контента в ру сегменте очень не хватает.
Теперь в экшн можно передавать только структуры данных , цитата из документации Порто "Actions take data structures as inputs, manipulates them according to the business rules internally or through some Tasks, then output a new data structures." Так что да - никаких реквестов ниже контроллера.
Дмитрий, привет! Ты на 28-й минуте возвращаешься к теме DTO. Показываешь файл CategoryUpdateDto, который наследует DtoParent. Можешь показать содержимое файла DtoParent в комментарии к моему вопросу?
Почему SubAction может быть вызван в командах и прослушивателях, а в контроллере не может, раз контроллер, команда и прослушиватель это *практически* одно и тоже? 39:49 Возможно это вопрос к Махмуду, но может всё-таки найдётся здесь кто-нб, с логичным объяснением...
Дружище, а есть git со скелетом Porto под проект? Хотелось бы пощупать отдельно от Apiato. Ранее я чуть ли не ежедневно ломал себе мозг, как бы всё аккуратно, удобно и понятно разграничить, а тем временем со всех щелей нудили про сервисный слой.
Не видел. Но где-то в ресурсах Махмуда есть ссылки на сторонние реализации порто. И "для себя" и под другие фреймворки. Возможно там есть нечто примитивное. Но сделать примитив самому - отличная практика!
Для новичков конечно же сложно будет. Советую сначала попробовать как все делают, по паттерну толстый контроллер)) сам около года на Симфони, щас осваиваю концепцию cqrs. Точнее уже в своем сервисе почти сделал. Принцип такой же
Я заранее извиняюсь за возможно глупый вопрос, но хотелось бы больше информации как сделать роуты. Получается мы выбрасываем роутинг laravel и пишем свою ActionFactory, которая будет по роуту экшены выдвавть? И как вообще это всё сделать, в роутах laravel дескать вызывать свой ApplicationHelperController на абсолютно все запросы, в котором уже вызывать фабрику, парсить свои самописные роуты и т.д.? Мне нравится идея использовать корпоративные шаблоны проектирования с laravel, но не многовато ли мы выкидываем? И как-то непривычно, что шаблон Command здесь называется Action, слегка вызывает ментальное неудобство.
Маршруты не выбрасываются. Работают как и работали. В апиато, маршруты модуля находятся в папке модуля. Это единственное отличие от "ванильных" маршрутов
@@DmitryAfanasyev очень крутые у вас видосы. Паттерны вообще весь год пересматриваю. И коллегам рекомендую. Сейчас как раз разбираюсь с различными подходами по модульной архитектуре. И как раз Porto и lucid изучаю.
потому что Махмуд, мир дому его, явно вдохновлялся классикой и придумал что-то своеобразное на ее основе, но в терминах Докера и микросервисов не говорю, что это плохо, но и смысла в этом не так много, когда есть общепринятый подоход, хоть он и вызывает многие споры конечно
Всё равно не понятно. В дотнэте DDD, CQRS сразу "из коробки" есть. Заранее заготовленные сущности с прописаными правилами и законами? Если так то круто, рад за вас, в php подобное фреймворки еще не предлагают.
@@DmitryAfanasyev было бы неплохо, но нет конечно. Есть всякие толстые книги, статьи, курсы Pluralsight, доки дотнета, вот такие же темплейты, приходится обмазываться всем этим, чтобы с пацанами разговаривать на равных ) я сам в былые времена наваливал в контроллеры и сервисы на Ларавеле, так что я пришел с миром, если что. Но не смог не набросить, потому что эта архитектура все же своего рода мутант
В 10-й версии зачем-то Транспортеры выпилили и теперь повсеместно объект Request передается в Action. Я в недоумении. Дмитрий, есть ли соображения, почему они так сделали?
Валидация ведь тоже может быть частью бизнес-логики. Например, проверка возраста человека, на которого бронируется детский билет. Оставлять всю валидацию в контроллере?
Я тоже так думал и поначалу делал. Но это тоже самое как реквест использовать вместо дто. Джобы это составная часть очереди которые имеют фичу запуска вне очереди. Именно так и надо к ним относиться.
Материал хороший но есть все таки вопрос что делать если у тебя используется на фронте еще и js vue компоненты и их ты держал в resources/js вопрос куда теперь это девать не выносить же на корабль
Так пусть там и лежат :) Ну и кстати, если mix юзаете, по идее, можно в каждом контейнере создать свои компоненты, и смиксовать. Но тут бы я уже не стал. Хотя, снова, как вы используете vue - у вас там прямо приложение, или вставляете фрагментарно в HTML для реактивности
интересно, в Action метод run может называться execute. Почему так? Это же не надежно, Дмитрий как думаешь? а то ведь один назовет run, другой назовет execute. по твоим данным run, а я читал доку, где называется execute. Опасно ведь.
ua-cam.com/video/tCZo8ZVcbJQ/v-deo.html Для тех кто хочет включить в PHPStorm "preview Tab" www.jetbrains.com/help/idea/using-code-editor.html#preview-tab
Эпизоды:
0:00 Начало
1:49 Обзор общей картины
15:25 Request (Запрос)
18:20 Controller (Контроллер)
32:10 Tasks (Задачи, они же Таски)
40:10 Models (Модели)
42:50 Необязательные компоненты
46:30 Смотрим псевдокод
47:15 Routes (Маршруты)
54:07 Говнокодик
57:00 DTO и проблемы именования
01:03:10 Рекомендации начинающим
Еще несколько раз пересмотреть серию в процессе работы и знания закрепятся. Спасибо за старания
Рекомендую сделать самостоятельно майндмап - сильно помогает запоминанию.
actions, subactions уже пользую без перехода на архитектуру порто. Полезная тема. Старый проект сложно перевести на порто. Лучше новый проект начну с порто.
Спасибо за детальный разбор. Очень полезно.
Спасибо большое за данные видосы
Благодаря Вам организовал модульную архитектуру проекта
Огромный респект)
Уже столкнулись с проблемой - "таск - не такс"?
Спасибо за шикарные уроки!
Спасибо! Очень интересно!
🙏
Как же вы любите сами себе жизнь усложнять, посмотрел эту порту-аорту и понимаю, что или от скуки или от того что жизнь проста через чур и скучно становится, не понимаю зачем всё на столько усложнять?
когда же люди начнут отталкиваться от того:
- чем проще, тем лучше?..
за материал спасибо, теперь буду понимать как называется такое произведение искусства
32:10 и до 40 секунды этой же минуты. Вопрос (может быть глупый 🙈): т.е если task, который мы написали нигде не используется повторно, ненужный? т.е обращаться к модели тогда прямо из Action?
Отличный обзор, спасибо автору за труды. Входе просмотра и обсуждения с коллегами появилась идея: интересно было бы сделать адаптеры на слое корабля которые реализовывали бы интерфейсы бизнес логики компонентов на слое контейнеров, тогда можно не тянуть кучу зависимостей фреймворка а реализовывать функционал который нам был бы не обходим, тогда мы реализовываем идею Роберта Мартина из книги чистая архитектура, и можем менять фреймворк если захотим. Но делать это очень долго, да и вопрос целесообразности, если мы можем использовать микросервисы )
Да, тут вопрос в целесообразности. Вероятно такое подойдёт как частный случай для особых проектов.
Почти 9 лет в коммерческой разработке. За это время только две задачи по переходу на другой фреймворк было: переписывал проект с Yii1 на Yii2, и ещё один проект на достаточно ранней стадии переводил с CodeIgniter на Laravel. Поэтому задачу абстрагироваться от фреймворка вообще не ставлю. Хотя читал всякие рекомендации, типа, используешь коллекции Laravel - напиши адаптер, потом поменяешь фреймворк - будешь свою реализацию писать (радость какая). Я не хочу писать адаптеры к ларавелю, я хочу задачу решить и деньги получить :)
Спасибо за труд
Видно, что Рождественские каникулы дали возможность и время записать значительную часть материала. Спасибо! Но Apiato при установке с обновлённым композером, просит пользоваться 1-й версией. Поставил, с 1-й версией.
Да, апиато слабовато поддерживается. Надеюсь этот курс хоть немного прибавит популярности.
Отличный подгончик!))) С рождеством всех!
Спасибо за старания, эти детальные разборы много о чем заставляют задуматься!
Про джобы непонятно. Зачем они, если есть экшоны и таски?
И про сервис провайдеры непонятно - они вообще отсутствуют на схеме, хотя в составе контейнера фигурируют. Интересно, какая роль им отведена согласно философии Порто. Что в них нужно выносить, откуда можно вызывать, и что можно вызывать из самого сервисного слоя.
В целом касательно Порто - меня воротит от идеи плодить сущности. Допустим, есть контроллер с 5 методами. Следуя философии Порто, мы ДОЛЖНЫ создать минимум 5 классов с 1 методом run, а в худшем случае еще классы тасков на каждый экшон. Если я буду что-то подобное внедрять, то буду группировать сущности одного порядка в 1 классе, потому что мне эстетически не нравится идея создавать класс ради одного метода, или файл ради маршрута. Иначе, по самым скромным подсчетам, в проекте, который я сейчас делаю, будет явно больше тысячи файлов. Я считаю, это слишком много для проекта, который разрабатывается одной парой рук. Для меня это как использовать 5 коробок вместо одной, чтобы сложить 5 разных отверток (или 10 свёрел, или 20 бит для шуруповерта)... В общем, я за классы-наборы, или классы-мультитулы)
Ещё можно было написать каждый абзац этого текста в виде отдельного комментария, утеряв при этом общую идею и последовательность повествования)
Вообще, я отношусь к классам "с увожением") Прежде чем вынести что-то в отдельный класс, я 10 раз думаю - а настолько ли это обособленная штука, чтобы быть удостоенной отдельного класса. Как будто класс - это дом, и не оптимально селить каждого человека в отдельный дом. Так же как не оптимально строить туалет в отдельном здании, чтобы следовать логике "люди отдельно, говно отдельно") Вообще, согласно идее Порто, каждый человек должен жить на отдельном участке земли с отдельными зданиями кухни, столовой, хранилища продуктов, туалета, душевой, спальни, офиса и т.д. И перемещаться между зданиями в DTO-мобиле) Я бы так жить не хотел. Как минимум, можно зимой отморозить яйца, перебегая из туалета в душевую.
Про "репозитории" вообще продолжаю находиться в диссонансе. Я помню ролики про репозитории, мне сам подход нравится. Но, по сути, это классы, генерирующие селекты, зачем их называть именно репозиториями? Ради дани моде? Это название не отражает суть. Я у себя в проекте решил назвать их селекторами, и вообще делать в виде трейтов, подключенных в модель, а не в виде отдельных классов... Но это уже вкусовщина, каждый называет как хочет, репозитории - значит, репозитории.
Отдельное спасибо за "пхпШторм открывает навсегда"))
А что с джобами не понятно? Их таски, сабэкшоны - это не альтернатива. Джобы - это задачи ОЧЕРЕДИ. Сервис провайдеры зачем - смотрим апиато. По остальному скажу кратко - все выводы ложные из рубрики - "я буду херачить все в моделях и контроллерах - они для этого и созданы". Если я не смог увести от этих мыслей в карс по ларе-шаблоны-порто, то в тдном комментарии точно переубедить не выйдет. Это яркий пример упёртости. А проходит это и с опытом и после прочтения книги "Чистый код", освоения solid, kiss, dry.
В PhpStorm можно открывать файлы для предпросмотра.
Editor > General > Editor Tabs > Opening Policy > Enable preview tab
@@DmitryAfanasyev хотел бы я увидеть человека, которому не присуща упёртость после 10 лет в профессии) У меня просто значительная часть опыта была связана с Битриксом (к сожалению), и теперь мозг сопротивляется очень многим правильным вещам. Я всего год назад начал Гит использовать, до этого все правки прямо на продакшене херачил) В любом случае, я из тех, кому надо пройти определенный путь, чтобы найти для себя решения, которые покажутся наиболее правильными. Идеальной архитектуры не существует - значит, хороших архитектур может быть сколько-угодно, в зависимости от ситуации...
Ещё раз спасибо за труды, такого контента в ру сегменте очень не хватает.
Спасибо!
Теперь в экшн можно передавать только структуры данных , цитата из документации Порто "Actions take data structures as inputs, manipulates them according to the business rules internally or through some Tasks, then output a new data structures." Так что да - никаких реквестов ниже контроллера.
Дмитрий, привет! Ты на 28-й минуте возвращаешься к теме DTO. Показываешь файл CategoryUpdateDto, который наследует DtoParent. Можешь показать содержимое файла DtoParent в комментарии к моему вопросу?
55:03 умер со смеху 🤣
Почему SubAction может быть вызван в командах и прослушивателях, а в контроллере не может, раз контроллер, команда и прослушиватель это *практически* одно и тоже? 39:49
Возможно это вопрос к Махмуду, но может всё-таки найдётся здесь кто-нб, с логичным объяснением...
Дружище, а есть git со скелетом Porto под проект? Хотелось бы пощупать отдельно от Apiato. Ранее я чуть ли не ежедневно ломал себе мозг, как бы всё аккуратно, удобно и понятно разграничить, а тем временем со всех щелей нудили про сервисный слой.
Не видел. Но где-то в ресурсах Махмуда есть ссылки на сторонние реализации порто. И "для себя" и под другие фреймворки. Возможно там есть нечто примитивное. Но сделать примитив самому - отличная практика!
Для новичков конечно же сложно будет. Советую сначала попробовать как все делают, по паттерну толстый контроллер)) сам около года на Симфони, щас осваиваю концепцию cqrs. Точнее уже в своем сервисе почти сделал. Принцип такой же
Спасибо, нужно переварить...
Да, большой объем информации
Я заранее извиняюсь за возможно глупый вопрос, но хотелось бы больше информации как сделать роуты.
Получается мы выбрасываем роутинг laravel и пишем свою ActionFactory, которая будет по роуту экшены выдвавть? И как вообще это всё сделать, в роутах laravel дескать вызывать свой ApplicationHelperController на абсолютно все запросы, в котором уже вызывать фабрику, парсить свои самописные роуты и т.д.?
Мне нравится идея использовать корпоративные шаблоны проектирования с laravel, но не многовато ли мы выкидываем?
И как-то непривычно, что шаблон Command здесь называется Action, слегка вызывает ментальное неудобство.
Маршруты не выбрасываются. Работают как и работали. В апиато, маршруты модуля находятся в папке модуля. Это единственное отличие от "ванильных" маршрутов
Про команду и экшон не понятно.
@@DmitryAfanasyev спасибо за ответ. Вроде стало понятнее. Напишу код, разберусь до конца. Спасибо
А как тестировать и мокать если там все на статических методах? :) надеюсь, это было просто для примера :)
Можно таймкод?
@@DmitryAfanasyev 01:00:00 и смотрите полминуты
@@DmitryAfanasyev очень крутые у вас видосы. Паттерны вообще весь год пересматриваю. И коллегам рекомендую. Сейчас как раз разбираюсь с различными подходами по модульной архитектуре. И как раз Porto и lucid изучаю.
Это просто вариант использования. Можно и так app(SomeTask::class)->run();
Привет братьям PHPшникам от представителя высшей расы Дотнэта! Весело у вас тут, переизобритаете DDD, CQRS и пр )
Почему "переизобретаете"?
потому что Махмуд, мир дому его, явно вдохновлялся классикой и придумал что-то своеобразное на ее основе, но в терминах Докера и микросервисов
не говорю, что это плохо, но и смысла в этом не так много, когда есть общепринятый подоход, хоть он и вызывает многие споры конечно
Всё равно не понятно. В дотнэте DDD, CQRS сразу "из коробки" есть. Заранее заготовленные сущности с прописаными правилами и законами? Если так то круто, рад за вас, в php подобное фреймворки еще не предлагают.
@@DmitryAfanasyev было бы неплохо, но нет конечно. Есть всякие толстые книги, статьи, курсы Pluralsight, доки дотнета, вот такие же темплейты, приходится обмазываться всем этим, чтобы с пацанами разговаривать на равных )
я сам в былые времена наваливал в контроллеры и сервисы на Ларавеле, так что я пришел с миром, если что. Но не смог не набросить, потому что эта архитектура все же своего рода мутант
В 10-й версии зачем-то Транспортеры выпилили и теперь повсеместно объект Request передается в Action. Я в недоумении. Дмитрий, есть ли соображения, почему они так сделали?
Гляну, спасибо за наводку 👍
Дмитрий, с наступающим праздником!
Когда будет практика? Ждём не дождёмся)
Благодарю! След видео будет по шаблонам, материал поднотовил, осталось снять.
Валидация ведь тоже может быть частью бизнес-логики. Например, проверка возраста человека, на которого бронируется детский билет. Оставлять всю валидацию в контроллере?
1:00:21 Не подходит?
в реквесте
Написал, недосмотрев видео, так что извеняйте
в валидации Laravel есть условия, больше-меньше и другие. Главное правильно воспользоваться
В качестве тасков же можно использовать стандартные ларавелевские джобы?
Я тоже так думал и поначалу делал. Но это тоже самое как реквест использовать вместо дто. Джобы это составная часть очереди которые имеют фичу запуска вне очереди. Именно так и надо к ним относиться.
@@DmitryAfanasyev жаль, было бы все совсем просто dispatchNow и все
Материал хороший но есть все таки вопрос что делать если у тебя используется на фронте еще и js vue компоненты и их ты держал в resources/js вопрос куда теперь это девать не выносить же на корабль
Так пусть там и лежат :) Ну и кстати, если mix юзаете, по идее, можно в каждом контейнере создать свои компоненты, и смиксовать. Но тут бы я уже не стал. Хотя, снова, как вы используете vue - у вас там прямо приложение, или вставляете фрагментарно в HTML для реактивности
интересно, в Action метод run может называться execute. Почему так? Это же не надежно, Дмитрий как думаешь?
а то ведь один назовет run, другой назовет execute.
по твоим данным run, а я читал доку, где называется execute. Опасно ведь.
Как угодно можешь назвать главное придерживаться одного именования. А если в рамках апиато работаешь, то придется run()
@@DmitryAfanasyev понятно, просто если пакет допустим создавать, то он получается не везде будет работать
А где какие нибудь Responses?
И ты вроде обещал подробней про связанность между контейнерами? Или это в следующих видео?
Полагаешь мне следовало эту тему впихнуть в данное видео?....
@@DmitryAfanasyev по концу видео сложилось впечатление что "все" это конец цикла. Возможно я не так понял
В данном случае есть так называемые Transformer's при помощи пакета Fractal
Можно ли где то скачать твою презентацию?
Это черновик. Он не доработан. И текстовка это чндекс перевод документации.
А как делегировать множество ролей? под каждую роль контейнер создавать?
Можно подсмотреть в апиато
Господи, почему экшОн а не Экшен ? или я чего то не знаю ?
Так прикольнее. Экшен - для снобов :D (шучу)
Типизация свойств класса с PHP 7.4
и почему бы создание ДТО не вынести в клас request и потом просто доставать его через $request->getDto()
Да, можно и так сделать
На самом деле в Apiato вы можете указать транспортер прямо в Request, а потом вызвать метод $request->toTransporter();
Чистая архитектура есть норм.
ua-cam.com/video/tCZo8ZVcbJQ/v-deo.html
Для тех кто хочет включить в PHPStorm "preview Tab"
www.jetbrains.com/help/idea/using-code-editor.html#preview-tab
Многое за уши притянуто. Аргументов мало, эмоций много.
Ты о чем? Конкретнее. Иначе это твой коммент - эмоция за уши притянутая....