Czy istnieje sposób dodania więcej niż jednego typu podpowiedzi do metody? Na przykład, foo (param) musi otrzymać instancję ciągu LUB paska OR baz.Czy można określić więcej niż jedną wskazówkę dotyczącą parametru?
Odpowiedz
Type hinting pozwala tylko na jedną wskazówkę na parametr (a także, wskazówka musi być array
lub nazwę klasy, nie można schować string
), ale można to zrobić poprzez sprawdzenie typ param wewnątrz swojej funkcji korzystając get_class
:
function foo($param)
{
if (!(is_string($param) || in_array(get_class($param), array("Bar", "Baz")))
{
// invalid type for $param!
}
}
można nawet użyć trigger_error
mieć ona niepowodzeniem z błędem PHP (jak byłoby gdyby wskazówkę typu nie powiodło się), jeśli chcieli.
Proponuję rzucić 'InvalidArgumentException', dzięki czemu można przynajmniej spróbować odzyskać od błędu ... – ircmaxell
@ircmaxell Właśnie pokazałem, w jaki sposób OP * może * powielić sposób działania wskazówek dotyczących typów. –
Nie mówię, że nie "trigger_error". Wszystko zależy od twojego stylu (i nie ma nic złego w używaniu 'trigger_error'). Preferuję wyjątki, więc używam 'InvalidArgumentException'. Jeśli twoim celem jest naśladowanie podpowiedzi typu, to wszelkimi sposobami wywołaj fatalny błąd ... – ircmaxell
Nie można tego wykonać (z wyjątkiem metody). Możesz podać tylko jedną wskazówkę typu i tylko dla obiektów/interfejsów i tablic (od PHP 5.1).
można/należy jednak udokumentować go w sposób, tj:
/**
* @param string|Bar|Baz $param1
*/
function foo($param1);
+1 dla dokumentacji – Hannes
To jedno użycie interfaces. Jeśli chcesz mieć pewność, że obiekt ma metodę ->foobar($baz)
, można spodziewać się interfejs:
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');
}
Potem, gdy dzwoni, to będzie działać:
doSomething(new Foo());
doSomething(new Bar());
te nie będą:
doSomething(new StdClass());
doSomething('testing');
Całkiem fajnie! Istnieją również typy SPL (eksperymentalne): http://pl.php.net/manual/en/book.spl-types.php – joao
w ten sam sposób, w jaki to zrobiłem. – ITroubs
@joao: SPLTypes nie będzie działać w wersji 5.3 (używają przestarzałych wywołań c). Plus ostatnia aktualizacja była w 2008 r., Więc całkiem bezpiecznie jest powiedzieć, że nie jest aktualna ... – ircmaxell
Fantastyczne pytanie. Dotyczy to zarówno dokumentacji IDE, jak i PHP 5 Type Hinting. Musisz pamiętać, że w OO polymorphism jest twoim przyjacielem.
Jeśli utworzysz klasę bazową i przedłużysz je, twoja podpowiedź będzie klasą podstawową ... wszystkie klasy rozszerzone będą działały. Zobacz przykład poniżej.
//
$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{}
W czasie pisania tego tekstu nie ma obsługi wielu typów jawnych. Musisz polegać na dokumentacji i dynamicznym systemie PHP.
Mam jednak najczęściej niekompletną propozycję dla union types. Jest ukierunkowany na 7.NEXT (w momencie pisania tego jest 7.1) lub 8 (w zależności od tego, co nastąpi wcześniej).
Oto prosty przykład czegoś, co myślę, że byłaby bardzo cenna: array | Traversable
:
function map(callable $fn, array|Traversable $input) {
foreach ($input as $key => $value) {
yield $key => $fn($value);
}
}
Niestety RFC nie przechodzą; jednak dla określonego typu array|Traversable
istnieje teraz typ: iterable
.
- 1. Czy można mieć więcej niż jedną aktywność programu uruchamiającego?
- 2. Backbone relacyjny - nie więcej niż jedną instancję ,,,
- 3. Eksportuj więcej niż jedną zmienną w ES6?
- 4. Dartlang czekaj więcej niż jedną przyszłość
- 5. Android tabela z więcej niż jedną kolumną jak iOS collectionView
- 6. Czy można ustanowić więcej niż jedną komunikację bluetooth w systemie Android?
- 7. Czy można zainstalować więcej niż jedną ghc i zmienić nazwę binarną każdej instalacji?
- 8. Czy w programie C# można mieć więcej niż jedną metodę main()?
- 9. queryselectorAll - znajdź element z więcej niż jedną pasującą klasą
- 10. Utwórz więcej niż jedną instancję eshell w emacs
- 11. Kontroler Api deklarujący więcej niż jedną instrukcję Pobierz
- 12. Przydział destrukturyzacji ES6 z więcej niż jedną zmienną typu
- 13. Znajdź węzły neo4j z więcej niż jedną relacją przychodzącą
- 14. Qt: Jak zorganizować test jednostek z więcej niż jedną klasą?
- 15. Jak zwrócić więcej niż jedną wartość z funkcji w Pythonie?
- 16. Regex, aby zablokować więcej niż jedną myślnik kolejno
- 17. sparql: jak GROUP BY więcej niż jedną kolumnę
- 18. Proste pytanie Linq: Jak wybrać więcej niż jedną kolumnę?
- 19. split string z więcej niż jedną Char w C#
- 20. Czy ob_start PHP można nazwać więcej niż raz?
- 21. Czy można utworzyć projekt gradacji z więcej niż 2 poziomami?
- 22. Czy można zwiększyć/zmniejszyć pętlę for o więcej niż jeden?
- 23. Czy w Sitemesh można dekorować więcej niż jeden raz?
- 24. Czy pliki rozwiązania Visual Studio (.sln) mają jakąkolwiek wskazówkę dotyczącą komputera, na którym zostały utworzone?
- 25. Czy mogę wybrać więcej niż jedną wartość dla atrybutu w XAML?
- 26. Czy strony githubu Plik CNAME może zawierać więcej niż jedną domenę?
- 27. Android - bindService więcej niż raz
- 28. Czy można ustawić więcej niż jeden plik cookie za pomocą jednego Set-Cookie?
- 29. Czy można określić pozycję toastu?
- 30. Mysqldump więcej niż jeden stół?
Podpowiedź typów nie obsługuje skalarów ciągów; tylko to wskazuję. – Qix
@Qix Powinniśmy teraz wspomnieć, że [PHP obsługuje podpowiedź typu skalarnego od PHP 7.0.0] (http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration). – faintsignal