Всем привет!
Это PHP Дайджест отCutCode. Давайте посмотрим, что произошло за прошедший месяц в мире PHP.
Новости PHP
ВышлиPHP 8.1.29,PHP 8.2.20иPHP 8.3.8
В этих выпусках исправлены уязвимости:
-
Инъекция аргументов в PHP-CGI.
-
Обход фильтра FILTER_VALIDATE_URL в функции filter_var.
-
Экранирование аргументов для bat- и cmd файлов в Windows окружении для функции proc_open.
-
Уязвимость к атаке Marvin функции openssl_private_decrypt.
Пожалуйста, обновитесь, как можно скорее.
PHP исполнилось 29 лет!
8 июня 1995 года Rasmus Lerdorfвпервые объявило PHP.
Рома Пронский опубликовал ролик, в котором он скомпилировал и запустил первую версию языка. Посмотрите, каким был PHP 29 лет назад.
С днем рождения, PHP! 🎉🥳🎂
Митап на Таганской
Прошел митап Beer PHP Moscow, на котором выступили с докладами про профилирование и асинхронные PHP-приложенияАлексей Сидоркин(Архитектор ГК Т1),Максим Хасанов(Team lead, АльфаСтрахование) иВалентин Удальцов(автор каналов Пых и PHP Point, преподаватель Хардкорного курса PHP).
Lamoda Tech Meetup
Прошел еще один митап от команды Lamoda Tech на котором выступили Михаил Мохначёв и Константин Козин, рассказав как почти безболезненно перейти на язык Go PHP-разработчику.
Developer Ecosystem Survey 2024
Команда JetBrains запустила восьмое ежегодное исследование экосистем разработчиков, посвященное текущему состоянию индустрии разработки программного обеспечения.
Прохождение опроса не займет много времени, а JetBrains, как всегда, поделится результатами исследования.
Projects IDX
Google анонсировала свой новый инструмент онлайн-среды разработки, который поставляется сшаблоном Laravel из коробки.
В своем личном телеграм канале Данил ужеподелился первыми впечатлениями, почитайте, если еще видели.
Большинство новостей ядра PHP подробно освещаются в серииPHP Core Roundupот PHP Foundation, мы лишь быстро по ним пробежимся:
✅ RFC: Add stream open functions to XML{Reader,Writer}
Niels Dossche предлагает добавить два новых метода для работы с потоком модуля XML:
XMLReader::fromStream()
XMLWriter::toStream()
📣 RFC: Static Constructors
Erick de Azevedo Lima предлагает добавить новый магический метод__staticConstruct
, который будет вызываться автоматически при вызове статического метода.
📣 RFC: Static class
Paul Morris предлагает добавить новый тип класса – статический. Статический класс определяется ключевым словом static, а все методы этого класса автоматически становятся статическими. В настоящее время в PHP можно объявить статическими отдельные методы.
📣RFC: Lazy Objects
Arnaud Le Blanc и Nicolas Grekas предлагают добавить ленивые объекты в PHP.
Ленивые объекты не будут инициализироваться до тех пор, пока в этом нет необходимости, например, не будет прочитано или изменено свойство объекта.
Ленивые объекты большинство пользователей не будут использовать напрямую, в первую очередь они предназначены для авторов библиотек и фреймворков.
📣RFC: Deprecations for PHP 8.4
Группа авторов Niels Dossche, Gina Peter Banyard, Máté Kocsis, Tim Düsterhus, Kamil Tekiela и Jorg Sowa запустила обсуждение RFC, чтобы определить какой функционал объявить устаревшим в PHP 8.4 и удалить в PHP 9.0.
Laravel дайджест
Обновления Laravel
11.10. Allow callback to be passed toupdateOrInsert()to pass different$valuesif the record already exists
https://github.com/laravel/framework/pull/51566
PR затрагивает QueryBuilder, прокачали методupdateOrInsert()
. Описание PR начинается с проблемы.
Я думаю, вы знаете, чтоupdateOrInsert()
под капотом в себе содержит два запроса. Сперва мы ищем, есть ли такая запись. Соответственно, если есть, то делаемUpdate
, в противном случаеInsert
. Но если, как в примере у автора:
$values = [
'name' => $data['name'],
'email' => $data['email'],
];
$exists = DB::table('users')->where('user_id', $user_id)->exists();
if (! $exists) {
$values['optional_column'] = $data['foobar'];
}
DB::table('users')->updateOrInsert(
['user_id' => $user_id],
$values
);
нам необходимо сделатьUpdate
полей с дополнительным условием, например, если запись существует, то набор полей будет иным. В таком случае нам придется сперва дополнительно проверить, есть ли запись. Далее на проверке уже сформировать массив и уже после вызвать этот сахар.
Казалось бы, зачем вообще всем этим заниматься? Сделай отдельные два запроса без сахара Laravel, но это не путь Laravel, поэтому прокачали методupdateOrInsert()
. Вторым параметром можно теперь передать callback, который в себе будет иметь boolean-значение, есть ли уже запись в таблице, и если есть, мы можем строить дополнительные условия и формировать массив наupdateOrInsert()
:
DB::table('users')->updateOrInsert(
['user_id' => $user_id],
function ($exists) use ($data) {
if ($exists) {
return [
'name' => $data['name'],
'email' => $data['email'],
];
}
return [
'name' => $data['name'],
'email' => $data['email'],
'optional_column' => $data['foobar'],
];
}
);
11.11. Give session ID retrieval the Laravel treatment
https://github.com/laravel/framework/pull/51732
Первый PR у нас затрагивает сессии, теперь нам не придется писать такой длинный методgetId
и появился простоId
:
use Illuminate\Support\Facades\Session;
- Session::getId();
+ Session::id();
В изменениях PR видим, что Id
это обертка над методомgetId
.
11.11. Add get, write and forget cache events
https://github.com/laravel/framework/pull/51560
В следующем PR, появились события по кэшу. В изменениях по PR, видим, что добавлен набор событий:

