Я конвертирую проект Symfony 3.4, чтобы полностью использовать строгие типы PHP 7.Это действительно здорово, как в обычных, более строгих языках программирования.
Я заметил нечто очень неправильное в процессе преобразования.Допустим, на других языках программирования у вас есть:
*string == nil (valid)
*string == string (invalid)
*string == *int (invalid)
В PHP у вас есть:
?string == null (valid)
?string == string (valid)
?string == ?int (valid)
Это последнее ?string == ?whatever
- это то, что теперь остается после добавления всей строгости к параметрам и методувозвращаемые значенияПроблема в том, что код теперь содержит тонны бомб с запахом кода, что уже вызвало у меня тонны неожиданных ошибок в режиме разработки.
Я знаю, что это не совсем возможно, потому что PHP не знает самих типов указателей,но мне было интересно, есть ли плагин PHPStorm, или что-то вообще, что может на самом деле найти эти возможные запахи кода.
Так что он будет соответствовать ?string == ?int
как неисправный (уровень ошибки), тогда как ?string == null
все еще в порядке,И что-то вроде ?string > string
(переход из nullable в string
может быть ошибочным (уровень предупреждения).
Я не могу быть единственным человеком, который столкнулся с этой проблемой. Как проект, который япреобразование является массовым и раньше в нем не было тестов, написанных на них. Надеюсь, что тестирование всех путей (буквальный просмотр) в приложении отлавливает большинство стандартных конфликтов, но вы можете просто предсказать, что в данных есть большая вероятность- разница в том, что он выдаст несколько ошибок, когда рабочая версия получит все пути кода с тонной дисперсией данных.
Обновление
<?php
declare(strict_types=1);
class SaleOrder
{
private $price;
private $fee;
private $number;
public function setPrice(?float $price): self
{
$this->price = $price;
return $this;
}
}
function generateStringedPrice(): ?string
{
return '420.00';
}
function generateStringedNulledPrice(): ?string
{
return null;
}
$price = 420.0;
$priceNulled = null;
$priceString = generateStringedPrice();
$priceStringNulled = generateStringedNulledPrice();
$order = new SaleOrder();
$order->setPrice($price); // OK
$order->setPrice($priceNulled); // OK
$order->setPrice($priceString); // Fatal, but not seen by PHPStorm because null fits in null, but it doesn't "smell" that when it knows `?float` and `?string` are in play it could give a warning that when `?string` is not null, it might cause a fatal (which it does, but you can't instantly detect it with different data flowing through the code from different sources)
$order->setPrice($priceStringNulled); // OK, it doesn't care ?float and ?string were in play; null is null; no one cares :P