Всем привет!

Это дайджест новостей от CutCode[ссылка удалена мод.]. Давайте посмотрим, что произошло за прошедший месяц в мире PHP и Laravel.

Новости PHP

Первый релиз-кандидат PHP 8.4 доступен для тестирования

Релиз-менеджеры Calvin Buckley, Saki Takamachi и Eric Mann создали ветку PHP-8.4, теперь разработка будет вестись в ней, а master ветка теперь нацелена на следующую версию PHP. Перед финальным выпуском, который ожидается 21 ноября, нас ожидает еще 3 релиз-кандидата.

Вышли PHP 8.1.30, PHP 8.2.24 и PHP 8.3.12

В этих выпусках исправлены:

  • Уязвимость инъекции параметров в CGI (CVE-2024-8926).

  • Обход из-за коллизии переменной окружения директивы cgi.force_redirect (CVE-2024-8927).

  • Возможность изменения логов от дочерних процессов FPM (CVE-2024-9026).

  • Ошибки при разборе данных многокомпонентных форм (CVE-2024-8925).

Пожалуйста, обновитесь, как можно скорее.

PHP-линч #22

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

PHP Russia 2024

2 и 3 декабря в Москве пройдёт конференция Highload, в рамках которой 16 докладов будут выделены под PHP Russia. Список докладов уже опубликован на сайте конференции.

Laravel привлёк $57 млн ​​в рамках серии A от Accel

Сразу после Laracon US Taylor Otwell опубликовал твит, в котором объявил об инвестициях в размере 57 миллионов долларов от Accel, известной венчурной компании. Поздравляем Тейлора и команду!

Кстати, Роман Пронский побывал на Laracon US и пообщался с разными ребятами из PHP-сообщества:

Inside Laracon 2024: PHP's Festival of Innovation and Connection

Новости ядра PHP

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

?RFC: Deprecate json_encode() on classes marked as non-serializable

В PHP, классы, непригодные для сериализации помечаются с помощью флага ZEND_ACC_NOT_SERIALIZABLE, который не позволяет сериализовать экземпляры таких классов с помощью функции serialize().

Однако этот флаг в настоящее время игнорируется функцией json_encode(), которая является другим способом сериализации, встроенным в PHP.

Philip Hofstetter предлагает запретить сериализовать с помощью функции json_encode() большинство экземпляров классов, отмеченных флагом ZEND_ACC_NOT_SERIALIZABLE и выдавать предупреждение об устаревании, начиная с PHP 8.5.

?RFC: Change Directory class to behave like an opaque object

Класс Directory, вероятно, является первым экземпляром того, что мы сейчас называем «непрозрачным объектом». Непрозрачные объекты обычно являются результатом преобразования ресурсов в объекты, что в общем случае подразумевает, что они являются окончательными, не сериализуемыми, не инициализируемыми с помощью ключевого слова new, не могут быть приведены и не реализуют никаких методов. Однако, поскольку этот класс существует со времен PHP 4, ничего из этого формально не реализовано.

Gina Peter Banyard предлагает изменить класс Directory:

  • Пометить его окончательным.

  • Выбрасывать ошибку при инициализации с помощью ключевого слова new.

  • Предотвратить клонирование экземпляров класса Directory.

  • Запретить сериализацию с помощью doc-комментария @not-serializable к заглушке класса.

  • Запретить создание динамических свойств для экземпляра класса Directory с помощью doc-комментария @strict-properties к заглушке класса.

?RFC: Warn on conversions from resource to string

PHP уже давно выполняет различные виды преобразования типов. В то время как большинство сомнительных случаев таких преобразований в настоящее время выбрасывает ошибку TypeError или, по крайней мере, выдает ошибку уровня E_WARNING, при преобразовании ресурса в строку ничего подобного не происходит.

Учитывая, что ресурсы постепенно уходят в сторону непрозрачных объектов и не поддерживают преобразование в строки, Gina Peter Banyard предлагает выдавать ошибку уровня E_WARNING, при преобразовании ресурса в строку.

Laravel дайджест

Обновления Laravel

11.22 Eloquent inverse relations 

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

PR, который затрагивает Eloquent и добавляет новый метод, о котором говорил Taylor на последнем Laracon. Он называется Chaperone. Он решает проблему N+1.

Давайте рассмотрим пример:

@foreach($post->comments as $comment)
  <!-- comment content -->
  @can('promote', $comment)
    <a href="{{ route('posts.comments.promote', [$post, $comment]) }}">promote</a>
  @endcan
@endforeach

У нас есть посты, мы также добавляем eager load с комментариями и вынуждены также добавлять eager load с родительским постом у комментариев, чтобы не попасть на исключение при strict mode и в целом, не плодить запросы. Хотя казалось бы, у нас и так есть родительская модель и логично было бы ее засетить ко всем загруженным комментариям. Как раз метод Chaperone это и делает. В pull request он называется inverse, в последующем он был переименован, а также добавлен, видимо, для обратной совместимости. И суть в итоге в том, что мы проходимся по всем загруженным моделькам и делаем set relation родительской записи. Я думаю, многие из вас это делали вручную. Теперь сможем ускорить процесс с помощью нового метода.

11.22 Allow enums to be passed to routes

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

Pull request добавляет поддержку указания name в route через enum. Ниже приведен пример:

// before
Route::domain(InterfaceDomain::Marketing->value)->name(Routes::Home->value)->get('/contact', ContactController::class);

// after
Route::domain(InterfaceDomain::Marketing)->name(Routes::Home)->get('/'contact, ContactController::class);

До этого приходилось вызывать value, теперь можно просто указать enum и под капотом все сработает.

11.23 Adding minRatio & maxRatio rules on Dimension validation ruleset

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

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

