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

如何在PHP 7之前解决“必须是string的一个实例,string-given”?

  •  204
  • leepowers  · 技术社区  · 15 年前

    function phpwtf(string $s) {
        echo "$s\n";
    }
    phpwtf("Type hinting is da bomb");
    

    从而导致此错误:

    看到PHP同时识别和拒绝所需的类型不仅仅是一点奥威尔主义。 有五盏灯,该死。

    什么是PHP中字符串的类型暗示?对这个答案的额外考虑可以解释这里到底发生了什么。

    9 回复  |  直到 8 年前
        1
  •  197
  •   Madbreaks    10 年前

    在PHP7之前 type hinting 只能用于强制对象和数组的类型。标量类型不是可hintable类型。在这种情况下,类的对象 string 一串 . 错误信息可能很有趣,但它不应该一开始就起作用。考虑到动态输入系统,这实际上有点反常。

    手动 “类型提示”标量类型:

    function foo($string) {
        if (!is_string($string)) {
            trigger_error('No, you fool!');
            return;
        }
        ...
    }
    
        2
  •  22
  •   Yanick Rochon    8 年前

    PHP's manual :

    类型提示只能是object和array(自PHP 5.1以来)类型。不支持使用int和string进行传统类型暗示。

    **2017年编辑**

    PHP7引入了更多的函数数据类型声明,前面提到的链接已经移动到 Function arguments : Type declarations . 从那一页:

    • 类/接口名称
    • 自己
    • 阵列 :参数必须是数组。(自PHP5.1.0起)
    • 布尔 :参数必须是布尔值。(自PHP7.0.0起)
    • :参数必须是浮点数。(自PHP7.0.0起)
    • :参数必须是整数。(自PHP7.0.0起)
    • 一串
    • 可迭代的 :参数必须是可遍历的数组或实例。(从PHP7.1.0开始)

    警告

    不支持上述标量类型的别名。相反,它们被视为类或接口名称。例如,使用boolean作为参数或返回类型将需要一个参数或返回值,该参数或返回值是类或接口boolean的实例,而不是bool类型:

    <?php
       function test(boolean $param) {}
       test(true);
     ?>
    

    上面的示例将输出:

     Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of boolean, boolean given, called in - on line 1 and defined in -:1
    

    最后一个警告对于理解错误“Argument must of type string,string given”非常重要;由于大多数情况下只允许将类/接口名称作为参数类型,因此PHP会尝试查找类名“string”,但找不到任何类名,因为它是基元类型,因此会失败并出现此错误。

        3
  •  8
  •   Surreal Dreams    15 年前

        4
  •  3
  •   mario    15 年前

    正如其他人已经说过的,类型暗示目前只适用于对象类型。但我认为您触发的特定错误可能是为了准备即将到来的字符串类型 SplString

    理论上,它的行为类似于字符串,但由于它是一个对象,因此将通过对象类型验证。不幸的是,它还没有在PHP 5.3中出现,可能在5.4中出现,所以还没有测试过。

        5
  •  2
  •   TwoStraws    10 年前

    从PHP 7.0开始,类型声明允许标量类型,因此这些类型现在可用: self array , callable , bool , float int , string integer boolean )将被解释为类名。

    See the PHP manual for more information .

        6
  •  0
  •   Patrick    15 年前

    class string
    {
        private $Text;
        public function __construct($value)
        {
            $this->Text = $value;
        }
    
        public function __toString()
        {
            return $this->Text;
        }
    }
    
    function Test123(string $s)
    {
        echo $s;
    }
    
    Test123(new string("Testing"));
    
        7
  •  0
  •   ecairol    10 年前

    当从Laravel控制器调用函数到PHP文件时,出现了这个错误。

    几个小时后,我发现了问题:我正在使用 $这个

        8
  •  0
  •   user719662    8 年前

    (最初由 leepowers 在他的问题中)

    基本类型名称在PHP中不保留

    class string { }
    class int { }
    class float { }
    class double { }
    

    我的错误是认为错误消息只指字符串原语类型——“实例”一词应该让我停顿一下。进一步说明的示例:

    class string { }
    $n = 1234;
    $s1 = (string)$n;
    $s2 = new string();
    $a = array('no', 'yes');
    printf("\$s1 - primitive string? %s - string instance? %s\n",
            $a[is_string($s1)], $a[is_a($s1, 'string')]);
    printf("\$s2 - primitive string? %s - string instance? %s\n",
            $a[is_string($s2)], $a[is_a($s2, 'string')]);
    

    输出:

    $s1-原始字符串?是-字符串实例?不

    在PHP中 string 一串 除非它实际上是 一串 . 与任何使用隐式类型转换的语言一样,上下文就是一切。

        9
  •  -1
  •   subosito    15 年前

    我认为在块内的php上打字,php上的String不是我所知道的对象:

    <?php
    function phpwtf($s) {
        $s = (string) $s;
        echo "$s\n";
    }
    phpwtf("Type hinting is da bomb");
    
    推荐文章