Reputation: 3730
I am going through a list of objects, all with the same parent class but they could be instances from one of many sub classes. Depending on the true type of the object I want to perform slightly different operations.
How can I run different blocks of code based on the object types?
In Java I would overload a processing function with each type I wanted to work with, but PHP doesn't allow this.
Background: To Gordon's comment.
We are building forms from a group of objects. A super class Component that is extended to represent specific types of form elements. TextInput extends Component
and the Component has the ability to hold other Components. We don't want them to be responsible for their actual representation.
We are working to build HTML right now, but we might potentially want to use them to build .PDFs or other formats.
So we have code that goes through the Components, and recursively through the Components it contains. Depending on the type of the Component, we need to create different output.
Upvotes: 1
Views: 80
Reputation: 2254
Try smth like this
function objectProcessor_A($o) {}
function objectProcessor_B($o) {}
function objectProcessor_C($o) {}
foreach($objects AS $o) {
if(function_exist("objectProcessor_" . get_class($o)))
call_user_func("objectProcessor_" . get_class($o), $o);
}
Now, I think, that best solution is using inheritance. Can't change $o's behavior/library code? Than use factory and add method as anonymous function:
class OFactory {
static function getO($type) {
$r = new $type();
if($type === "A") {
$r.processor = function() {...};
} else if($type === "B") {
$r.processor = function() {...};
} else if($type === "C") {
$r.processor = function() {...};
}
return $r;
}
}
$a = OFactory::getO("A");
call_user_func($a->processor);
$b = OFactory::getO("B");
call_user_func($b->processor);
Upvotes: 2
Reputation: 12244
Use
if($myobject instanceof class1){
}elseif($myobject instanceof class1){
}
Or
switch(get_class($myobject)){
case 'class1':
break;
case 'class2':
break;
}
Also, make sur you don't break the Open/Closed principle. If you put that portion of code in a class and not in a specific portion of a controller, you end up breaking an important reusability feature of your code:
Open / Closed Principle
Have you never done a plug-in system? If you did, i’m sure you didn’t ask your users to hardcode a loading line in the code to handle that plug-in right?
Normaly speaking, you’d want your classes to be extendable without needing to change the parent. Extension should be an open principle where adding more code should be as easy as extending but you should never have to modify the parent class.
Thus addind a switch inside the parent or inside another class to handle all possible versions of that class breaks the open principle, because users then have to change the class to add more features...
Upvotes: 2
Reputation: 219864
Make an abstract class that represents all of the common functionality of the objects and also dictates what other methods they must have so you can be sure you're working with the same interface every time (these are called abstract methods).
Then create subclasses for each specific type of object. They must implement all of the abstract methods from the main abstract class.
Then use the factory pattern to dynamically create the proper object based on whatever flag determines the object type (a.k.a subclass).
Upvotes: 2