Расширение класса и конструктор с переменным числом параметров - как сделать?

  • Автор темы Автор темы GRIG
  • Дата начала Дата начала

GRIG

Новичок
Расширение класса и конструктор с переменным числом параметров - как сделать?

Привет всем! Подскажите идею для такой проблемы.
Есть класс, у которого определен конструктор с 6 параметрами. Причем некоторые параметры конструктора могут не указываться и берутся по умолчанию.
Мне нужно написать расширение этого класса. Вся специфика расширения - дополнительные действия в конструкторе и соответствующие обратные действия в деструкторе. Новые члены и методы не вводятся.
Я думал, что будет что-то вроде такого:
PHP:
class MyClass extends OldClass
{
  public function __construct( $p1, $p2, $p3, $p4, $p5, $p6 )
  {
    parent::__construct( $p1, $p2, $p3, $p4, $p5, $p6 );
    $this->setDefaults( myDefaults );
  }
}
В принципе это работает. Но есть одно "но": если я в своем скрипте заменяю старый класс на новый, причем в скрипте был вызов конструктора с 4 параметрами, - то PHP пишет в лог сначала предупреждения о том, что параметры 5 и 6 в конструкторе MyClass не определены, а потом предупреждения о том, что конструктор OldClass вызывается с неопределенными переменными в качестве параметров. И мне этот факт не нравится. Хочется написать класс более "по уму" - чтобы работало без всяких предупреждений.
Как бы это сделать?
Подавить выдачу предупреждений - не предлагать.
Заранее спасибо.
 
PHP:
public function __construct()
{
     $args = func_get_args();
     #...
}

и уже работать с $args всегда...
 
Автор оригинала: A1x
указать для параметров 5 и 6 значения по умолчанию в объявлении конструктора нового класса
К сожалению, не прокатит. Потому что я эти значения не знаю. Старый класс определяет эти значения исходя из каких-то своих файлов-конфигов - и я в этот процесс вмешиваться не хочу.

-~{}~ 03.08.10 13:41:

Автор оригинала: Major
PHP:
public function __construct()
{
     $args = func_get_args();
     #...
}

и уже работать с $args всегда...
И что дальше сказать конструктору старого класса?
 
Потому что я эти значения не знаю. Старый класс определяет эти значения исходя из каких-то своих файлов-конфигов
ээ... значения по умонлчанию могут быть только константами не?

как выглядит объявление конструктора родительского класса?
 
вообще то класс потомок не должен изменять интерфейс родителя, может только расширять

т. е. если конструктор родителя мог вызываться с четырьмя параметрами то и потомок должен это уметь, так что придется поставить для параметров значения по умолчанию (хоть null) и как-то дальше выкручиваться
 
Автор оригинала: A1x
вообще то класс потомок не должен изменять интерфейс родителя, может только расширять

т. е. если конструктор родителя мог вызываться с четырьмя параметрами то и потомок должен это уметь, так что придется поставить для параметров значения по умолчанию (хоть null) и как-то дальше выкручиваться
Вот о том и речь - как научить потомка всему этому? Желательно без нудных конструкций вида "если получили 6 параметров то... иначе если получили 5 параметров то ..."
 
GRIG
Выложи сюда коды конструкторов обоих классов.
 
в случае типа mysqli избежать "нудных" конструкций вряд ли удастся
 
Автор оригинала: Adelf
GRIG
Выложи сюда коды конструкторов обоих классов.
Код конструктора старого класса недоступен. Есть только ссылка на доку, которая его описывает. Выше я ее привел.
А код конструктора нового класса приводить бессмысленно потому что именно его и надо придумать.
 
Есть два плохих варианта:
PHP:
class MyClass extends OldClass
{
  public function __construct( $p1, $p2, $p3, $p4, $p5 = null, $p6 = null )
  {
   if(is_null($p5)) $p5 = ini_get("mysqli.default_port");
   if(is_null($p6)) $p6 = ini_get("mysqli.default_socket");
    parent::__construct( $p1, $p2, $p3, $p4, $p5, $p6 );
    $this->setDefaults( myDefaults );
  }
}

PHP:
class MyClass extends OldClass
{
  public function __construct( $p1, $p2, $p3, $p4, $p5 = null, $p6 = null )
  {
    if(is_null($p5)) 
    {
      parent::__construct( $p1, $p2, $p3, $p4);
    }
    else
    if(is_null($p6))
    {
      parent::__construct( $p1, $p2, $p3, $p4, $p5);
    }
    else
    {
      parent::__construct( $p1, $p2, $p3, $p4, $p5, $p6 );
    }

    $this->setDefaults( myDefaults );
  }
}
 
Вариант с if ... else if ... else if ... сработал. Хотя и выглядит очень коряво.
Ну да ладно. Раз лучше не получается - пусть будет так.
 
Adelf
а зачем во втором вся эта конструкция с if/else?
Если родитель принимает 6 параметров, то почему ему null и не передавать дальше?
К тому же, я бы заменил
is_null($p5) на !isset($p5) && !isset($p6), что равнозначно is_null($p5) && is_null($p6)
 
Если родитель принимает 6 параметров, то почему ему null и не передавать дальше?
Потому что далеко не факт, что будет все работать нормально.

is_null($p5) на isset($p5, $p6), что равнозначно (в данном случае) is_null($p5) && is_null($p6)
Смысл? Мы ловим только случай когда параметры не переданы. Оба или один. Моих проверок достаточно.
 
Adelf
я там поправил немного свое сообщение :)

Теоретически можно не передать p5 и передать p6 в дочерний класс.
ИМХО, не корректно передавать в метод параметры, не соответствующие его интерфейсу.

Поэтому, в данном конкретном случае, я бы выбрал первый плохой вариант, да :)
 
Лучше поздно, чем никогда.

В PHP >= 4.0.4:
PHP:
class MyClass extends OldClass
{
	public function __construct($p1, $p2, $p3, $p4, $p5 = null, $p6 = null )
	{
		$args = func_get_args();
		call_user_func_array(array('parent', '__construct'), $args);
		//$this->setDefaults( myDefaults );
	}
}

В PHP >= 5.3 можно так:
PHP:
class MyClass extends OldClass
{
	public function __construct($p1, $p2, $p3, $p4, $p5 = null, $p6 = null )
	{
		$args = func_get_args();
		call_user_func_array('parent::__construct', $args);
		//$this->setDefaults( myDefaults );
	}
}
 
Сверху