Basically it says that add() will only allow instances of Test.
It's possible to achieve this in PHP by simply adding the type before the argument name in the function definition (similar with C/C++/C# types):
class Main { protected $items = []; public function add(Test $object) { $this->items[] = $object; } }
PHP 5 accepts classes, interfaces, array and callable as type hints. If Test is a class then Main::add() accepts objects of class Test and its children. If Test is an interface, then the method Main::add() accepts objects that implement Test or one of its children.
PHP 7 (coming soon to a server near you) introduces type hinting for scalar types too.
PHP does not support anything similar with C++ templates or C# generics. If you want to create a class that works with objects of type A and another class that has identical behaviour but works with objects of type B you have several options but none of them is as elegant as the templates/generics:
- Create two classes having identical behaviour, one for objects of type
A, another for objects of type B; use different type hints (A and B) in the arguments lists of the methods of the two classes to enforce the separation - not scalable; - Something similar to your code, use the allowed class name as a string property and check it on any operation; you can also validate the argument of the constructor using
class_exists() - the code becomes cluttered with tests and less readable; Use OOP polymorphism; extend both A and B from the same class T or, even better, make A and B implement the same interface I. A PHP interface can be empty, it doesn't need to declare anything; empty interfaces used just for type hinting are common practice in PHP.
Then write a single class Main and use I as type hint for all its methods that accept objects. It will accept objects of both types A and B but if you also declare functions in I (and implement them in A and B, of course) then use them in Main you can be sure nothing breaks (I becomes a contract between Main and the objects its accepts as arguments for its methods).
I would choose option #3 because it gets the most help from the interpreter; it verifies the type of the arguments on each function call that has type hints and triggers a recoverable fatal error (in PHP 5) or throws an exception (in PHP 7).
Also some IDEs and static code analysis tools can validate the calls without running the code and help you fix it.
add(), and the problem with usingMyClass::classas a parameter is that the value of that is a string, meaning I have to allow for strings to get passed in, sonew Main('bool')is a valid, but nothing is aninstanceofboolpublic function __construct($type){ if(class_exists($type)) $this->type = $type; else $this->type = "default"; }?