有没有办法给方法添加多个类型提示?例如,foo(param)必须接收字符串OR bar或baz的实例。是否可以为参数指定多个类型提示?
回答
Type hinting只允许每个参数的一个提示(并且也提示必须array
或类名,你不能暗示string
),但你可以通过你的函数内检查帕拉姆的类型做使用get_class
:
function foo($param)
{
if (!(is_string($param) || in_array(get_class($param), array("Bar", "Baz")))
{
// invalid type for $param!
}
}
你甚至可以使用trigger_error
有它失败,一个PHP错误(像它会如果一个类型提示失败),如果你想要的。
我建议抛出一个'InvalidArgumentException',这样你至少可以尝试从错误中恢复...... – ircmaxell 2010-10-01 14:48:42
@ircmaxell我只是演示了OP *如何*复制类型提示的工作方式。 – 2010-10-01 14:54:41
我不是说不要'trigger_error'。这一切都取决于你的风格(并且使用'trigger_error'没有什么错误)。我更喜欢异常,所以我使用'InvalidArgumentException'。如果你的目标是模仿类型提示,那么通过一切手段触发致命错误... – ircmaxell 2010-10-01 15:00:53
这是不可能执行(除了在方法内)。你只能提供一个单一的类型提示,并且只能提供对象/接口和数组(从PHP5.1开始)。
可以/但是应该在你的方法将其记录下来,即:
/**
* @param string|Bar|Baz $param1
*/
function foo($param1);
+1文档 – Hannes 2010-10-01 14:44:26
这是一个利用interfaces。如果你想确保对象具有->foobar($baz)
方法,你可以期望的接口:
interface iFooBar {
public function foobar($baz);
}
class Foo implements iFooBar {
public function foobar($baz) { echo $baz; }
}
class Bar implements iFooBar {
public function foobar($baz) { print_r($baz); }
}
function doSomething(iFooBar $foo) {
$foo->foobar('something');
}
然后,打电话时,这些将工作:
doSomething(new Foo());
doSomething(new Bar());
这些不会:
doSomething(new StdClass());
doSomething('testing');
奇妙的问题。它适用于IDE文档和PHP 5 Type Hinting。 你必须记住,在OO polymorphism是你的朋友。
如果你创建一个基类并扩展它们,你的类型提示将是基类......所有的扩展类都可以工作。见下面的例子。
//
$test = new DUITest();
// Calls below will work because of polymorphism
echo $test->test(new Molecule()) . '<br/>';
echo $test->test(new Vodka()) . '<br/>';
echo $test->test(new Driver()) . '<br/>';
echo $test->test(new Car()) . '<br/>';
// Will not work because different data type
echo $test->test(new Pig()) . '<br/>';
echo $test->test(new Cop()) . '<br/>';
echo $test->test('test') . '<br/>';
echo $test->test(array()) . '<br/>';
/**
* Class to test
*/
class DUITest {
public function __construct() {
;
}
/**
* Using type-hinting
*
* See below link for more information
* @link http://www.php.net/manual/en/language.oop5.typehinting.php
*
* @param Molecule|Car|Driver|Vodka $obj
*/
public function test(Molecule $obj) {
echo $obj;
}
}
/**
* Base Class
*/
class Molecule {
public function __construct() {}
/**
* Outputs name of class of current object
* @return <type>
*/
public function __toString() {
return get_class($this);
}
}
class Car extends Molecule {}
class Driver extends Molecule {}
class Vodka extends Molecule {}
class Pig {}
class Cop extends Pig{}
在写这篇文章时,不支持多显式类型。你必须依赖文档和PHP的动态类型系统。
但是,我确实有一个主要不完整的建议union types。它的目标是7.NEXT(在撰写本文时为7.1)或8(以先到者为准)。
下面是一些简单的例子,我觉得这是非常有价值的:array | Traversable
:
function map(callable $fn, array|Traversable $input) {
foreach ($input as $key => $value) {
yield $key => $fn($value);
}
}
不幸的是,RFC没有通过;但是对于特定类型array|Traversable
,现在有一个iterable
类型,正是这种类型。
- 1. 是否可以从指针模板参数中提取类型?
- 2. 是否可以指定多个预期响应类型?
- 3. 是否可以为类型参数指定一个通用约束从另一个类型转换?
- 4. 是否可以投射类型参数?
- 5. python 3.5类型提示:我可以检查函数参数是否匹配类型提示?
- 6. 我可以将参数类型指定为多种类型之一而不是TypeScript中的任何类型?
- 7. 有一个模板参数可以是指针类型或非指针类型
- 8. 如何使用类型提示指定多个返回类型
- 9. 在函数中是否可以将类型作为参数?
- 10. Rails序列化哈希 - 是否可以指定数据类型?
- 11. 是否可以定义“模板函数指针”的类型?
- 12. 是否可以在不指定类型的情况下传递表参数?
- 13. 确定是否类是与多个泛型参数
- 14. 是否可以使用gradle'application'插件指定多个主类
- 15. 是否可以在C#中定义参数化类型别名?
- 16. 是否可以强制参数成为某种类型的键?
- 17. 参数类型可能不是指一个抽象类型
- 18. 如何使用可重复的参数指示多个类型参数?
- 19. Python类型提示:如何指定文件指针作为参数?
- 20. 是否可以显示多视图两个活动指数在
- 21. 是否可以同时为多个指令定义{$ IFDEF}?
- 22. 是否可以使用任意类型参数定义返回类型?
- 23. 类型提示:参数类型类
- 24. 可以使用InInjectedInto为ninject指定多个参数吗?
- 25. 是否可以确定某个类型是否是范围枚举类型?
- 26. 我可以通过类型特征确定指针是否为整型:
- 27. 是否可以在Scala中指定一个匿名函数的返回类型?
- 28. 是否可以使用可变参数定义一个宏,并获取每个参数的类型?
- 29. 未指定类型参数
- 30. 是否可以指定一个空的std :: vector作为默认参数?
类型提示不支持字符串标量;只是指出了。 – Qix 2014-10-13 21:35:16
@Qix现在我们应该提到[PHP支持自PHP 7.0.0起的标量类型暗示](http://php.net/manual/en/functions.arguments.php#functions.arguments.type- declare)。 – faintsignal 2017-08-28 22:02:03