function ($attribute, $value, $fail) {
    [$width, $height] = getimagesize($value->getPathname());
    $aspectRatio = $width / $height;
    if ($aspectRatio > 1 / 2 || $aspectRatio < 1 / 3) {
        $fail("The image aspect ratio must be between 1:2 and 1:3.");
    }

11.23 Add BackedEnum support to Gate methods 

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

Снова Enum. На этот раз не Route, а Gates, и мы также можем объявлять и далее во многих методах взаимодействовать с Gates через Enum. Как видим в примерах, до этого через строку, теперь то же самое можем делать с Enum, который возвращает строку и соответственно в методах указывать именно enum. Отлично, гораздо удобнее, чтобы не держать эти строки в памяти.

enum Abilities: string {
    case VIEW_DASHBOARD = 'view-dashboard';
    case EDIT = 'edit';
    case UPDATE = 'update';
}


// Before
Gate::define('view-dashboard', function (User $user) {
    return $user->isAdmin;
});

Gate::authorize('view-dashboard');
Gate::inspect('view-dashboard');
Gate::check('view-dashboard');
Gate::any(['edit', 'update], $post);
Gate::none(['edit', 'update]], $post);
Gate::allows('update', $post)
Gate::denies('update', $post)

// After
Gate::define(Abilities::VIEW_DASHBOARD, function (User $user) {
    return $user->isAdmin;
});

Gate::authorize(Abilities::VIEW_DASHBOARD);
Gate::inspect(Abilities::VIEW_DASHBOARD);
Gate::check(Abilities::VIEW_DASHBOARD);
Gate::any([Abilities::EDIT, Abilities::UPDATE], $post);
Gate::none([Abilities::EDIT, Abilities::UPDATE], $post);
Gate::allows(Abilities::UPDATE, $post)
Gate::denies(Abilities::UPDATE, $post)

11.23 Add BackedEnum support to Authorize middleware

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

Двигаемся дальше по релизу 11.23. Снова Enum. И теперь они также допускаются в объекте Authorize методе using.

 Route::get('/dashboard', [AdminDashboardController::class, 'index'])->middleware(Authorize::using(Abilities::VIEW_DASHBOARD))->name(AdminRoutes::DASHBOARD);

11.23 Add Skip middleware for Queue Jobs 

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

Pull request добавляет новый middleware для очередей, который называется Skip. С помощью него можно в методы when и unless указывать условия, при выполнении которых выполнение очереди будет пропускаться. Нам показывают также пример, что раньше автор решал проблему пропуска через замыкание и соответственно сделал middleware, чтобы не дублировать эту логику, хотя в целом и непонятно, почему не добавить условия просто в handle.

class MyJob implements ShouldQueue
{
    use Queueable;

    public function handle(): void
    {
        // TODO
    }

    public function middleware(): array
    {
        return [
            function ($job, $next) {
                if ($someCondition) {
                    $next($job);
                }
            },
        ];
    }
}

11.23 Add Eloquent\Collection::findOrFail 

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

Следующий pull request затрагивает коллекции Eloquent, в которых добавлен метод findOrFail. У новичков часто возникает проблема - после совершения запроса, который возвращает коллекцию с данными, новичок продолжает дергать методы queryBuilder, ожидая, что у нас все еще queryBuilder, а не коллекция, и натыкается на ошибку. Метод findOrFail у нас уже и есть коллекция и он будет по ID искать нужные модельки в этой коллекции. Но я думаю, есть вероятность, что это только добавит путаницы для новичков, но в целом вот такой сахар добавили в Eloquent коллекции.

$users = User::get(); // [User(id: 1), User(id: 2)]
$users->findOrFail(1); // User
$user->findOrFail([]); // []
$user->findOrFail([1, 2]); // [User, User]
$user->findOrFail(3); // ModelNotFoundException: 'No query results for model [User] 3'
$user->findOrFail([1, 2, 3]); // ModelNotFoundException: 'No query results for model [User] 3'

Laracon 2024

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

Далее у нас огромный pull request от Taylor, на котором я уже сделал обзор на канале, обязательно посмотрите. Это Helper Defer, фасад Concurrency и метод Flexible у кэша. Мы разобрали все подробно, заглянули под капот - обязательно посмотрите ролик на канале.

11.23  New when() helper

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

И напоследок по релизу 11.23 это новый Helper When, хотя не совсем Helper, а Blade-директива, благодаря которой можно указать условия и вторым параметром вывести определенные данные, как мы это видим в примерах в этом pull request.

<div @when($condition, 'wire:poll.5s="myMethodName"', false)>

<input name="phone" @when($isRequired, 'required') />

11.24 add nullOnUpdate() method to ForeignKeyDefinition 

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

Pull request затрагивает Schema. До этого у нас был nullOnDelete(), также добавлен и nullOnUpdate(). Кто ожидал - новый сахар добавлен.

$table->foreign('user_id')
      ->references('id')
      ->on('users')
      ->nullOnUpdate();

11.24 Allow BackedEnum to be passed to Route::can()

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

Снова Enum, снова роуты. Метод can() также принимает Enum начиная с этого релиза.

11.25

Также появился релиз 11.25, но он исключительно из фиксов и ревертов, ничего интересного.

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

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


  1. t38c3j
    11.10.2024 22:03

    57 миллионов долларов от Accel

    В какой-то ларавел инвестировали да еще не мало, а более значимые проекты типа гном и кде скребут по сусекам. Что с этим миром не так...


    1. isumix
      11.10.2024 22:03

      Кеды рулят ;)


  1. isumix
    11.10.2024 22:03

    Увидел фото авторов, подумал из серии "разыскиваются военкоматом", зашел посмотреть))