Всем привет!
Это 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.
Видео-версия дайджеста: