Всем привет!

Это PHP Дайджест от CutCode. Давайте посмотрим, что произошло за прошедший месяц в мире PHP.

Новости PHP

Вышли PHP 8.2.19 и PHP 8.3.7

Выпуски с исправлениями ошибок вышли по расписанию.

Вышел Statamic 5

В новой версии CMS для Laravel улучшена производительность, по заверениям разработчиков, наблюдалось увеличение скорости от 50 до 600%. Также улучшена работа с командной строкой и добавлена возможность добавлять новые сайты непосредственно из админки.

Statamic 5 поддерживает Laravel 11, а также добавлена поддержка Laravel Reverb и Laravel Prompts.

Открыта программа раннего доступа PhpStorm 2024.2

В новой версии добавлена поддержка стиля кода PER, а также упрощен рефакторинг выражений.

Ознакомьтесь бесплатно с последними функциями, которые были добавлены в IDE до официального релиза.

Большинство новостей ядра PHP подробно освещаются в серии PHP Core Roundup от PHP Foundation, мы лишь быстро по ним пробежимся:

RFC: new MyClass()->method() without parentheses RFC Валентина Удальцова прошел этап голосования и был принят. Новый синтаксис, который позволит не оборачивать new выражения в cкобки при обращении к ним, появится в PHP 8.4.

Поздравляю Валентина с этим прекрасным начинанием и желаю новых одобренных RFC.

В телеграм-канале «Пых» уже набросали идей для новых RFC, напишите в комментариях, а что бы вы хотели добавить в PHP.

RFC: array_find

RFC был принят, четыре новые функции появятся в PHP 8.4:

●     Функция array_find возвращает значение первого элемента, для которого $callback возвращает значение true. Если подходящий элемент не найден, функция возвращает NULL.

●     Функция array_find_key возвращает ключ первого элемента, для которого $callback возвращает значение true. Если подходящий элемент не найден, функция возвращает NULL.

●     Функция array_any возвращает значение true, если $callback возвращает значение true для любого элемента. В противном случае функция возвращает значение false.

●     Функция array_all возвращает значение true, если $callback возвращает значение true для всех элементов. В противном случае функция возвращает значение false.

RFC: Support object type in BCMath RFC, о котором мы говорили в прошлых выпусках, был также принят большинством голосов. Поддержка объектов типов в модуле BCMath появится в PHP 8.4.

? RFC: #[\Deprecated] Attribute

Benjamin Eberlei и Tim Düsterhus предлагают добавить новый атрибут #[\Deprecated] с необязательным текстовым сообщением и параметром since, для указания даты или версии, начиная с которых функция или константа объявлена устаревшими.

В настоящее время существует атрибут #[\JetBrains\PhpStorm\Deprecated] с необязательными параметрами reason, replacement и since, который поддерживается PhpStorm и статическими анализаторами.

?RFC: New ext-dom features in PHP 8.4

Niels Dossche продолжает улучшать модуль DOM. В этом RFC он предлагает добавить поддержку CSS-селекторов, добавить недостающие, но распространенные функции и добавить новые свойства.

?RFC: Transform exit() from a language construct into a standard function

Языковая конструкция exit может использоваться без скобок, если нет необходимости указывать параметр status.

Gina Peter Banyard предлагает изменить тип языковой конструкции exit на обычную функцию:

 function exit(string|int $status = 0): never {}

Laravel дайджест

Обновления Laravel

11.7. Introduce method Rule::array()

https://github.com/laravel/framework/pull/51250

Первый PR затрагивает правила валидации. В класс Rule добавили новый метод Array. До этого у нас было правило валидации с Array в виде строки, часто приходилось пользоваться конкатенацией, и выглядело все это не очень красиво. Теперь с помощью объекта Rule и метода Array можно будет удобно взаимодействовать, передавать массивы, либо просто набор ключей через параметры, и даже поддерживаются коллекции. Таким образом, теперь возможно следующее:

Rule::array();
Rule::array('key_1', 'key_2', 'key_3');
Rule::array(['key_1', 'key_2', 'key_3']);
Rule::array(collect(['key_1', 'key_2', 'key_3']));
Rule::array([UnitEnum::key_1, UnitEnum::key_2, UnitEnum::key_3]);
Rule::array([BackedEnum::key_1, BackedEnum::key_2, BackedEnum::key_3]);

Я думаю, такой метод давно напрашивался.

11.7. Add ability to override the default loading cached Routes for application

https://github.com/laravel/framework/pull/51292

Следующий pull request затрагивает route. Я думаю, все вы прекрасно знаете, что route кэшируются в Laravel, но сама логика кэширования не поддавалась изменению до этого PR. Теперь это все вынесено в отдельный callback и вы можете переопределить логику кэширования, если это требуется.

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        ...
        RouteServiceProvider::loadCachedRoutesUsing(function(){
         
          //logic here 
        });

    }

11.7. Add ->whereJsonOverlaps() for mysql

https://github.com/laravel/framework/pull/51288

На этот раз queryBuilder и новый метод whereJsonOverlaps, который под капотом будет использовать MySQL функцию JSON_OVERLAPS(). В PR расписали, что она из себя представляет, необходима для сравнения двух JSON документов и вернет true, если хотя бы одна пара ключей у нас будет совпадать. Соответственно, первый параметр у нас поле в базе данных, второй - массив с набором ключей, которые мы сравниваем.

