有沒有辦法給方法添加多個類型提示?例如,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