Блог Валентина Удальцова о разработке на PHP.
Хобот @phpyhobot
https://youtube.com/@phpyh
https://vkvideo.ru/@phpyh
https://t.me/isPHPdying
Статистика: https://t.me/INOTAROBOT?start=st1219340804
Для связи используйте личные сообщения канала.
Post #950
8.12K
Горю с PHPStan
Все привыкли ограничивать дженерики типов сверху (upper bound):
Пример. Представьте, что существует ссылка на какое-то значение и нужно заапкастить (преобразовать в супертип) тип значения в этой ссылке:
В Java wildcards это выражается так:
В PHPStan, о чудо, тоже начали об этом думать аж в 2021 году: phpstan/phpstan/issues/5179.
Я был в курсе, и, не глядя в issue, решил попробовать. Пишу:
Анализатор говорит No issues!, я радостно продолжаю работать. А потом намеренно пробую вызвать
Разбираюсь и понимаю, что PHPStan поддержал пару лет назад синтаксис
Представьте, что в PHP добавили property hooks только на уровне синтаксиса — по факту они вообще не работают. Как вам такая фича?
Между PHP-анализатором и PHPDoc-парсером есть фундаментальный каплинг (то есть, кохижен). Нельзя поправить одно и не учесть это в другом. Нормально разделять компоненты и делать один более универсальным, но тогда должны быть фича-флаги, при помощи которых второй компонент выключает (opt-out) или не включает (opt-in) неподдерживаемое поведение в первом.
⸻
Этот пост я разместил неделю назад в 🐘 PHPeople.
GitHub Lower bounds support · Issue #5179 · phpstan/phpstan Support of lower bounds for generics / templates Hi, first of all, thanks for all the great work, that has been done on generics lately. To have generics more complete I suggest to introduce lower ... Все привыкли ограничивать дженерики типов сверху (upper bound):
@template T of U. Но бывают ситуации, когда дженерик логично ограничить снизу (lower bound), в частности другим дженериком.Пример. Представьте, что существует ссылка на какое-то значение и нужно заапкастить (преобразовать в супертип) тип значения в этой ссылке:
use Psr\Log\LoggerInterface as Logger;
use Monolog\Logger as Monolog;
use Typhoon\Type;
/**
* @template T
*/
interface Ref
{
/**
* @template S, где S — супертип для T
* @param Type<S> $super
* @return self<S>
*/
public function as(Type $super): self;
}
/**
* @param Ref<Monolog> $ref
* @return Ref<Logger>
*/
function upcastLogger(Ref $ref): Ref
{
return $ref->as(Type\objectT(Logger::class));
}
В Java wildcards это выражается так:
? super T. В Scala оператором: [S >: T].В PHPStan, о чудо, тоже начали об этом думать аж в 2021 году: phpstan/phpstan/issues/5179.
Я был в курсе, и, не глядя в issue, решил попробовать. Пишу:
/**
* @template S super T
* @param Type<S> $super
* @return self<S>
*/
public function as(Type $super): self;
Анализатор говорит No issues!, я радостно продолжаю работать. А потом намеренно пробую вызвать
$ref->as(Type\stringT) и всё равно вижу No issues!Разбираюсь и понимаю, что PHPStan поддержал пару лет назад синтаксис
super, но только в PHPDoc-парсере! Исходный тикет в анализаторе всё ещё не закрыт!Представьте, что в PHP добавили property hooks только на уровне синтаксиса — по факту они вообще не работают. Как вам такая фича?
Между PHP-анализатором и PHPDoc-парсером есть фундаментальный каплинг (то есть, кохижен). Нельзя поправить одно и не учесть это в другом. Нормально разделять компоненты и делать один более универсальным, но тогда должны быть фича-флаги, при помощи которых второй компонент выключает (opt-out) или не включает (opt-in) неподдерживаемое поведение в первом.
⸻
Этот пост я разместил неделю назад в 🐘 PHPeople.
- 😁 30
- 👍 12
- ❤ 3
- 🤯 3
- 🥴 3