User::whereJsonOverlaps('languages', ['en', 'fr'])->exists();
User::whereJsonDoesntOverlap('languages', ['en', 'fr'])->exists();

Вот такой сахарный метод добавили в релизе 11.7

11.7. Add InteractsWithInput methods to ValidatedInput

https://github.com/laravel/framework/pull/51316

Следующий PR затрагивает объект request метод safe, который возвращает объект validatedInput. И если работали просто с объектом request, то в нем присутствовал trait InteractsWithInput и были доступны методы field, boolean, exist и так далее. Вот он список всех методов:

exists, hasAny, whenHas, filledisNotFilled, anyFilled, whenFilled, whenMissing, keys, input,str,string, boolean, integer, float, date, enum, dd, dump

Но при этом, когда мы обращались к объекту validatedInput через safe, у нас был скудный набор методов. Теперь и там присутствует вот этот trait, поэтому весь набор методов доступен:

$request->safe()->filled('test');
$request->safe()->boolean('test');

11.7. Adding PasswordResetLinkSent event

https://github.com/laravel/framework/pull/51253

И напоследок по релизу 11.7 - добавился новый event, который срабатывает, когда мы отправляем ссылку по сбросу пароля. Теперь у нас присутствует это событие и мы можем с вами с ним взаимодействовать.

11.8. Create new "has" validation rule

https://github.com/laravel/framework/pull/51348

PR по правилам валидации. Добавили новое правило валидации has, как указано в title, но на самом деле позже оно было переименовано и стало contains. Его уже и добавили в документацию. Правило сделали для того, чтобы проверить, есть ли значения в массиве из request.

Например, предположим, что вы настраиваете возможность ограничения доступа к определенным IP-адресам. Вы можете настроить некоторые правила следующим образом:

return [
    'allowed_ips'   => ['present', 'nullable', 'array'],
    'allowed_ips.*' => ['required', 'ip'],
];

Однако, необходимо убедиться, что IP-адрес текущего пользователя включен в предоставленный массив входных данных. Действующие правила не предусматривают возможности сделать это. С новым правилом contains будет выглядеть следующим образом:

return [
    'allowed_ips'   => ['present', 'nullable', 'array', contains:' . $request->ip()],
    'allowed_ips.*' => ['required', 'ip'],
];

11.8. Allow adding array or string for web and api routes in bootstrap/app.php

https,//github.com/laravel/framework/pull/51356

Следующий важный PR касается bootstrap/app.php. До этого мы внутри могли указать web route и api route в виде строки, теперь же можем указывать в виде массива и сразу подключать несколько файлов с route. Я думаю, так гораздо удобнее, чем как ранее, когда могли подключить только один файл и внутри уже делать require.

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: [
            __DIR__.'/../routes/web.php',
            __DIR__.'/../admin/web.php',
            ],
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();```

11.8. Adds ability to manually fail a command from outside the handle() method

https,//github.com/laravel/framework/pull/51435

Следующий PR по Jobs. Теперь можно через метод fail самостоятельно зафейлить выполняющуюся job:

public function handle()
    {
        $this->trigger_failure();
    }

    protected function trigger_failure()
    {
        $this->fail('Whoops!');
    }

11.8. MailMakeCommand, Add new --view option

https://github.com/laravel/framework/pull/51411

Небольшой pull request на make:mail команду, которая создает класс по отправке email уведомлений и помимо самого класса создаст и view для email. 

11.8. Add the events to be displayed on the model:show command

https://github.com/laravel/framework/pull/51324

Прокачали команду model:show. Теперь она нам также показывает и все объявленные события в модели.

11.9. Изменения в composer.json

Зависимостей стало еще меньше и мы не видим с вами привычный spatie/ignition, который отвечал за страницу с ошибкой. Также у страницы с ошибкой новый вид:

Теперь она у нас прямо из коробки, выглядит компактно. Здесь минимум информации, но выглядит все стильно. Я думаю сразу у вас возникает вопрос, а как быть, та страница spatie/ignition была намного круче? Не переживайте, можно сделать следующее:

composer require spatie/laravel-ignition 

просто установить зависимость, и после установки мы видим с вами знакомую нам страницу с ошибкой.

11.9. Prevent destructive commands from running

https://github.com/laravel/framework/pull/51376

Появилась интересная фича - новый trait для консольных команд. Внутри - статический метод который позволяет не вызывать в продакшене деструктивные команды. Метод называется Prohibit и в итоге мы с вами прямо в сервис-провайдере можем указать, что MigrateFresh, MigrateRefresh и остальные деструктивные команды не будут вызываться в продакшене, даже если укажете force.

public function boot(): void
{
    FreshCommand::prohibit($this->app->isProduction());
    RefreshCommand:: prohibit($this->app->isProduction());
    ResetCommand:: prohibit($this->app->isProduction());
    WipeCommand:: prohibit($this->app->isProduction());
}

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

DB::prohibitDestructiveCommands($this->app->isProduction());

Видео-версия дайджеста:

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