我正在将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
(从可为空的状态变为仅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