PHP tricky problem
I have the following class structure:
class Parent
{
public function process($action)
{
// i.e. processCreateMyEntity
$this->{'process' . $action};
}
}
class Child extends Parent
{
protected function processCreateMyEntity
{
echo 'kiss my indecisive ass';
}
}
I need to write some unified method in Child class to process several very similar actions for creating entities. I can't change the Parent::process and I need those methods to be called from it.
The first thing that comes to mind is magic __call method. The entity name is parsed from the first __call argument. So the structure turns to:
class Parent
{
public function process($action)
{
// i.e. processCreateMyEntity
$this->{'process' . $action};
}
}
class Child extends Parent
{
protected function __call($methodName, $args)
{
$entityName = $this->parseEntityNameFromMethodCalled($methodName);
// some actions common for a lot of entities
}
}
But the thing is that __call can't be protected as I need it. I put a hack method call at the beginning of __call method that checks via debug_backtrace that this method was called inside Paren开发者_JS百科t::process, but this smells bad.
Any ideas?
If 'several' means 3 or 4, I'd probably just do something like:
protected function processThis()
{
return $this->processThings();
}
protected function processThat()
{
return $this->processThings();
}
protected function processThings()
{
//common function
}
Sure, there is duplicate code, but what it does makes immediate sense. There are a handful of functions that do something similar, and it's easy to discover that.
I am assuming your child extends from the parent.
Then what you could do is:
public function process($action)
{
$methods = get_class_methods($this);
$action = 'process' . $action;
if(in_array($action, $methods)){
$this->{$action}()
}
else {
die("ERROR! $action doesn't exist!");
}
}
Actually, you don't need __call
, you can create your own and protected:
class Parent
{
public function process($action)
{
// i.e. processCreateMyEntity
$this->entityCall('process' . $action);
}
}
class Child extends Parent
{
protected function entityCall($methodName, $args)
{
$entityName = $this->parseEntityNameFromMethodCalled($methodName);
// some actions common for a lot of entities
}
}
According to the description in your question, this should be fitting, but I'm not entirely sure.
精彩评论