Сложная проблема с PHP - PullRequest
       7

Сложная проблема с PHP

2 голосов
/ 27 сентября 2011

У меня следующая структура класса:

class Parent
{
    public function process($action)
    {
        // i.e. processCreateMyEntity
        $this->{'process' . $action};
    }
}

class Child extends Parent
{
    protected function processCreateMyEntity
    {
        echo 'kiss my indecisive ass';
    }
}

Мне нужно написать некоторый унифицированный метод в дочернем классе, чтобы обработать несколько очень похожих действий для создания сущностей. Я не могу изменить Parent :: process, и мне нужно, чтобы эти методы вызывались из него.

Первое, что приходит на ум, - это магический метод __call. Имя сущности анализируется из первого аргумента __call. Таким образом, структура превращается в:

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
    }
}

Но дело в том, что __call нельзя защитить так, как мне нужно. Я поместил взломать метод вызова в начале метода __call, который проверяет через debug_backtrace, что этот метод вызывался внутри Parent :: process, но это плохо пахнет.

Есть идеи?

Ответы [ 3 ]

2 голосов
/ 27 сентября 2011

Если «несколько» означает 3 или 4, я, вероятно, просто сделаю что-то вроде:

protected function processThis()
{
  return $this->processThings();
}

protected function processThat()
{
  return $this->processThings();
}

protected function processThings()
{
  //common function
}

Конечно, есть повторяющийся код, но то, что он делает, имеет непосредственный смысл. Есть несколько функций, которые делают что-то подобное, и это легко обнаружить.

2 голосов
/ 27 сентября 2011

Я предполагаю, что ваш ребенок происходит от родителя.

Тогда вы можете сделать следующее:

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!");
    }
}
0 голосов
/ 27 сентября 2011

На самом деле, вам не нужно __call, вы можете создать свой собственный и защищенный:

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
    }
}

Согласно описанию в вашем вопросе, это должно быть подходящим,но я не совсем уверен.

...