PHP расширяется с неизвестными аргументами - PullRequest
1 голос
/ 22 сентября 2011

У меня есть abstract класс и ребенок:

abstract class Cubique_Helper_Abstract {
    abstract public function execute();
}

class Cubique_Helper_Doctype extends Cubique_Helper_Abstract{
    public function execute($type) {}
}

Как видите, метод execute() распространен. Но количество аргументов может быть разным во всех классах. Как я могу сохранить это расширение с различными аргументами метода?

Это моя текущая ошибка:

Declaration of Cubique_Helper_Doctype::execute() must be compatible
with that of Cubique_Helper_Abstract::execute()

Спасибо, я заранее.

Ответы [ 4 ]

3 голосов
/ 22 сентября 2011

вы можете создать метод или функцию без ограниченного аргумента.

function test(){
$num = func_num_args();
for ($i = 0;$i < $num;$i++)
{
    $arg[$i] = func_get_arg($i); 
}
    // process on arguments  
}
2 голосов
/ 22 сентября 2011
  • Вы можете удалить execute() из аннотации, но вы, вероятно, не хотите этого делать.

  • Вы также можете указать объект данных в качестве аргумента, например:

    class MyOptions {
      public function getType(){}
      public function getStuff(){}
    }
    
    abstract class Cubique_Helper_Abstract {
        abstract public function execute(MyOptions $options);
    }
    
    class Cubique_Helper_Doctype extends Cubique_Helper_Abstract{
      public function execute(MyOptions $options) {
        $type = $options->getType();
      }
    }
    
  • Или вы можете сделать так, чтобы это зависело от значений в конструкторе и пропустить аргумент:

    abstract class Cubique_Helper_Abstract {
        abstract public function execute();
    }
    
    class Cubique_Helper_Doctype extends Cubique_Helper_Abstract{
      public function __construct($type) {
        // since __construct() is not in abstract, it can be different
        // from every child class, which let's you handle dependencies
        $this->type = $type;
      }
      public function execute() {
        // you have $this->type here
      }
    }
    

Последняя альтернатива - моя любимая. Таким образом, вы действительно убедитесь, что у вас есть зависимости, и когда пришло время execute(), вам не нужно давать ему никаких аргументов.


Я бы не использовал func_get_args(), поскольку вы теряете зависимость. Пример:

class Cubique_Helper_Doctype extends Cubique_Helper_Abstract {
  public function execute() {
    $args = func_get_args();
    $type = $args[0];
    $title = $args[1];
    $content = $args[2];
    // do something, for example
    echo $type; // will always echo "" if you miss arguments, but you really want a fatal error
  }
}

$d = new Cubique_Helper_Doctype();
$d->execute();
// this is a valid call in php, but it ruins your application.
// you **want** it to fail so that you know what's wrong (missing dependencies)
1 голос
/ 22 сентября 2011

Когда количество аргументов отличается, вы получаете ошибку:

Fatal error: Declaration of Cubique_Helper_Doctype::execute() must be compatible with that of Cubique_Helper_Abstract::execute() in C:\wamp\www\tests\41.php on line 16

Таким образом, ваш единственный вариант - сделать аргумент массивом и передать в нем действительные аргументы или сделать объявление execute без параметров и искажать отправленные аргументы с помощью func_get_args или func_get_arg и func_num_args

1 голос
/ 22 сентября 2011

Вы можете использовать func_get_arg , чтобы сигнатура метода дочернего класса была одинаковой.

...