有沒有辦法給方法添加多個類型提示?例如,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. 如何使用可重複的參數指示多個類型參數?
- 6. Python類型提示:如何指定文件指針作爲參數?
- 7. 是否可以強制參數成爲某種類型的鍵?
- 8. 是否可以顯示多視圖兩個活動指數在
- 9. 是否可以同時爲多個指令定義{$ IFDEF}?
- 10. 我可以通過類型特徵確定指針是否爲整型:
- 11. 是否可以在Scala中指定一個匿名函數的返回類型?
- 12. 未指定類型參數
- 13. 是否可以將泛型類型擴展爲Java中的多個類?
- 14. 只指定第一個類型參數
- 15. 是否可以指定匿名類型的列表長度?
- 16. 我可以指定一個C#類型參數只能是一個接口類型嗎?
- 17. 成員函數指針指向未指定的類類型 - 是否有可能?
- 18. C++元函數,確定是否可供調用提供的參數類型
- 19. C++ - 是否可以從模板中的成員函數類型中提取類和參數類型?
- 20. 是否可以在Java中爲類型參數指定上限和下限約束?
- 21. 是否可以爲模型中的字段指定標籤?
- 22. Python類型提示 - 如何提示可選參數的默認值不是None?
- 23. 我可以指定一個類實例可以轉換爲某種類型嗎?
- 24. 被指定爲特徵而不是具體類型的可選函數參數
- 25. 多維紅寶石數組:是否可以使用多個參數定義[] -operator?
- 26. 是否可以在將pandas DataFrame保存爲羽化時指定列類型?
- 27. 是否可以轉換參數包中的類型?
- 28. 是否可以在類型參數中使用'case object`?
- 29. 是否可以獲得泛型參數的類?
- 30. 在Java中,我可以指定任何數量的泛型類型參數嗎?
類型提示不支持字符串標量;只是指出了。 – 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