我第一次看到这个声明时,我不知道它是做什么的。我以为这是某种注释,或者是我之前的旧PHP语法,但我错了(大错特错!
)。
在这篇文章中,我们将先容什么是declare(strict_types=1),以及它如何帮助您提高PHP代码的类型安全性。
declare(strict_types=1)是一个启用PHP严格模式并在PHP运用程序中逼迫严格类型的语句。

它是在PHP 7.0中添加的,当时类型声明系统首次在PHP中实现。这意味着它可以在PHP 8项目中利用,因此您可以开始在代码中充分利用严格类型。
当你利用这个语句时,PHP会对函数的参数和返回类型进行严格的类型检讨。这意味着如果一个函数须要某种类型的参数或返回值,如果利用了缺点的类型,PHP将抛出错误。这也适用于具有指定类型提示和返回类型的PHP闭包和箭头函数。
让我们举一个不该用declare(strict_types=1)的大略例子:
function add(int $a, int $b): int{ return $a + $b;}
现在假设我们用字符串参数调用这个函数:
echo add('1', '2'); // Output:// 3
PHP会很高兴地将字符串参数转换为整数并返回结果3。
在某些情形下,您可能完备不介意这种行为。但它可能会产生一些您没有预见到的意外后果,并可能导致运用程序中的缺点。
然而,让我们假设我们想在这个例子中利用declare(strict_types=1)。我们可以通过在文件顶部添加以下语句来实现这一点:
declare(strict_types=1); function add(int $a, int $b): int{ return $a + $b;}
现在,如果我们用字符串参数调用add函数,PHP将抛出一个缺点:
echo add('1', '2'); // Output:// Fatal error: Uncaught TypeError: Argument 1 passed to add() must be of the type int, string given
正如我们在这里看到的,PHP抛出了一个缺点,由于add函数期望通报整数,但却吸收到了字符串。
类似地,如果启用了严格的类型检讨,并且我们试图从方法返回缺点的数据类型,PHP也会抛出错误。例如,假设我们的add函数现在接管浮点数而不是整数,并且我们没有启用严格的类型检讨:
function add(float $a, float $b): int{ return $a + $b;}
我们可以这样调用函数:
echo add(1.25, 2.25); // Output:// 3
你创造输出中的问题了吗?
我们该当得到的答案是3.5。然而,由于我们已经将返回类型定义为int,以是我们已经将浮点数(该当返回的)转换为整数,并失落去了精度。可以想象,这可能会在我们运用程序的其他部分导致一些问题,我们正在利用这个结果,并且可能须要精度。
现在让我们通过利用declare(strict_types=1)来办理这个问题:
declare(strict_types=1); function add(float $a, float $b): int{ return $a + $b;}
我们可以这样调用函数:
echo add(1.25, 2.25); // Output:// Fatal error: Uncaught TypeError: add(): Return value must be of type int, float returned
正如我们所看到的,通过启用严格的类型检讨,我们可以创造函数没有返回与返回类型声明匹配的精确数据类型。这很好,由于它可以突出显示我们代码中可能存在的缺点,而我们并不知道。然后,我们可以采纳必要的步骤:
如果返回类型禁绝确,请更新它们如果类型提示禁绝确,请更新类型提示如果数据类型禁绝确,则更新函数体以返回精确的数据类型修复调用函数的代码中可能向其通报缺点数据类型的任何缺点我该当利用declare(strict_types=1)吗?我个人认为,在所有的PHP文件中利用declare(strict_types=1)是一个好主张。我曾经认为仅仅有类型提示和返回类型就足以确保通报精确的数据类型,但我现在改变了主张。当我利用declare(strict_types=1)时,我对我的代码更有信心,并且由于利用它而创造了一些bug(特殊是当将它添加到旧代码库时)。
由于PHP是一种动态类型的措辞(而不是严格类型的措辞),这意味着如果你不想的话,你根本不须要指定任何返回类型或类型提示。相反,PHP将在运行时为您确定类型。然而,纵然有可能这样做,我还是强烈建议不要这样做。如果你不能在代码中利用严格类型(无论出于什么缘故原由),我仍旧建议利用类型提示和返回类型作为最低限度来提高PHP代码质量。
自从理解它以来,我习气在我创建的每个新PHP文件中利用它。事实上,我更新了PhpStorm设置中的所有模板,以便它自动包含在我创建的每个文件的顶部。例如,下面是创建一个新的PHP类时利用的模板:
<?phpdeclare(strict_types=1);#parse("PHP File Header.php")#if (${NAMESPACE})namespace ${NAMESPACE};#endclass ${NAME} {}
这真的很方便,由于它鼓励我连续利用declare(strict_types=1),而不须要在创建文件后进行任何手动变动(我肯定会忘却这样做!
)。
对付我的任何Laravel阅读器,您还可以在运行Artisan命令(如php artisan make:controller)时发布用于创建PHP文件的存根。通过发布存根,您可以编辑它们并将declare(strict_types=1)添加到顶部。这意味着您利用Artisan命令创建的文件将在已启用更严格类型安全的情形下创建。
当然,如果您打算对现有文件添加更严格的类型检讨,我强烈建议您首先要有一个高质量的测试套件。您的PHP代码可能许可通报禁绝确的数据类型而不引发任何缺点。但是,通过启用严格的类型检讨,您的代码将变得不那么宽容,并可能开始抛出错误。这可能会导致运用程序以用户意想不到的办法中断。
您可能还会创造须要重构一些代码,使其与declare(strict_types=1)兼容。但我不认为这是件坏事。相反,我认为这是一个提高代码质量的机会。
为了帮助您将declare(strict_types=1)添加到代码中,您可能须要利用PHPStan之类的工具,它可以为您网络这些类型不匹配。