Можно ли указать более одного типа подсказки для параметра?
Есть ли способ добавить несколько методов к методу? Например, foo (param) должен получить экземпляр строки OR bar ИЛИ baz.
Ответы
Ответ 1
Это невозможно выполнить (кроме внутри метода). Вы можете указать только один тип подсказки и только для объектов/интерфейсов и массивов (начиная с PHP 5.1).
Вы можете/должны документировать его в своем методе, т.е.
/**
* @param string|Bar|Baz $param1
*/
function foo($param1);
Ответ 2
Это одно использование 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');
Ответ 3
На момент написания этой статьи нет поддержки нескольких явных типов. Вы должны полагаться на документацию и систему динамического типа PHP.
Однако у меня есть в основном неполное предложение для типов профсоюзов. Он нацелен на 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
, который является именно этим.
Ответ 4
Тип hinting разрешает только одну подсказку для каждого параметра (а также подсказка должна быть array
или имя класса, вы можете 't hint 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 (например, если бы тип подсказки не удался), если вы хотите.
Ответ 5
Фантастический вопрос. Это относится как к документации 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{}