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?

Проголосовал 281 человек. Воздержалось 100 человек.

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

Поделиться с друзьями
-->

Комментарии (92)


  1. Agel_Nash
    24.01.2017 20:40
    +3

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

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


    1. dMarley
      24.01.2017 20:45

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


      1. SerafimArts
        24.01.2017 23:27
        +1

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


        1. Agel_Nash
          24.01.2017 23:31

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


        1. dMarley
          24.01.2017 23:41
          -1

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


          1. AmdY
            25.01.2017 01:07
            +4

            Видимо вы об этом


            1. dMarley
              25.01.2017 01:14

              Да.


            1. Agel_Nash
              25.01.2017 01:28
              +1

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


              1. SerafimArts
                25.01.2017 01:55
                +3

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


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


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


              1. Metus
                25.01.2017 10:51
                -1

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



              1. Metus
                27.01.2017 21:48
                +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. SamDark
              25.01.2017 13:57
              +1

              Охренеть.


    1. imgen
      25.01.2017 12:07
      -1

      Вы что-то делаете не так, буквально месяца 3 назад проект перенёс с 5.1 на 5.3 и проблем никаких не было. Возможно, по той причине, что использовались преимущественно стандартные библиотеки, а не стандартные были заменены на стандартные в процессе переноса.


      1. Agel_Nash
        25.01.2017 12:30
        +1

        Ну как минимум, админка требует полного переписывания, т.к. нужно переходить с https://github.com/sleeping-owl/admin на https://github.com/LaravelRUS/SleepingOwlAdmin. Все бы ничего, но в процессе работы добавилось очень много кастомных типов ввода данных: автокомплит, другой визуальный редактор, разметка телефонов, seo поля, редактор json полей. Да, я могу в процессе обновления это все разом переписать — но кто мне за это заплатит? Да, я могу ничего не делать и просто обновить оставив стандартные поля ввода — но как на меня посмотрят клиенты? Так что проект-проекту рознь.


        1. imgen
          25.01.2017 12:52

          Не используем автоматических генераторов, да даже если бы и использовали — есть смысл обратить внимание на voyager. Админка в моём понимании — это обычный crud и это всё генерится прямо из консоли artisan без особых проблем.


          1. Agel_Nash
            25.01.2017 13:20
            +1

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


            1. dMarley
              25.01.2017 13:30

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


              1. Agel_Nash
                25.01.2017 13:49
                +2

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


                1. fallart
                  25.01.2017 16:20
                  +1

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


            1. imgen
              25.01.2017 15:47
              -1

              Под CRUD подразумевал встроенные генераторы классов, не нужно смешивать мелкое с мягким. Пока Вы мне пытались доказать правильность своих решений и не правильность выбора наших. Мы обновились, сели в локомотив 5.4 и поехали дальше, чего и Вам желаю.


              1. Agel_Nash
                25.01.2017 17:54
                +2

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

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

                Тут я имею в виду формы редактирования/добавления данных стандартных форматов


                1. imgen
                  26.01.2017 12:12

                  Такого же уровня админка (еще не завершенная), но созданная без генераторов

                  Небольшой гос проект


                  1. Agel_Nash
                    26.01.2017 13:20

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


    1. uelkfr
      25.01.2017 12:33
      +1

      Сколько с Laravel ни работал, всегда чувствовал что 5.1 нифига не LTS, так как он сам по себе сырой. Всегда приходилось новые проекты на последней версии Laravel начинать.


    1. rixaman
      27.01.2017 11:15
      +1

      Странная политика, вроде фреймворку уже много лет и пора взрослеть.
      Без LTS ларе не захватить вкусный корпоративный (и консервативный) сектор, так и останется хипстерской игрушкой.


  1. iborzenkov
    24.01.2017 23:22
    -6

    Госспади, какой ужас…
    Вот весь ларавель это костыли и подпорки вместо того чтобы чуток почитать сложные места документации симфони.
    Наплодить столько кривых решений это надо уметь, но похоже сейчас markdown в письмах получает премию за самый кривой костыль.


    1. http3
      24.01.2017 23:30
      +2

      Все фреймворки, кроме Simfony — УГ? :)
      Где-то есть нормальное сравнение фреймворков?


      1. iborzenkov
        24.01.2017 23:40
        -7

        Нет конечно, претензии восновном к ларавелю. Из ларавеля торчат уши симфони очень сильно — взяли компоненты симфони которые очень легко использовать, а те которые использовать сложнее потому что они довольно мощные заменили на свое, причем это свое получилось скажем так не очень. Из примеров — Eloquent, Blade и фасады.


        1. pudovMaxim
          25.01.2017 00:01
          -3

          Twig с блоками и Blade со слотами — это прям как из анекдота про немца, русского, украинца и сраку :)


          1. iborzenkov
            25.01.2017 00:13
            -3

            Вот точно :)
            Интересно, они починили блейд?
            https://habrahabr.ru/post/238017/#comment_8316215


          1. pudovMaxim
            25.01.2017 11:09
            -1

            А чего минусите-то? Пользователи Twig и Blade не согласны в «разности» шаблонизаторов? Или кого-то оскорбила срака?


            1. iborzenkov
              25.01.2017 11:58
              -4

              Тут боевой отряд хомячков Тейлора прибежал :)


            1. SerafimArts
              25.01.2017 12:02

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


              1. pudovMaxim
                25.01.2017 13:12

                А embed это не оно?


                1. SerafimArts
                  25.01.2017 13:31
                  +1

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


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


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


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


        1. http3
          25.01.2017 00:07
          +1

          Но Laravel, афаик, — самый трендовый фреймворк 2016 года. :)


          1. iborzenkov
            25.01.2017 00:16
            -4

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


        1. Big_Shark
          25.01.2017 02:48
          +2

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


          1. SerafimArts
            25.01.2017 03:00
            +1

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


            1. iborzenkov
              25.01.2017 03:42
              -4

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


              1. SerafimArts
                25.01.2017 04:41
                +3

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


                1. SerafimArts
                  25.01.2017 06:04

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

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


                  1. pbatanov
                    25.01.2017 11:04

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


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


                1. http3
                  25.01.2017 11:13

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

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

                  Спасибо.


                  1. oxidmod
                    25.01.2017 11:27

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


                    1. SerafimArts
                      25.01.2017 11:54
                      +2

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


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


                      1. oxidmod
                        25.01.2017 12:28
                        +1

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


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


                        1. SerafimArts
                          25.01.2017 12:39
                          +1

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


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


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


                          1. iborzenkov
                            25.01.2017 13:42
                            -2

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

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


                        1. Big_Shark
                          25.01.2017 20:07
                          +1

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


                  1. SerafimArts
                    25.01.2017 11:49
                    +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. SerafimArts
                      25.01.2017 12:10
                      +1

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

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


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


                    1. Metus
                      25.01.2017 13:38

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


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

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


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


                      1. SerafimArts
                        25.01.2017 13:56
                        +2

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


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


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


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


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


                        1. oxidmod
                          25.01.2017 15:28
                          -1

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


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


                          1. pbatanov
                            25.01.2017 16:58

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


                            1. Metus
                              25.01.2017 17:13
                              -1

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


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


                    1. iit
                      25.01.2017 13:52

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

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


                      1. SerafimArts
                        25.01.2017 14:01
                        +1

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


          1. iborzenkov
            25.01.2017 12:13
            -2

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


            1. dMarley
              25.01.2017 12:36
              +3

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


              1. Metus
                25.01.2017 13:30
                +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 вполне обоснована.


                1. dMarley
                  25.01.2017 17:28

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

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


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


    1. ifalur
      25.01.2017 00:40
      +1

      А могли бы конкретные примеры привести? С симфони плотно не работал поэтому интересно. И почему markdown в письмах это костыль?


      1. iborzenkov
        25.01.2017 01:45
        -3

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

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


        1. pilot911
          25.01.2017 03:21
          -2

          У Симфони другие задачи. Относитесь к Ларавелю, как к Yii — для небольших сайтов и быстрого старта они подходят оптимально.

          Симфони хорош для больших архитектур, где необходимы DI через конфиги и тп.


        1. amylabs
          25.01.2017 11:04
          +1

          Markdown письма внтури фреймворка (как и многие другие костыли) из-за того, что так Тейлору удобнее разрабатывать и поддерживать свои коммерческие продукты +)


      1. SerafimArts
        25.01.2017 02:17
        +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 местами гибче симфони.


        1. iborzenkov
          25.01.2017 03:34
          -7

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

          А всякие замечания «прибито гвоздями» просто из-за того что посмотрел код мейлера.
          Извините, но

                  $markdown = Container::getInstance()->make(Markdown::class);
          

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

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


          1. SerafimArts
            25.01.2017 03:42
            +6

            гвоздями к роутеру, как в ларавеле

            шта?


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

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


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

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


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

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


            1. http3
              25.01.2017 12:34

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


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

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


              1. SerafimArts
                25.01.2017 12:57
                +2

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

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


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

                P.S.


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

                </irony>


  1. Prometheus
    25.01.2017 00:43

    Можно вопрос?
    В документации Ларавеля указано в требованиях
    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


    1. JhaoDa
      25.01.2017 00:47
      +3

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


      1. Prometheus
        25.01.2017 01:35
        -1

        Спасибо за разъяснение!
        Так бы я не догадался, что это не «сорок», а просто «четыре».


  1. pilot911
    25.01.2017 00:46
    +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. AmdY
      25.01.2017 01:23
      +1

      Пока этого нет в документации, использовать не советуется, т.к. Тейлор любит убирать незадокументированные фичи, в текучем релизе есть такие поломки BC.


      1. pilot911
        25.01.2017 03:29

        Проверил — на месте

        https://github.com/laravel/framework/blob/master/src/Illuminate/Routing/RouteUrlGenerator.php#L208


        1. AmdY
          25.01.2017 03:48
          +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


          1. pilot911
            25.01.2017 15:43

            документация на большинстве opensource продуктов неполная… по тому же Request 50% методов не освещены на https://laravel.com/docs/5.4/requests — нет методов merge(), clone() и многих других… поэтому лучшая документация — это код фреймворка


            1. AmdY
              25.01.2017 16:57
              +1

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


              1. pilot911
                25.01.2017 17:07
                +1

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


  1. Alexeyco
    25.01.2017 01:45
    -8

    Я человек простой: вижу пост о Laravel — ставлю лайк (если, конечно, он годный).


  1. cjmaxik
    25.01.2017 16:48

    Осталось дождаться Множественные в JSON-переводах.


    1. pilot911
      26.01.2017 20:29

      о чем речь, что такое Множественные в JSON-переводах?


      1. cjmaxik
        27.01.2017 16:15

        plurals в конструкции __()


  1. hlorofos
    30.01.2017 22:23

    как-то уж очень бодро выпиливает Тейлор код от версии к версии. Сейчас радостно перешли на Dusk и при этом выпилили большой пласт ассертов для тестов seeJson*


    1. SerafimArts
      31.01.2017 01:16

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


      1. pilot911
        31.01.2017 17:00

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


        1. SerafimArts
          31.01.2017 19:13

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


          1. pilot911
            31.01.2017 19:16

            хм… спасибо


  1. allokdog
    02.02.2017 00:34
    -1

    У laravel отличная документация + крутое сообщество.