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

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 вызывается с неопределенными переменными в качестве параметров. И мне этот факт не нравится. Хочется написать класс более "по уму" - чтобы работало без всяких предупреждений.
Как бы это сделать?
Подавить выдачу предупреждений - не предлагать.
Заранее спасибо.
 

Major

Новичок
PHP:
public function __construct()
{
     $args = func_get_args();
     #...
}
и уже работать с $args всегда...
 

GRIG

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

-~{}~ 03.08.10 13:41:

Автор оригинала: Major
PHP:
public function __construct()
{
     $args = func_get_args();
     #...
}
и уже работать с $args всегда...
И что дальше сказать конструктору старого класса?
 

A1x

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

как выглядит объявление конструктора родительского класса?
 

A1x

Новичок
вообще то класс потомок не должен изменять интерфейс родителя, может только расширять

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

GRIG

Новичок
Автор оригинала: A1x
вообще то класс потомок не должен изменять интерфейс родителя, может только расширять

т. е. если конструктор родителя мог вызываться с четырьмя параметрами то и потомок должен это уметь, так что придется поставить для параметров значения по умолчанию (хоть null) и как-то дальше выкручиваться
Вот о том и речь - как научить потомка всему этому? Желательно без нудных конструкций вида "если получили 6 параметров то... иначе если получили 5 параметров то ..."
 

Adelf

Administrator
Команда форума
GRIG
Выложи сюда коды конструкторов обоих классов.
 

A1x

Новичок
в случае типа mysqli избежать "нудных" конструкций вряд ли удастся
 

GRIG

Новичок
Автор оригинала: Adelf
GRIG
Выложи сюда коды конструкторов обоих классов.
Код конструктора старого класса недоступен. Есть только ссылка на доку, которая его описывает. Выше я ее привел.
А код конструктора нового класса приводить бессмысленно потому что именно его и надо придумать.
 

Adelf

Administrator
Команда форума
Есть два плохих варианта:
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 );
  }
}
 

GRIG

Новичок
Вариант с if ... else if ... else if ... сработал. Хотя и выглядит очень коряво.
Ну да ладно. Раз лучше не получается - пусть будет так.
 

FB3

Новичок
Adelf
а зачем во втором вся эта конструкция с if/else?
Если родитель принимает 6 параметров, то почему ему null и не передавать дальше?
К тому же, я бы заменил
is_null($p5) на !isset($p5) && !isset($p6), что равнозначно is_null($p5) && is_null($p6)
 

Adelf

Administrator
Команда форума
Если родитель принимает 6 параметров, то почему ему null и не передавать дальше?
Потому что далеко не факт, что будет все работать нормально.

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

FB3

Новичок
Adelf
я там поправил немного свое сообщение :)

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

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

john.spies

Новичок
Лучше поздно, чем никогда.

В 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 );
	}
}
 
Сверху