Всем привет!
Это дайджест новостей от 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, но он исключительно из фиксов и ревертов, ничего интересного.
Видео-версия дайджеста: