如何在自己的函数中使用混合参数类型?

23
我希望定义一个PHP 7函数,它需要一个混合类型的参数。(我的目标是实现C#中泛型类型参数的等效方式;如果在PHP 7中有更好的模拟方法,请告诉我。)
我的代码如下。
<?php
declare (strict_types = 1);    

function test (mixed $s) : mixed {
    return $s;
}

// Works
echo gettype ('hello');
// Does not work
echo test ('hello');
?>

当我运行这段代码时,我得到了以下结果。
Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of mixed, string given, called in mixed.php on line 11 and defined in mixed.php:4
Stack trace:
#0 mixed.php(11): test('hello')
#1 {main}
thrown in mixed.php on line 4

如果我注释掉对test()函数的调用,代码就可以正常运行,因此显然在函数声明中使用混合参数类型至少是可以的。
我知道像gettype()这样的内置PHP函数可以接受混合参数,但我不知道它们是否在内部使用严格类型。
我发现“mixed”也被用作PHP 文档中的伪类型,所以我可能误解了“mixed”作为PHP关键字的目的,但我至少从这里看到的意味着它是一个合法的关键字。我是否只是在以一种它不打算使用的方式使用它?
最后,我意识到我可以通过简单地不指定参数类型来规避所有这些问题,但我希望通过指定所有我的参数和返回类型来保持一致。
谢谢你,请告诉我是否需要提供任何其他信息。

2
是的,“mixed”不是真正的类型。在这里保持一致与正确的语义无关。 - mario
3
FYI,mixed并不是一种类型。(http://php.net/manual/zh/language.pseudo-types.php) 它只是一种伪类型:一种提示,表示任何类型的参数可以被传递或从方法中返回...或者对于因任何原因松散地类型化为mixed的变量...与C#不同,尤其是在启用 strict_types 时,你想要实现的目标可能有些棘手。 但是,你可以在不使用Strict Typing的情况下实现几乎相似的效果,在这种情况下,只要不提供任何类型提示,你的方法就可以接受任何类型的参数。虽然对于C#程序员来说这是不好的,但这却是PHP的精髓所在。 - Poiz
1
非常感谢Mario和Poiz。看起来我只需要添加/mixed/作为注释。 - FSharpN00b
@Poiz,你应该把你的评论变成一个真正的答案。然后FsharpNoob可以将其标记为已接受的答案。我刚刚问了同样的问题。对我来说,答案只是一个“伪类型”,并不完全清楚(至少在先验上)。例如,在CSS伪元素中,它们不是实际的元素,但仍然是语言结构/关键字。因此,我错误地认为伪意味着变量永远不能具有此类型,但您仍然可以将参数定义为混合类型(类似于无法实例化的抽象类)。 - Bart
1
@Poiz(虽然您无法再编辑评论了,但是https://www.php.net/manual/en/language.pseudo-types.php是一个失效的链接。) - mickmackusa
显示剩余3条评论
3个回答

29

请注意,mixed 不是一种类型。(参见文档)它只是一种伪类型(pseudo type):它是一个提示,表示任何类型都可以传递给或从方法返回……或者对于因任何原因而松散地被标记为 mixed 的变量……

与 C# 不同,在 PHP 中尤其是在启用 strict_types 的情况下,实现你想达到的目的可能比较棘手。

但是,即使不使用严格类型,你也可以达到几乎相似的效果 - 在这种情况下,只要你不提供任何类型提示,你的方法就可以接受任何类型。虽然对于 C# 程序员来说,这很糟糕 - 但是,这就是 PHP 的精髓


14

2021年更新

PHP8引入了混合类型。可以按照问题中所示的方式使用它。


3
PHP混合类型的官方文档链接:https://www.php.net/manual/zh/language.types.declarations.php#language.types.declarations.mixed。 - Eelke

1
为了表明该函数也接受null,?-操作符也可以像http://php.net/manual/de/functions.returning-values.php#functions.returning-values.type-declaration中提到的那样使用。
但是,只有在代码不需要向后兼容时才可用此功能,因为此功能仅适用于PHP >= 7.1。如https://wiki.php.net/rfc/mixed-typehint所示,有一个RFC用于添加混合类型提示。因此,实际上似乎没有机会为接受多种类型的参数定义正确的类型提示。
因此,phpDoc注释可能是一种解决方案(并且它也向后兼容)。例如:
/**
* Functiondescription
* @author FSharpN00b
* @param mixed $s
* @return mixed
**/
function test ($s){
    return $s;
}

我已经更新了。 希望现在更有帮助。 - Alexander Behling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接