質問

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 Parent::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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top