首页 > 解决方案 > 如何检查可空类型严格的代码气味

问题描述

我正在将 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

标签: phpphpstormphp-7strict

解决方案


推荐阅读