PHP Fart Time
1.72K subscribers
75 photos
3 videos
2 files
162 links
Привет, фартаны!

Дурачимся, пилим OpenSource и рассказываем про пердовые технологии в php.

Авторы контента: @roxblnfk и @butschster
Download Telegram
Channel created
Channel photo updated
Скоро запроцессится ещё одно
https://youtu.be/lpOax1iGVkE
Релизим Spiral инсталлятор, сосисочная вечеринка на 6 персон
Рассматриваем Storybook в контексте обновления фронтовой части нового Buggregator.
Поверхностное рассмотрение демонстрационного проекта Ticket Booking, в котором интегрировано всё сразу: #Spiral, #Zipkin, #Birddog, #OpenTelemetry, #Grafana, #RoadRunner, #Centrifugo и #Temporalio.

https://youtu.be/Zk9E3ZBDtb8

Вуху, у нас есть чат! Теперь наши высеры можно комментировать! :)
Please open Telegram to view this post
VIEW IN TELEGRAM
PHP Fart Time
https://youtu.be/IGRI4I_nnQM Репка с бечами https://github.com/php-fart/benchmarks-serializers
Хотел, было, добавить детализации в тексте поста, но при работе с цифрами бенчей возникли вопросы.
Как этот инструмент считает avg?
Оказывается, при расчёте среднего значения исключаются 10% максимальных и 10% минимальных значений. Not bad.
#Hint
А я напомню, что атрибуты можно использовать и в PHP 7.4 с помощью пакета spiral/attributes:^2.7

https://t.me/isPHPdying/143
#Article #Типизация #php

#️⃣ Типизация PHP

Наверное буду кэпом, если скажу, что следование строгим типам и избежание неявных преобразований уменьшает магичность кода, что ведёт к стабильности и надёжности.
Поэтому в коде Spiral, Cycle и других наших продуктов мы используем строгую типизацию, где это возможно.
Вроде тема понятная, но... это же PHP. А значит без нюансов не обойтись 💩

⭕️ declare(strict_types=1);

Прям из доки: по умолчанию, PHP будет преобразовывать значения неправильного типа в ожидаемые. ...
Можно включить режим строгой типизации на уровне файла.
В этом режиме, тип значения должен строго соответствовать объявленному, иначе будет выброшено исключение TypeError.
Единственным исключением из этого правила является передача значения типа int туда, где ожидается float.

⚠️ На вызовы из внутренних функций, действие strict_types не распространяется.

Обратите внимание на предупреждение. Многие core-функции не следуют строгости типов.
Например, array_map() и array_filter() сделают неявное приведение типов.

print_r(array_map(fn(int $a, int $b) => $a + $b, [1, '10', 3], [4, 5, '1e2']));
---
Array (
[0] => 5
[1] => 15
[2] => 103
)


А вот call_user_func() будет ругаться на несоответствие типов.

Рефлексия тоже не следует строгости. Поэтому вместо newInstanceArgs/newInstance в фабрике контейнера у нас $instance = new $class(...$arguments);.
Оно, может, чуть медленнее, но зато надёжнее.

Теперь к костылям.

⭕️ Типизация переменных

С помощью несложного текучего костыля можно привязать тип к переменной.

function makeInt(int &$i): void
{
static $list = [];
$list[] = $obj = new class() {
public int $i;
};
$obj->i = &$i;
}

$int = 1;
makeInt($int);

$int = 42; // 42
$int = 'foo'; // Fatal error: Uncaught TypeError: Cannot assign string...


Не делайте так.

⭕️ PHP 8.2

Типы null, false и true теперь можно использовать автономно.
Зачем это надо? Для вариантности. Например, при расширении метода возвращаемое значение с bool можно сузить до true или false, а nullable (?Foo) — до null. Таких кейсов в библиотеках не мало.

Завезли DNF (Disjunctive Normal Form).
Вот такого мутанта теперь можно будет встретить в коде: (Countable&Traversable)|array

ℹ️
Что интересно, nullable-сахар (?Foo) был добавлен в PHP 7.1 ещё до Union Types.
ℹ️ Всегда явно указывайте тип nullable параметров (?Foo $foo = null) а не полагайтесь только на значение null по умолчанию (Foo $foo = null).
ℹ️ Тип never был добавлен в PHP 8.1. Но он вряд ли вам пригодится, если вы гоняете на RoadRunner.
ℹ️ Тип callable существует только в сигнатурах функций и методов. Его нельзя указать для свойств, а значит и в Promoted properties не засунуть. А всё потому, что в разных контекстах callable может быть разным.
Как же принять callable и записать в свойство? Например так:

// A class declaration
private \Closure $callback;

public function __construct(callable $callback)
{
$this->callback = $callback(...);
}


Может у вас есть какие-то мысли, нюансы или лайфхаки вокруг типов PHP? Поделитесь в комментариях