Краткий обзор нововведений в Laravel 5.4

    image


    Сегодня состоялся вход новой версии PHP фреймворка Laravel — 5.4! В новой версии были добавлены такие возможности, как поддержка Markdown-разметки для формирования электронных писем и уведомлений, улучшена поддержка Redis, добавлены новые возможности шаблонизатора Blade и множество других. Но обо всём по порядку.



    Markdown-разметка для электронных писем и уведомлений


    С поддержкой Markdown, Laravel теперь может генерировать красивые и адаптивные HTML шаблоны для электронных писем, а также генерирует обычную текстовую версию. Например, теперь Ваш код для генерирования письма может выглядеть так:


    @component('mail::message')
    # Order Shipped
    
    Your order has been shipped!
    
    @component('mail::button', ['url' => $url])
    View Order
    @endcomponent
    
    Next Steps:
    
    - Track Your Order On Our Website
    - Pre-Sign For Delivery
    
    Thanks,<br>
    {{ config('app.name') }}
    @endcomponent

    Выглядеть это будет так:


    image


    Laravel Dusk


    Laravel Dusk — это новая утилита для end-to-end тестирования приложений. По-умолчанию, для её использования не требуется установка JDK или Selenium. Вместо них, Dusk использует standalone версию ChromeDrive, но вы также можете использовать любой другой драйвер, совместивый с Selenium.


    Поскольку Dusk использует реальный браузер для тестирования, Вы можете с лёгкостью тестировать и взаимодействовать с приложениями, в которых используется JavaScript:


    /**
     * A basic browser test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $user = factory(User::class)->create([
            'email' => 'taylor@laravel.com',
        ]);
    
        $this->browse(function ($browser) use ($user) {
            $browser->loginAs($user)
                    ->visit('/home')
                    ->press('Create Playlist')
                    ->whenAvailable('.playlist-modal', function ($modal) {
                        $modal->type('name', 'My Playlist')
                              ->press('Create');
                    });
    
            $browser->waitForText('Playlist Created');
        });
    }

    Компоненты и слоты для Blade шаблонизатора


    Использование новых функций шаблонизатора Blade — компонентов и слотов — позволяет делать всё то, что вы привыкли делать с секциями и шаблонами. Однако, для некоторых разработчиков модель компонент-слот может показаться намного легче для понимания. Для начала, представим, что у нас есть компонент "alert", который мы хотим использовать в нашем приложении во всех шаблонах:


    <!-- /resources/views/alert.blade.php -->
    
    <div class="alert alert-danger">
        {{ $slot }}
    </div>

    Переменная {{ $slot }} будет содержать тот контент, который мы захотим передать в компонент. Чтобы объявить этот компонент, мы используем новую дериктиву @component:


    @component('alert')
        <strong>Whoops!</strong> Something went wrong!
    @endcomponent

    Именованыне слоты позволяют использовать несколько слотов в одном компоненте:


    <!-- /resources/views/alert.blade.php -->
    
    <div class="alert alert-danger">
        <div class="alert-title">{{ $title }}</div>
    
        {{ $slot }}
    </div>

    Они передаются в компонент с использованием директивы @slot. Любой контент вне это директивы будет передан в компонент в качестве переменной $slot:


    @component('alert')
        @slot('title')
            Forbidden
        @endslot
    
        You are not allowed to access this resource!
    @endcomponent

    Broadcast Model Binding


    Равно как и HTTP роуты, роуты для каналов прослушки событий теперь также могут использовать неявную привязку к модели. Например, вместо строки или числового ID, вы можете передать экземпляр модели (класса) Order:


    use App\Order;
    
    Broadcast::channel('order.{order}', function ($user, Order $order) {
        return $user->id === $order->user_id;
    });

    Сообщения высшего порядка в коллекциях (Higher order messages, HOM)


    Коллекция теперь поддерживают сообщения высшего порядка, которые позволяют производить общие операции с коллекциями. Сейчас доступны следующие сообщения:


    • contains
    • each
    • every
    • filter
    • first
    • map
    • partition
    • reject
    • sortBy
    • sortByDesc
    • sum

    К каждому сообщению можно обратиться как к динамическому свойству экземпляра коллекции. Например, используем сообщение each, чтобы применить какой-либо метод к каждому объекту внутри коллекции:


    $users = User::where('votes', '>', 500)->get();
    
    $users->each->markAsVip();

    Аналогичным образом, Вы можете использовать sum, чтобы, к примеру, посчитать количество голосов в коллекции с пользователями:


    $users = User::where('group', 'Development')->get();
    
    return $users->sum->votes;

    Пользовательские обработчики событий Eloquent


    Обработчики событий в Eloquent теперь могут быть привязаны к объектам событий. Это позволяет намного проще обрабатывать события Eloquent, а также упрощает тестирование этих событий. Чтобы использовать это нововведение, необходимо объявить свойство $events в классе Вашей модели, что позволит использовать Ваши собственные классы для обработки базовых событий Eloquent:


    <?php
    
    namespace App;
    
    use App\Events\UserSaved;
    use App\Events\UserDeleted;
    use Illuminate\Notifications\Notifiable;
    use Illuminate\Foundation\Auth\User as Authenticatable;
    
    class User extends Authenticatable
    {
        use Notifiable;
    
        /**
         * The event map for the model.
         *
         * @var array
         */
        protected $events = [
            'saved' => UserSaved::class,
            'deleted' => UserDeleted::class,
        ];
    }

    Retry & Timeout для каждого процесса


    Раньше, настройки "retry" и "timeout" устанавливались глобально для всех процессов командной строки. В Laravel 5.4, эти настройки теперь можно задавать для каждого процесса в индивидуальном порядке, определив их непосредственно в классе процесса:


    <?php
    
    namespace App\Jobs;
    
    class ProcessPodcast implements ShouldQueue
    {
        /**
         * The number of times the job may be attempted.
         *
         * @var int
         */
        public $tries = 5;
    
        /**
         * The number of seconds the job can run before timing out.
         *
         * @var int
         */
        public $timeout = 120;
    }

    Middleware для очистки запросов


    В Laravel 5.4 появились два новых middleware'a (фильтра запросов): TrimStrings и ConvertEmptyStringsToNull


    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

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


    "Realtime" Фасады


    Раньше, только поставляемые по-умолчанию Laravel сервисы предоставляли фасады, которые позволяли быстро и лаконично использовать свои методы через сервис-контейнер. В Laravel 5.4 появилась возможность легко конвертировать любой ваш класс в фасад в реальном времени. Представим, что у нас имеется следующий класс:


    <?php
    
    namespace App\Services;
    
    class PaymentGateway
    {
        protected $tax;
    
        /**
         * Create a new payment gateway instance.
         *
         * @param  TaxCalculator  $tax
         * @return void
         */
        public function __construct(TaxCalculator $tax)
        {
            $this->tax = $tax;
        }
    
        /**
         * Pay the given amount.
         *
         * @param  int  $amount
         * @return void
         */
        public function pay($amount)
        {
            // Pay an amount...
        }
    }

    Чтобы сделать его фасадом, достаточно лишь добавить префикс Facades:


    use Facades\ {
        App\Services\PaymentGateway
    };
    
    Route::get('/pay/{amount}', function ($amount) {
        PaymentGateway::pay($amount);
    });

    Вы также можете писать тесты взаимодействи с использованием функции имитирования фасадов:


    PaymentGateway::shouldReceive('pay')->with('100');

    Пользовательские модели для связующих таблиц


    В Laravel 5.3 все модели "связующих" таблиц для связей "many-to-many" использовали один и тот же экземпляр встроенной модели Pivot. В Laravel 5.4 вы можете определить свою модель для сводной таблицы после объявления связи следующим образом:


    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Role extends Model
    {
        /**
         * The users that belong to the role.
         */
        public function users()
        {
            return $this->belongsToMany('App\User')->using('App\UserRole');
        }
    }

    Улучшена поддержка кластеров Redis


    Ранее не было возможность определить соединения Redis к одному хосту и кластерам в одном приложении. С Laravel 5.4 Вы можете определить несколько подключений к хостам и кластерам. Более подробно в документации к Redis.


    Длинна строк по-умолчанию в миграциях


    В Laravel 5.4 используется utf8mb4 в качестве кодировки по-умолчанию, которая поддерживает хранение эмодзи в базе данных. Если вы обновляетесь с Laravel 5.3, вам не нужно менять кодировку.


    Если Вы всё же её меняете вручную или используете MySQL версии младше 5.7.7, вам необходимо вручную настроить длину строк по-умолчанию, которые генирируют миграции, с помощью метода Schema::defaultStringLength в вашем AppServiceProvider:


    use Illuminate\Support\Facades\Schema;
    
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Schema::defaultStringLength(191);
    }

    Поддержка JSON-формата в языковых файлах


    В версии 5.4 добавилась возможность использовать JSON-формат для составления языковых файлов в приложениях. Они по-прежнему хранятся в директории resources/lang.
    Например, если у вас есть русский перевод вашего проекта, вы можете создать ru.json в директории resources/lang, и его содержимое может выглядеть примерно так:


    {
        "I love Laravel!": "Я люблю Laravel!"
    }
    

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

    Будете ли Вы апгрейдить свои проекты до версии 5.4?

    Поделиться публикацией

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

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

      +3
      Чем дальше в лес, тем сложнее поддерживать проекты на Laravel в актуальном состоянии. То некоторые компоненты не позволяют обновиться — приходится временно форкать, решать проблемы совместимости и ждать когда примут PR. То приоритеты насущных задач не позволяют переключиться на обновление.

      Так, на одном проекте 5.1 и как с нее переходить на 5.4 я уже ума не приложу. Работы явно не на 1 день. А ведь поддержка LTS 5.1 прекращается уже в июне 2017 года…
        0

        Тейлор отказался от идеи LTS в принципе, насколько я знаю. Так что 5.1 — последняя LTS версия.

          +1

          А как же 5.5? https://laravel-news.com/laravel-release-process Откуда подобная инфа про отказ от новых LTS?

            0
            Вот я тоже гуглю и не могу найти. Везде упоминается, что 5.5 будет следующей версией с LTS. При чем выпуск планируется как я и писал — в июне 2017 года.
              –1

              Хм, значит, не правильно понял. :)

                +4
                Видимо вы об этом
                  0

                  Да.

                    +1
                    LTS - Анти-паттерн

                      +3

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


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


                      Так что это палка о двух концах. Имхо, стоит выпускать LTS но с менее продолжительным жизненным циклом и чуть большим количеством оных.

                        –1

                        Ещё вот это порадовало:


                          +1

                          Он вообще такой интересный.
                          Вот тут можно проследить интересную логику: https://twitter.com/search?f=tweets&vertical=default&q=LTS%20from%3Ataylorotwell&src=typd


                          LTS is sort of an anti-pattern IMO.

                          I am not a fan of LTS in general. Prefer people take a couple days per year to stay updated

                          А до этого:


                          Forge currently designed for 14.04 LTS… will update to 16.04 LTS when its available

                          А чего ж не 14.10, 15.04, 15.10? Хорошо же несколько дней в году тратить на обновления! Быть на острие! Тем более когда LTS — антипаттерн!

                          +1

                          Охренеть.

                    –1
                    Вы что-то делаете не так, буквально месяца 3 назад проект перенёс с 5.1 на 5.3 и проблем никаких не было. Возможно, по той причине, что использовались преимущественно стандартные библиотеки, а не стандартные были заменены на стандартные в процессе переноса.
                      +1
                      Ну как минимум, админка требует полного переписывания, т.к. нужно переходить с https://github.com/sleeping-owl/admin на https://github.com/LaravelRUS/SleepingOwlAdmin. Все бы ничего, но в процессе работы добавилось очень много кастомных типов ввода данных: автокомплит, другой визуальный редактор, разметка телефонов, seo поля, редактор json полей. Да, я могу в процессе обновления это все разом переписать — но кто мне за это заплатит? Да, я могу ничего не делать и просто обновить оставив стандартные поля ввода — но как на меня посмотрят клиенты? Так что проект-проекту рознь.
                        0
                        Не используем автоматических генераторов, да даже если бы и использовали — есть смысл обратить внимание на voyager. Админка в моём понимании — это обычный crud и это всё генерится прямо из консоли artisan без особых проблем.
                          +1
                          Хрен редьки не слаще. В указанном вами CRUD абсолютно те же поля, что есть по умолчанию в SleepingOwl. При этом встраивание своих контроллеров и редактирование полиморфных связей под вопросом (я имею в виду возможны те же грабли при обновлении).
                            0

                            IMHO, в Вашем случае лучше всего дождаться поддержки Совой новой версии Laravel и только тогда апгрейдиться, чем делать это вслепую.

                              +2
                              Пока ближайшее обновление запланировано после релиза Laravel 5.5. И это если Тейлор не откажется от LTS. В противном же случае будем будем взвешивать все за и против продолжения использования этого фреймворка в проекте.
                                +1

                                как мне кажется, в вашем случае zend или symfony подойдут гораздо лучше
                                учитывая родство симфони и лары — симфони подойдет даже больше

                              –1
                              Под CRUD подразумевал встроенные генераторы классов, не нужно смешивать мелкое с мягким. Пока Вы мне пытались доказать правильность своих решений и не правильность выбора наших. Мы обновились, сели в локомотив 5.4 и поехали дальше, чего и Вам желаю.
                                +2
                                Боже упаси вам что-то чего-то доказывать. Просто проект проекту-рознь. А генераторы классов != CRUD в априори. При этом взяв любой компонент за основу для разработки админки, проблем нет ровно до тех пор, пока не возникает необходимости дорабатывать эту самую админку нестандартными решениями и выводами.

                                На простых проектах обновления протекают достаточно безболезненно — сел в локомотив и поехал дальше.
                                Тут я имею в виду формы редактирования/добавления данных стандартных форматов

                                Но на проектах с более сложной архитектурой такой фокус уже не проходит



                                Поэтому приходится балансировать между скоростью разработки и поддержанием версий в актуальном состоянии. Если бы админка писалась полностью под проект без всяких CRUD — мы бы уже давно обновились. Но вы же должны понимать, что на такой проект потребуется несколько больше времени…

                                Возьмем еще один пример: laravelrus/localized-carbon. Отличный компонент, думаю многие им пользуются. Но увы, без вот этого патча локомотив не тронется даже в рамках 5.1 версии. Или вы предлагаете вообще все писать самостоятельно?
                                  0
                                  Такого же уровня админка (еще не завершенная), но созданная без генераторов
                                  Небольшой гос проект


                                  Есть в том числе и модалки со вкладками и есть отдельная Модерка на лицевой странице сайта, на тех же контроллерах. Разница, как мне кажется, только в выборе пути развития проекта. Вы пошли одним путём — мы пошли другим (возможно более трудным).
                                    0

                                    Формы подобного вида я и охарактеризовал как типовые

                        +1
                        Сколько с Laravel ни работал, всегда чувствовал что 5.1 нифига не LTS, так как он сам по себе сырой. Всегда приходилось новые проекты на последней версии Laravel начинать.
                          +1
                          Странная политика, вроде фреймворку уже много лет и пора взрослеть.
                          Без LTS ларе не захватить вкусный корпоративный (и консервативный) сектор, так и останется хипстерской игрушкой.
                          –6
                          Госспади, какой ужас…
                          Вот весь ларавель это костыли и подпорки вместо того чтобы чуток почитать сложные места документации симфони.
                          Наплодить столько кривых решений это надо уметь, но похоже сейчас markdown в письмах получает премию за самый кривой костыль.
                            +2
                            Все фреймворки, кроме Simfony — УГ? :)
                            Где-то есть нормальное сравнение фреймворков?
                              –7
                              Нет конечно, претензии восновном к ларавелю. Из ларавеля торчат уши симфони очень сильно — взяли компоненты симфони которые очень легко использовать, а те которые использовать сложнее потому что они довольно мощные заменили на свое, причем это свое получилось скажем так не очень. Из примеров — Eloquent, Blade и фасады.
                                –3
                                Twig с блоками и Blade со слотами — это прям как из анекдота про немца, русского, украинца и сраку :)
                                  –3
                                  Вот точно :)
                                  Интересно, они починили блейд?
                                  https://habrahabr.ru/post/238017/#comment_8316215
                                    –1
                                    А чего минусите-то? Пользователи Twig и Blade не согласны в «разности» шаблонизаторов? Или кого-то оскорбила срака?
                                      –4
                                      Тут боевой отряд хомячков Тейлора прибежал :)
                                        0

                                        Я не минусил, но сравнение совершенно неверное. Альтернатива блоков в симфони — это секции блейда. Для слотов же альтернатива в твиге — это macro, и то с большой натяжкой.

                                          0
                                          А embed это не оно?
                                            +1

                                            Ну ок, слоты — это embed + macro.


                                            Просто сравнивать Blade с Twig крайне не корректно. Blade создан для разработчиков, как доп.возможности для php. А Twig — это абстракция над языком с полным разбором токенов, построением AST (могу заблуждаться в деталях, не все сырцы просматривал) и прочее-прочее.


                                            Это как сравнивать Doctrine и Eloquent и вопрошать "зачем?!!11". Одно DataMapper, другое ActiveRecord. Разные подходы, идеи и цели.


                                            Понятно, что будут пересечения в возможностях, но концепции разные.

                                      +1
                                      Но Laravel, афаик, — самый трендовый фреймворк 2016 года. :)
                                        –4
                                        Ну так виндовс вон тоже самая популярная система, так что же теперь.
                                        +2

                                        Какой в симфони аналог Eloquent? Doctrine? так это отдельный продукт, а для Blade? Twig? Так и это другой продукт, может быть в симфони есть "фасады"? так такого там вообще нет. Может вам стоит разобраться в теме, а не делать пустые вбросы?

                                          +1

                                          Ну фасады — это просто красивый способ избавиться от симфонийской сервис локации $container->get, так что можно сказать, что да, это аналог, только чуть более элегантный.

                                            –4
                                            Это красивый способ? Да он же создает кучу псевдо-статических классов и ломает автокомплит, и это при том что с пятой версии DI стал вполне себе нормальным.
                                            Для этого «красивого способа» уже приделали стандартный костыль, без которого вообще ад.
                                              +3

                                              На вкус и цвет. Лично я против, как фасадов, так и сервис локации. Но. Автокомплит есть (достаточно плагин подключить или пакет поставить). А шансов ошибиться в алиасе или судорожно вспоминать какое у него там название, исследуя services.yml из десятков бандлов на порядок меньше. Плюс статический доступ к элементу контейнера на порядок повышает профитность REPL (это, признаться, единственное место где фасады нужны, имхо).

                                                0
                                                А шансов ошибиться в алиасе или судорожно вспоминать какое у него там название, исследуя services.yml из десятков бандлов на порядок меньше.

                                                *конечно же я имел ввиду что шанс ошибиться выше, а не меньше. Опечатался.

                                                  0

                                                  Это такой себе аргумент. IDE уже давно все автокомплитит, причем с учетом типов.


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

                                                  0
                                                  Лично я против, как фасадов, так и сервис локации.

                                                  А что Вы используете? :)
                                                  Можно примеры, почему за и против? :)

                                                  Спасибо.
                                                    0

                                                    Я не автор, но я против статики, потому что это неявные зависимости. Я за внедрение зависимостей через конструктор.

                                                      +2

                                                      Опять та же самая ошибка (самая популярная, наверное) =)


                                                      Фасады, в контексте Laravel — это не статика. Это статический прокси на элемент (объект, не класс) контейнера. По-факту там совершенно пустой класс у которого есть лишь пометка-ссылка на элемент контейнера. Отсюда и моё сравнение с сервис-локацией, популярной раньше в симфони.

                                                        +1

                                                        Подумайте почему "популярной раньше" и почему от этого ушли.
                                                        Вот добавили вы вызов Auth:user() в своем классе и… все, по публичному контракту вашего класса я никогда не узнаю что он поломается в консоли, потому как сессии нету.


                                                        зы. Если я не прав, укажите в чем

                                                          +1

                                                          А кто говорит, что от этого ушли? Ядро Symfony до сих пор напичкано этим. Но это не значит что нет более профитных инструментов, которые появились в symfony 2.8 (намёк на автовайринг). С таким же успехом можно говорить: "вот вы отнаследовались от базового симфонёвого контроллера и… ну и т.д. ваши слова.)


                                                          Это просто значит, что это хоть и есть в ядре и хоть это облегчает порог входа, более того — даже в доках примеры есть (как в симфони, так и в ларке) но эти решения не есть истина в последней инстанции и грамотные разрабы всегда предпочтут DI сервис локации.


                                                          По-этому и говорю, что "популярной раньше", так же как были популярны раньше фасады в ларке. Просто удобных альтернатив не было.

                                                            –2
                                                            Это не напичкано, это просто один базовый контроллер от которого совсем не обязательно наследоваться. Как раз создан для вот такой вот кучки хелперов, которые удобны в небольших проектах.

                                                            А фасады в ларавеле умудрились сделать из DI фактически статику по использованию со всеми ее проблемами.
                                                            +1

                                                            В симфони этим тоже многие страдают, но только не через фасады, а через запрос контейнера, и вызова нужных сервисов уже внутри класса, а не через DI.

                                                        +2

                                                        В ларке есть совершенно чудесный DI с инжектами как в конструктор, так и в методы. При этом, у каждого "фасада" есть интерфейс, который висит в Contracts. Как следствие
                                                        1) фасады, либо для тех, кто осознаёт риск, но иногда проще и профитнее их запилить, вместо создания тучи сервисных классов
                                                        2) либо для новичков, которые пока не изучили механизм внедрения и сам контейнер


                                                        С фасадами


                                                        public function some()
                                                        {
                                                            return \Config::get('some.any', 23);
                                                        }

                                                        С двойной диспатчеризацией


                                                        // RepositoryInterface == Illuminate\Illuminate\Contracts\Config\Repository
                                                        public function some(RepositoryInterface $config)
                                                        {
                                                            return $config->get('some.any', 23);
                                                        }

                                                        С инжектом в конструктор


                                                        public function __contruct(RepositoryInterface $config)
                                                        {
                                                            $this->config = $config; // А в методе some просто получаем объект
                                                        }

                                                        В случае 2 и 3 достаточно указать интерфейс — ларка сама всё пробросит (во отличие от симфони, где надо прописывать автовайринг и проч).

                                                          +1
                                                          во отличие от симфони, где надо прописывать автовайринг и проч

                                                          * в отличии (очепятался, простите)


                                                          По сути: Это не плохо. Можно в любой момент увидеть что куда улетает, пробежавшись по конфигам (services.yml). Но это не так удобно. Т.е. и плюс большой и минус.

                                                            0

                                                            Вы правы, фасады это не статика. Это классический сервис-локатор.
                                                            И правильнее пример переписать так:


                                                            public function some()
                                                            {
                                                                return $this->serviceLocator->get('some.any', 23);
                                                            }

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


                                                            Также лично я никогда не понимал радостей внедрения зависимостей прямо в методы. Это несколько нелогично перемешивать зависимости (которые могут меняться, добавляться и убираться) и аргументы — нет стабильного интерфейса.

                                                              +2

                                                              Ну я приводил пример с фасадом, чтобы потом привести два других примера "как от них отказаться и начать жить". Радость же с внедрениями в метод просты:
                                                              1) Облегчается инциализация объекта (уменьшается список зависимостей в конструкторе)
                                                              2) Видно какие зависимости требует сам класс, а какие сам метод — это крайне актуально при тестировании и на порядки его упрощает
                                                              3) Позволяет реализовывать факторные методы, вместо написания самой фектори
                                                              4) Просто в некоторых местах удобнее


                                                              Можно рассмотреть простой пример. Как работают консольные скрипты в симфони:
                                                              1) Если мы хотим использовать православный DI — добавляем инжект в конструктор нужных сервисов и радуемся.
                                                              НО:
                                                              а) Набертся штук 30 таких скриптов и старт консоли превратится в муку, особенно из дев. режима с пересбором контейнера по несколько секунд
                                                              б) Если мы решим что-то инициализировать в этом конструкторе (ну, допустим соединение к БД указать другое) — нужно помнить, что эта иницализация отразится на всех существующих скриптах в проекте


                                                              Вывод: Надо получать либо через сеттер, либо через сервис-локацию в методе execute. И то, и другое, объективно, не очень. Но живём.


                                                              Пример с Laravel приводить нужно с DI в метод выполнения скрипта, вместо конструктора?


                                                              Ну и да, никто не мешает НЕ ломать интерфейс, даже используя DD. Но согласен, есть такие места, где так не прокатывает в Laravel. Боль.

                                                                –1
                                                                1. Никто вас не заставляет наследовать все ваши команды от общего предка с жестко заданным конструктором. Вы можете кажду команду зарегистрировать отдельным сервисом только с нужными ему зависимостями. А значит поменять конект в одной команде вообще не проблема.


                                                                2. Я не представляю насколько огромным должен быть проект, чтобы в дев режиме сборка контейнера была проблемой. Поделитесь ссылочкой чтоли (зы. сборка медленная потому что ямл парсер который идет с симфоны написан на пыхе. Всегда можно поставить pecl расширение для парсинга ямлов и допилить на его основе свой ридер. Симфони позволяет это сделать без проблем)
                                                                  0
                                                                  Там не в парсере дело, а в том, что при вызове консоли приложение регистрирует ВСЕ команды из ВСЕХ бандлов принудительно (и не лениво в данный момент). Если команд действительно много — это может стать проблемой. Но я до такого пока не доходил. В принципе всегда можно оформить PR с фиксом этой фичи, я например не вижу никакой принципиальной проблемы сделать их ленивыми сервисами или инициализировать лениво через замыкания
                                                                    –1

                                                                    А ещё можно сделать так, чтобы в команде был сервис-локатор, из которого бы лениво подгружался единственный объект и выполнялся — вынести всю логику из команды. По факту, это будет то же самое, о чём сейчас и говорим в ларавеле. В данном случае сервис локатор будет выступать в роли фабрики — и не более.


                                                                    Только одно дело — применять эти фасады (как и сервис-локаторы) в контроллерах и командах, а другое — погружать их куда-нибудь далеко-далеко в бизнес логику.

                                                              0
                                                              Есть еще и возможность напрямую обратиться к DI что чаще всего я и делаю, если объект из DI используеться только в этом методе.

                                                              public function some()
                                                              {
                                                              return app('config')->get('some.any', 23);
                                                              }
                                                                +1

                                                                Это такая же сервис-локация сквозь функцию-хелпер, которая дёргает контейнер ядра (т.е. тот, который зарегистрирован как синглтон). Ничем не лучше фасадов, а может даже хуже.

                                                      –2
                                                      Вот именно что доктрина и твиг это отдельные проекты, потому что очень хорошие проекты, и можно их использовать, а не лепить свои кривейшие поделки (Eloquent и Blade).
                                                      А может в симфони фасады нафиг не нужны? Не задумывались над этим? В ларавеле они кстати тоже нафиг не нужны, потому что DI вполне нормальный, но нет, прикрутили.
                                                      Этот ваш ларавель уже оброс костылями для подключения доктрины, твига и до кучи хелперами для хоть какой-то подсветки этих ваших фасадов и элоквента.
                                                        +3

                                                        Чем Eloquent плох? Можно конкретики? А то всё "кривой-кривой", а аргументов 0.

                                                          +1

                                                          В Eloquent слишком много магии, из-за которых порой возникают очень странные ошибки, которые не мог предусмотреть сам создатель.
                                                          Вот например, что случилось после недавнего неожиданного обновления laravel 4.2: https://www.reddit.com/r/laravel/comments/5cgih9/too_much_magic_in_laravel/
                                                          Тейлор в итоге выпустил новую версию, где откатил эти изменения.


                                                          Также там много чего намешано, что нарушает принцип MVC. За примером далеко ходить не надо:


                                                          $users = DB::table('users')->paginate(15);

                                                          Если же появится желание использовать Eloquent отдельно от Laravel, придётся увидеть на первый взгляд странную инициализацию, т.к. выяснится, что для полной работы eloquent нужны illuminate события — на них завязаны события eloquent вроде saving и прочего. Кому-то, возможно, удобно отправлять и обрабатывать события ORM через менеджер событий вместе со всеми остальными событиями приложений. Но лично для меня это бардак.


                                                          Недавно я делал простенький проект — собирал из компонентов symfony и прочих библиотек и решил в качестве шаблонизатора использовать привычный blade. И я отказался от этой идеи, увидев сколько всего он за собой тянет, включая эти сраные события (видимо для обработки composer-ов) и хелперы Illuminate\Support, которые не будут работать у меня из-за отсутствтия остальных частей Laravel.


                                                          На самом деле и Eloquent очень даже удобен в использовании (особенно конструктор запросов), но надо иметь ввиду следующие факты:


                                                          1. Много магии, которая порой выстреливает в разработчика.
                                                          2. Порой нарушаются принципы MVC и SOLID, что иногда мешает что-то сделать кастомное.
                                                          3. Эти библиотеки крайне сильно завязаны на Laravel и не сильно то модульные.

                                                          Потому критика Eloquent вполне обоснована.

                                                            0
                                                            Эти библиотеки крайне сильно завязаны на Laravel и не сильно то модульные.

                                                            Они и не подразумевались как модульные. Но, думаю, через пару версий станут (судя по тому, что Tinker вынесли в отдельный модуль).


                                                            Но в целом мысль Ваша понятна.

                                                  +1
                                                  А могли бы конкретные примеры привести? С симфони плотно не работал поэтому интересно. И почему markdown в письмах это костыль?
                                                    –3
                                                    Ну вот сейчас скачал это чудо посмотреть.
                                                    Скачались базовые компоненты симфони в зависимостях. К ним написаны обертки, которые по сути проксируют вызовы и добавляют фасады.
                                                    А потом у нас появляются статьи как прикрутить доктрину к ларавелю. Зачем нужно было использовать такой кривой велосипед как Eloquent?
                                                    Потом, посмотрите на папку Illuminate — там либо как в случае базовых компонентов идет extend Symfony либо творчество уровня студента —
                                                    Illuminate\Config например, конечно, симфоневый конфиг это сложно
                                                    роутинг — обвязка над симфоневым, и кеширование выдрано с мясом, а инициализация роутов вещь тяжелая
                                                    консоль — полностью притащена с симфони, но зачем-то сделана обертка.

                                                    > И почему markdown в письмах это костыль?
                                                    Вот на кой черт оно во фреймворке? Причем это blade, а потом то что получилось обрабатывается маркдауном, причем это прибито гвоздями, только в мейлере.
                                                    Для сравнения — как это сделано в симфини — есть банд https://github.com/symfony/swiftmailer-bundle который просто подключает библиотеку в контейнер и из него конфигурирует ее и ее плагины, после настройки метода отправки нужно просто вызвать container->get('mailer')->send($message) и передать ей объект сообщения, которому уже сам генеришь тело хоть твигом хоть маркдауном, хоть еще каким конвертором, который ставишь отдельно.
                                                      –2
                                                      У Симфони другие задачи. Относитесь к Ларавелю, как к Yii — для небольших сайтов и быстрого старта они подходят оптимально.

                                                      Симфони хорош для больших архитектур, где необходимы DI через конфиги и тп.
                                                        +1
                                                        Markdown письма внтури фреймворка (как и многие другие костыли) из-за того, что так Тейлору удобнее разрабатывать и поддерживать свои коммерческие продукты +)
                                                        +4

                                                        Идея Laravel быть гибкой и удобной. Идея Симфони быть правильной. Отсюда и ответ. Любому отпетому симфонисту вряд-ли понравится возможность "из коробки" иметь дополнительную зависимость.


                                                        При этом Laravel в результате получается на порядок удобнее:


                                                        // Symfony
                                                        public function listAction() 
                                                        {
                                                            $repo = $this->container->get('doctrine')->getRepository(Some::class);
                                                        
                                                            return new JsonResponse(['items' => $repo->findAll()]);
                                                        }
                                                        
                                                        // Laravel
                                                        pubic function index(SomeRepositoryInterface $repo)
                                                        {
                                                            return $repo->findAll();
                                                        }

                                                        И зачастую даже грамотнее. А всякие замечания "прибито гвоздями" просто от незнания, т.к. Laravel местами гибче симфони.

                                                          –7
                                                          Простите, вы когда симфони последний раз видели? Версия 2.1?
                                                          Инжект параметров есть с 3.1 версии, причем не прибит гвоздями к роутеру, как в ларавеле, а реализован через события с помощью ресолверов и возможностью добавлять свои.
                                                          Вы простите когда удобство показываете хоть не на двухстрочных функциях это делайте, а то я же тоже могу взять бандлы для апи, там куча вкусностей развешено, а не только 2-3 стандартных преобразования.

                                                          А всякие замечания «прибито гвоздями» просто из-за того что посмотрел код мейлера.
                                                          Извините, но
                                                                  $markdown = Container::getInstance()->make(Markdown::class);
                                                          

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

                                                          Гибкий блин, удобный, особенно гибкий. Хомячки блин тупые, даже код не могут посмотреть той поделки на которой пишут.
                                                            +6
                                                            гвоздями к роутеру, как в ларавеле

                                                            шта?


                                                            а реализован через события

                                                            Вместо того, что бы сделать по-нормально через контейнер. В ларке подобная схема работает не только для контроллеров, а для чего угодно. Т.к. DD реализован именно через него. Вспомните сколько автовайринг ожидали. И только к версии 3.2 (да ведь?) его наконец доделали до нормального состояния с резолвом из интерфейсов.


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

                                                            А я не беру бандлы, я беру коробочную стандарт эдишн. В коробочной поставке симфони огрызок ещё тот, по-этому каждый проект потом превращается в фарш из JMS, Knp, Fos и прочей лабуды с вермишельками сонаты.


                                                            Гибкий блин, удобный, особенно гибкий. Хомячки блин тупые, даже код не могут посмотреть той поделки на которой пишут.

                                                            Мне жаль, что у меня, как симфониста есть подобные коллеги как вы.

                                                              0
                                                              В коробочной поставке симфони огрызок ещё тот, по-этому каждый проект потом превращается в фарш из JMS, Knp, Fos и прочей лабуды с вермишельками сонаты.


                                                              Мне жаль, что у меня, как симфониста есть подобные коллеги как вы.

                                                              На Simfony получается вермишельный код?
                                                              Его удобно поддерживать?
                                                              Почему вам тогда нравится Simfony? :)
                                                                +2
                                                                На Simfony получается вермишельный код?
                                                                Его удобно поддерживать?
                                                                Почему вам тогда нравится Simfony? :)

                                                                Это утрированная ирония =)


                                                                • В Symfony ты собственноручно отстреливаешь себе ногу из пистолета
                                                                • В Laravel тебе мило предоставляется гранатомёт сразу "из коробки", чтобы наверняка

                                                                P.S.


                                                                • В Yii это небольшой виджет-танк на JQuery

                                                                </irony>

                                                      0
                                                      Можно вопрос?
                                                      В документации Ларавеля указано в требованиях
                                                      PHP >= 5.6.4
                                                      https://laravel.com/docs/5.4

                                                      PHP 5.6.4 — это, что за зверь такой?

                                                      Версию 5.6.30 — знаю, 7.1.1 — знаю, а вот 5.6.4 — не знаю
                                                      http://php.net/downloads.php
                                                        +3

                                                        Открываю секрет: 5.6.4 → 5.6.8 →… → 5.6.10 →… → 5.6.30.

                                                          –1
                                                          Спасибо за разъяснение!
                                                          Так бы я не догадался, что это не «сорок», а просто «четыре».
                                                        +1
                                                        Мой реквест https://github.com/laravel/framework/pull/16736 влили в 5.4 и теперь можно для роутера объявить глобальные маркеры типа {locale} и тп.

                                                        Можете определить, например, в своем ServiceProvider

                                                        app("url")->setDefaultNamedParameters(["locale", app()->getLocale(), "userId" => app("auth")->user()->getKey()]);
                                                        


                                                        а потом использовать в роутерах

                                                        app('router')->pattern('locale', '(' . implode('|', config('app.locales')). ')');
                                                        app('router')->group(['domain' => '{locale}.telenok.com'], function ()
                                                        {
                                                            app("router")->post("some-url", array("as" => "some-name", "uses" => "SomeClass@somemethod"));
                                                        });
                                                        
                                                          +1
                                                          Пока этого нет в документации, использовать не советуется, т.к. Тейлор любит убирать незадокументированные фичи, в текучем релизе есть такие поломки BC.
                                                            0
                                                            Проверил — на месте

                                                            https://github.com/laravel/framework/blob/master/src/Illuminate/Routing/RouteUrlGenerator.php#L208
                                                              +2
                                                              Важно ни его наличие в коде, а наличие в документации. Вот пример из неё
                                                              The share method has been removed from the container. This was a legacy method that has not been documented in several years. https://laravel.com/docs/5.4/upgrade#upgrade-5.4.0

                                                                0
                                                                документация на большинстве opensource продуктов неполная… по тому же Request 50% методов не освещены на https://laravel.com/docs/5.4/requests — нет методов merge(), clone() и многих других… поэтому лучшая документация — это код фреймворка
                                                                  +1
                                                                  Нет, потому недокументированными методами и не нужно пользоваться, они могут быть удалены без предупреждения. Я даже пример привёл.
                                                                    +1
                                                                    пример апгрейда, при котором, само собой, методы могут исчезнуть, были они задокументированы или не были
                                                          –8
                                                          Я человек простой: вижу пост о Laravel — ставлю лайк (если, конечно, он годный).
                                                            0
                                                            Осталось дождаться Множественные в JSON-переводах.
                                                              0
                                                              о чем речь, что такое Множественные в JSON-переводах?
                                                                0
                                                                plurals в конструкции __()
                                                              0
                                                              как-то уж очень бодро выпиливает Тейлор код от версии к версии. Сейчас радостно перешли на Dusk и при этом выпилили большой пласт ассертов для тестов seeJson*
                                                                0

                                                                Ох, если бы это было только единственное фатальное изменение… Были и другие: https://github.com/laravel/internals/issues/391

                                                                  0
                                                                  как теперь передавать параметры в конструктор?
                                                                    0

                                                                    Через биндинг, ака singleton(), bind(), etc.

                                                                      0
                                                                      хм… спасибо
                                                                –1
                                                                У laravel отличная документация + крутое сообщество.
                                                                  0
                                                                  Десант Фабьена уже высаживался в комментариях?

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

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