typehinting: metodo deve accettare qualsiasi $ arg che è un oggetto
-
26-09-2019 - |
Domanda
Ho una classe 'Collection', che ha un metodo add. Il metodo add dovrebbe accettare solo gli oggetti. Quindi questo è il comportamento desiderato:
$x=5;//arbitrary non-object
$obj=new Foo; //arbitrary object
$collection=new Collection;
$collection->add($obj); //should be acceptable arg, no matter the actual class
$collection->add($x); //should throw an error because $x is not an object
Secondo il manuale di PHP, si può typehint metodi con prefazione del $arg
con un nome di classe. Dal momento che tutte le classi PHP sono figli di stdClass
, ho pensato che questo firma del metodo avrebbe funzionato:
public function add(stdClass $obj);
Ma non riesce con "argomento deve essere un'istanza di stdClass".
Se cambio la firma per una classe genitore definito da me, allora funziona:
class Collection {
public function add(Base $obj){
//do stuff
}
}
$collection->add($foo); //$foo is class Foo which is an extension of Base
Qualcuno sa come digitare suggerimento per un oggetto generico?
Soluzione
A differenza di classe Object
di Java, PHP non ha una classe base per gli oggetti . Gli oggetti fanno stdClass
non eredita: si tratta di un'implementazione oggetto predefinito, non è una classe base. Così, purtroppo, non è possibile digitare suggerimento per tutti gli oggetti in PHP. Bisogna fare qualcosa di simile:
class MyClass {
public function myFunc($object) {
if (!is_object($object))
throw new InvalidArgumentException(__CLASS__.'::'.__METHOD__.' expects parameter 1 to be object");
}
}
Per fortuna, PHP definisce già la classe InvalidArgumentException
a tal fine.
Altri suggerimenti
Non c'è classe radice in PHP. Gli oggetti non hanno nemmeno ereditano da stdClass
:
class Foo {}
var_dump(new Foo instanceof stdClass); // bool(false)
var_dump(get_parent_class(new Foo)); // bool(false)
A quanto pare non c'è modo è noto in PHP digitare suggerimento per object
anche se object
è un tipo di dati in PHP (come array
), e fusione di caratteri a object
produce un oggetto stdClass
:
echo get_class((object) "string"); // stdClass
Credo che come una soluzione si potrebbe dire il metodo per generare un'eccezione o morire con un errore fatale se i rendimenti is_object($obj)
falso.
Beh, la cosa è, che PHP è ancora un linguaggio dinamico, e il tipo di suggerimenti sono proprio questo: i suggerimenti. Penso che si dovrà ripiegare al vecchio is_object metodi simili o e un'eccezione personalizzato.
class Collection {
public function add(Base $obj){
if(!is_object($obj))
throw new Exception("Parameter must be an object");
// do stuff
}
}
In PHP 7.2 v'è ora un tipo di object
suggerimento. Si può semplicemente fare
class Collection {
public function add(object $obj){
//do stuff
}
}