И соответственно в репозитории, когда сбрасываем кэш или добавляем в кэш, будут дергаться определенные события и теперь появились дополнительные возможности для отслеживания и взаимодействия.
11.11. Add before and after methods to Collection
https://github.com/laravel/framework/pull/51752
PR затрагивает коллекции. Добавлены два новых методаbefore
иafter
. У нас есть коллекция, как в примере:
$collection = collect([1, 2, 3, 4, 5, 'name' => 'taylor', 'framework' => 'laravel']);
$collection->before(2) // 1
$collection->before('taylor') // 5
$collection->before('laravel') // 'taylor'
$collection->before(fn ($value) => $value > 4) // 4
$collection->before(fn ($value) => ! is_numeric($value)) // 5
$collection->before(1) // null
$collection->before('not found') // null
Благодаря методуbefore
мы можем указать значение одного из элементов коллекции и получить предыдущее.
Например, через методbefore
указываем двойку - получаем предыдущее значение - единицу, указываем значение taylor, получаем пятерку. Также поддерживается и callback.After
выполняет то же самое действие, только после указанного элемента.
11.11. About command improvement
https://github.com/laravel/framework/pull/51791
Простой PR, который продолжает улучшать artisan-командуabout
- добавили переменные timezone и locale из текущего конфига.
11.11. Add Relation::getMorphAlias()
https://github.com/laravel/framework/pull/51809
Следующий PR добавляет новый метод у класса Relation, чтобы получить alias у Morph-типа модели. Как видим просто указываем модель и получаем alias если он у нас ранее зарегистрирован.
$this->assertDatabaseHas('taskables', [
'taskable_type' => Relation::getMorphAlias(Document::class),
'taskable_id' => $mitigation->id,
'task_id' => $taskB->id
]);
11.11. Support third-party relations in model:show command
https://github.com/laravel/framework/pull/51807
PR прокачивает artisan-командуmodel:show
(находит отношения модели). Теперь эта команда будет демонстрировать нам также third-party relations, например из пакетов.
11.11. Chop PHP extension when passed to make commands
https://github.com/laravel/framework/pull/51842
Раньше при вызове команд которые генерируют определенные классы, если указать расширение.php
, то у вас будет сформирован класс с двойным расширением. Благодаря этому pull request, если вдруг и прописали расширение, то оно у нас будет тримиться.
До:
php artisan make:controller UserController.php
# Controller [app/Http/Controllers/UserController.php.php] created successfully.
После:
php artisan make:controller UserController.php
# Controller [app/Http/Controllers/UserController.php] created successfully.
11.12. Add multiply to collection
https://github.com/laravel/framework/pull/51870
PR по коллекциям, на этот раз добавили методmultiply
. Что он из себя представляет? Например, у нас есть коллекция с определенным набором:
<div>
{{ $user->name }}
{{ $user->name }}
{{ $user->name }}
{{ $user->name }}
div>
Multiply
их будет дублировать и повторно пушить указанное количество раз:
@foreach($class->students->multiply(4) as $student)
<x-student :student="$student" />
@endforeach
11.12. Add multiply to collection
https://github.com/laravel/framework/pull/51870
PR добавляет в EventServiceProvider статический метод, который позволяет указывать где именно нам автоматически искать наши ивенты. И таких директорий может быть несколько. Можем указать либо строкой, либо в виде массива.
11.13. Account for long strings on new Laravel error page
https://github.com/laravel/framework/pull/51880
PR прокачивает верстку новой error page. Поправлены моменты, когда длинные строки с содержанием ошибки ломали верстку или выходили за экран на дисплеях с небольшим разрешение. Проблемы решены и error page выглядит еще лучше.
11.13. Add Support for Extensions in Str::markdown Method
https://github.com/laravel/framework/pull/51907
Следующий PR затрагивает Helper по работе со строками. МетодMarkdown
. Третим параметром также принимает набор extension из набора CommonMark:
public function parseMarkdownFromFile($file_location){
$markdown_contents = File::get($file_location);
$html = Str::markdown($markdown_contents, [], [
new AttributesExtension(),
new TaskListExtension(),
]);
return $html;
}
Автор PR даже снял минутный ролик о том как это работает. Как это выглядело до и как он прокачал рендер Markdown.
11.13. Update config:show command
https://github.com/laravel/framework/pull/51902
PR который прокачивает командуconfig:show.
До этого были проблемы с отображением конфига через "dot"-нотацию. Ошибка если конфиг не найден была некорректной - теперь исправили.
11.13. Display view creation messages
https://github.com/laravel/framework/pull/51925
Следующий PR улучшил отображение информации. Раньше при создании компонента у нас отображалось, что компонент по указанному пути успешно создан, но при этом не говорилось о том, что также создана вьюха. Теперь эта проблема решена.
11.13. Introduce Str::chopStart and Str::chopEnd
https://github.com/laravel/framework/pull/51910
Прокачали Helper-класс по работе со строками, добавили несколько новых методовChopEnd
,ChopStart
,ReplaceEnd
иReplaceStart
.ChopEnd
нам дает возможность получить значение строки до указанного выражения и аналогичноChopStar
(только указываем после какого значения). Также можно передавать массив с несколькими значениями:
Str::chopEnd('path/to/file.php', '.php');
// "path/to/file"
Str::chopStart('https://laravel.com', ['https://', 'http://']);
// laravel.com
МетодreplaceEnd
заменяет окончание строки на указанное значение, если эта строка заканчивается на определённую подстроку. Аналогично работаетReplaceStart
.
Видео-версия дайджеста: