In a class I have a handling method which performs actions based on what post/get variables are available. Here is a simplified example:
public function handleAll(array $vars) {
if (isset($vars['var1'])) {
$this->doThisAction($vars['var1']);
} else if (isset($vars['var2'])) {
$this->doAnotherAction($vars['var2']);
}
}
So at runtime the method could be called like this $handler->handleAll($_POST)
.
The problem is that the variables stored in the $vars array must be named "var1" & "var2" etc. This means that the handling code is coupled with the names of html form elements or get variables in urls (or indeed the keys of any array passed in).
Allowing an array of any variables to be injected makes the method flexible which is necessary as it is also polymorphic. Classes inherit this method and use it to call it's own actions. A result of this is that it is not obvious from the outside what the handling method requires for it to function. This means that the implementation must be examined to find out what it does (unless I copy the code into the phpdoc which would be silly).
I'm not sure how to get around this. Having enormous if/case statements all exposed on index pages (from multiple classes like these) makes for extremely messy code so it is preferable to have all this encapsulated within a method. Also, it makes sense to have it as a method of the class responsible for calling the actions that manipulate it's own state (responsibility driven design). I thought about having each variable as a parameter for the method but for some classes the parameter list would be quite large. Also it would mean that many handleAll() methods of different classes cannot be called automatically as all parameters would need to be explicitly injected for each call, removing the polymorphic aspect.
To sum up I need to keep the method polymorphic but I need some way of decoupling the handling code from user input from html forms or urls. In doing this perhaps there is a way of separating the interface from the implementation too. I'm surprised I can't find any solutions to this already, it seems like it would be a common problem.