C'è un modo per aggiungere più di un tipo a un metodo? Ad esempio, foo (param) deve ricevere un'istanza di string OR bar O baz.È possibile specificare più di un suggerimento per un parametro?
risposta
Type hinting permette solo per un suggerimento per parametro (e anche, il suggerimento deve essere array
o un nome di classe, non si può accennare string
), ma è possibile farlo controllando il tipo di parametro all'interno della vostra funzione , utilizzando get_class
:
function foo($param)
{
if (!(is_string($param) || in_array(get_class($param), array("Bar", "Baz")))
{
// invalid type for $param!
}
}
si potrebbe anche usare trigger_error
avere fallire con un errore PHP (come sarebbe se un tipo di suggerimento fallito) se si voleva.
Suggerirei di lanciare un 'InvalidArgumentException', in modo che tu possa almeno tentare di recuperare dall'errore ... – ircmaxell
@ircmaxell Stavo solo dimostrando come l'OP * potrebbe * replicare come funzionano i tipi di suggerimenti. –
Non sto dicendo di non usare 'trigger_error'. Tutto dipende dal tuo stile (e non c'è niente di sbagliato nell'uso di 'trigger_error'). Preferisco le eccezioni, quindi uso 'InvalidArgumentException'. Se il tuo obiettivo è quello di imitare i suggerimenti di tipo, quindi innescare tutti un errore fatale ... – ircmaxell
Ciò non è possibile applicare (tranne all'interno del metodo). È possibile fornire solo un suggerimento di tipo singolo e solo per oggetti/interfacce e matrici (da PHP 5.1).
Si può/deve tuttavia documentarlo nel metodo, cioè:
/**
* @param string|Bar|Baz $param1
*/
function foo($param1);
+1 per documentazione – Hannes
Questo è uno uso di interfaces. Se si vuole essere sicuri che l'oggetto ha un metodo ->foobar($baz)
, ci si potrebbe aspettare un'interfaccia:
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');
}
Poi, quando si chiama, questo non funziona:
doSomething(new Foo());
doSomething(new Bar());
Questi non:
doSomething(new StdClass());
doSomething('testing');
Piuttosto interessante! Ci sono anche i tipi SPL (sperimentale): http://pl.php.net/manual/en/book.spl-types.php – joao
allo stesso modo in cui l'ho fatto. – ITroubs
@joao: SPLTypes non funziona su 5.3 (Usano chiamate c deprecate). Inoltre l'ultimo aggiornamento è stato nel 2008, quindi è abbastanza sicuro dire che non è aggiornato ... – ircmaxell
Domanda fantastica. Si applica sia alla documentazione IDE che a PHP 5 Type Hinting. Devi ricordare che in OO polymorphism è tuo amico.
Se crei una classe base ed estendali, il tuo suggerimento tipo sarà la classe base ... tutta la classe estesa funzionerà. Vedi l'esempio qui sotto.
//
$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{}
Al momento della stesura di questo documento non è supportato più tipi espliciti. Devi fare affidamento sulla documentazione e sul sistema di tipo dinamico di PHP.
Tuttavia, ho una proposta per lo più incompleta per union types. Ha come target 7.NEXT (al momento in cui scrivo questo è 7.1) o 8 (a seconda di quale viene prima).
Ecco un semplice esempio di qualcosa che penso sarebbe molto prezioso: array | Traversable
:
function map(callable $fn, array|Traversable $input) {
foreach ($input as $key => $value) {
yield $key => $fn($value);
}
}
Purtroppo la RFC non ha superato; tuttavia per il tipo specifico array|Traversable
c'è ora un tipo iterable
che è esattamente quello.
- 1. C'è un suggerimento di tipo PHPDoc per un parametro booleano?
- 2. È possibile mostrare un suggerimento in un'app per iOS?
- 3. È possibile passare un parametro aggiuntivo a un predicato?
- 4. Utilizzare la libreria di digitazione di python per specificare più di un possibile tipo
- 5. Python: str.split() - è possibile specificare solo il parametro "limite"?
- 6. ^char suggerimento non è consentito per il parametro clojure defn
- 7. È possibile specificare più comandi in `pre_window` di` tmuxinator`?
- 8. È possibile utilizzare una funzione lambda per un parametro template?
- 9. È possibile fare un parametro per implementare due interfacce?
- 10. È possibile registrare più ModelAdmins per un modello? Alternative?
- 11. È possibile specificare un nome di classe per Spring Framework in un file esterno?
- 12. È possibile utilizzare `caso caso` con un parametro di tipo?
- 13. Swagger: è possibile rendere costante/readonly un parametro di funzionamento?
- 14. È possibile che OCMock esegua un parametro di blocco?
- 15. È possibile avere un delegato come parametro di attributo?
- 16. MSBUILD: errore MSB1008: è possibile specificare un solo progetto
- 17. È possibile specificare più di una semplice versione "normale" e "grassetto" di un carattere in un foglio di stile Qt?
- 18. È possibile aggiungere un elemento a un array in awk senza specificare un indice?
- 19. Copia costruttore con più di un parametro
- 20. È possibile specificare i parametri di ricerca nei percorsi Yesod?
- 21. Come è possibile specificare un limite di timeout per la chiamata di sistema Perl?
- 22. Come specificare un parametro variadic (ellissi) come opzionale in Swift?
- 23. È possibile fornire a C# intellisense di Visual Studio un suggerimento per visualizzare prima un certo overload di metodi?
- 24. Specificare un driver predefinito per ODBC
- 25. È possibile definire più acceleratori per un JMenuItem?
- 26. Set suggerimento per un pulsante disattivato
- 27. Metodo di passaggio come parametro - È possibile?
- 28. Ricerca di un suggerimento per un libro AutoLisp/VisualLisp
- 29. È possibile vincolare un parametro del tipo di metodo generico C# come "assegnabile dal parametro di tipo della classe contenente"?
- 30. accetta più tipi per un parametro in scala
L'hint di tipo non supporta gli scalari di stringa; solo sottolineando questo. – Qix
@Qix Dovremmo ora ricordare che [PHP supporta l'hint di tipo scalare come da PHP 7.0.0] (http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration). – faintsignal