代码之家  ›  专栏  ›  技术社区  ›  Matrix

PHP8严格类型是否强制用于本机函数?

  •  0
  • Matrix  · 技术社区  · 2 年前

    我的代码在PHP 7上工作:

    round(microtime(),3);
    

    但在PHP 8中:

    致命错误:未捕获的类型错误:round():参数#1($num)必须为 类型为int | float,[…][…]中给定的字符串:4堆栈跟踪:#0 […]…:圆形('0.21066100 1646…',3)#1{main}投掷 […][…]在4号线上

    如果我强制铸造:

    round((float)microtime(),3);
    

    它是有效的,但PHP的所有力量都是自动播放和非严格类型的!如果我数十亿行代码中的所有本机函数都必须经过编辑才能强制到处强制转换,我该如何使用PHP8?

    有没有办法保留内部函数的自动类型转换?

    我在代码中以microtime()为例,但是:

    round("200 42"); 
    

    作为同一个问题,所以解决方案不仅仅是 microtime(true) ,这不是这里的主题。

    问题是,如果在我的代码中使用本机函数,会有潜在的错误,我不知道(只有在脚本运行时才会出现错误),所以如果我让PHP 8,可能是,我的网站的某些页面不工作,我不可能知道!这是个大问题!

    https://www.php.net/manual/en/migration80.other-changes.php

    数学函数abs()、ceil()、floor()和round()现在正确了 请注意stricttypes指令。之前,他们胁迫了第一个 参数,即使在严格类型模式下也是如此。

    所以这个函数必须专注于更新代码,而不是所有的原生函数!

    0 回复  |  直到 2 年前
        1
  •  4
  •   Markus AO    2 年前

    您不需要在任何地方强制强制强制强制转换以匹配本机函数签名,除非 strict_types 已声明。您确实需要确保输入到这些函数中的变量可以 毫不含糊的打字 转换为所需的数据类型。我们有一个关于数学函数的例子,你真的想有一个 有效号码 作为参数,无论数据类型如何:

    php > echo round("200");
    200
    
    php > echo round("200 12");
    Warning: Uncaught TypeError: round(): 
    Argument #1 ($num) must be of type int|float, string given
    

    这是绳子 "200" 有效,因为它是一个明确的数字。然而 "200 12" 不会,因为这是模棱两可的。假设您铸造它:

    php > echo (int) "200 12";
    200
    

    你的 “200 12” 变成 (int) 200 。这是你所期望的吗?再次:

    php > echo (float) "gummy bears";
    0
    
    php > echo 200 + "1";
    201
    
    php > echo 200 - "gummy bears" + "1";
    Warning: Uncaught TypeError: Unsupported operand types: int - string
    

    这些都是在早期版本的PHP中会通过的异常评估,幸运的是我们现在得到了 TypeError 相反变量只能进行类型转换 无损失地 ,“鲁莽”的类型转换和损坏的数据是无数躲避错误的根源。

    另请参阅: PHP Manual on Numeric Strings …特别是关于可以 解释为数字 还有什么不能。基本上,如果您的变量通过 is_numeric() ,这对数学运算来说很好——如果不是,那么您应该得到一条错误消息!以下是手册中的示例列表:

    $foo = 1 + "10.5";                // $foo is float (11.5)
    $foo = 1 + "-1.3e3";              // $foo is float (-1299)
    $foo = 1 + "bob-1.3e3";           // TypeError as of PHP 8.0.0, $foo is integer (1) previously
    $foo = 1 + "bob3";                // TypeError as of PHP 8.0.0, $foo is integer (1) previously
    $foo = 1 + "10 Small Pigs";       // $foo is integer (11) and an E_WARNING is raised in PHP 8.0.0, E_NOTICE previously
    $foo = 4 + "10.2 Little Piggies"; // $foo is float (14.2) and an E_WARNING is raised in PHP 8.0.0, E_NOTICE previously
    $foo = "10.0 pigs " + 1;          // $foo is float (11) and an E_WARNING is raised in PHP 8.0.0, E_NOTICE previously
    $foo = "10.0 pigs " + 1.0;        // $foo is float (11) and an E_WARNING is raised in PHP 8.0.0, E_NOTICE previously
    

    总之,您确实希望在不明确的类型转换曾经有效的地方更新代码。。。从长远来看,更新代码所花费的时间将少于查找“自动播放”时损坏的变量值所导致的异常情况所花费的精力。

        2
  •  2
  •   cigien    1 年前

    in_array也有同样的问题:

    $a = null;
    in_array( 1, $a ); // works in php 7 -null becomes [], fails in php 8
    in_array( 1, (array)$a ); // works in php 8 but we don't want to type this... autocast is what made PHP attractive in the first place.