LINUX.ORG.RU

[PHP5] Можно ли сделать в классе несколько конструкторов?


0

0

Здравствуйте!

Что-то я не пойму, в PHP5 нельзя чтоли сделать класс с несколькими конструкторами? Следующий код

class Field
{
 private $name='';
 private $properties=array();

 function __construct($field_name)
 {
  $this->name=$field_name;
 }


 function __construct($field_name, $field_properties)
 {
  $this->name=$field_name;
  $this->properties=$field_properties;
 }
 ...
}

Дает ошибку

Fatal error: Cannot redeclare Field::__construct()

Ищу хоть какуюто информацию о нескольких конструкторах - не нахожу. Ищу информацию о том, что несколько кострукторов в PHP5 сделать нельзя - тоже не нахожу.

Вопрос. Возможно ли в PHP5 сделать несколько конструкторов у класса?


Нельзя.

Но можно:

function __construct($field_name, $field_properties = NULL) { ... }

KRoN73 ★★★★★
()

Ты хочешь перегрузку в убогом языке который даже проверки типов не имеет?

wfrr ★★☆
()

К сожалению PHP не поддерживает несколько конструкторов в классе. Как обходной вариант используй фабрики или фабричный метод или прототип.

http://en.wikipedia.org/wiki/Design_pattern_(computer_science)

В зависимости от контекста задачи выбирается наиболее удобный или (понятный) вариант реализации.

В твоем случае может быть так:


class My {

  protected function __construct($params){...}

  public static function constructMy1($p1){return new My($p1);}
  public static function constructMy2($p2){return new My($p2);}
}

Если заранее неизвестно число параметров конструктора:

-switch на число параметров ... case 0: return new $x(); ....

-вспомогательный класс-фабрика или фабричный метод в том же классе

-юзать в конструкторе func_get_args() как уже советовали

-несколько лучше ситуация в 5.3

swwwfactory ★★
()
Ответ на: комментарий от swwwfactory

Слишком усложняешь. Человеку нужно просто такое:

class Field
{
 private $name='';
 private $properties=array();

 function __construct($field_name, $field_properties = array())
 {
  $this->name=$field_name;
  $this->properties=$field_properties;
 }
 ...
}

И всё :)

$x1 = new Field('test1'); $x2 = new Field('test2', array('type' => 'int'));

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

В простейшем случае, согласен да, твой вариант наиболее подходит. Можно вообще принять, что конструктор всегда принимает массив свойств на входе и забыть про разные варианты конструкторов. Однако, если класс будет расти, то потребуются подклассы, конструирование которых реализовать с помощью фабрик проще. Наконец, если человек взялся за изучение, данная информация будет полезной.

swwwfactory ★★
()
Ответ на: комментарий от swwwfactory

> если класс будет расти

дык наследование же. а в child классе уже можно и конструктор расширить.

isden ★★★★★
()
Ответ на: комментарий от isden

ну да :) но все равно остается проблем: Надо знать как создавать конкретный класс и кто должен знать об этом...

А человек вероятно ожидал, что если объявлен более чем один конструктор, то PHP сам решит какой конструктор выбрать в зависимости от параметров при вызове...

swwwfactory ★★
()
Ответ на: комментарий от boombick

>А вы на чем раньше писали?

Видимо на с++

anonymous
()
Ответ на: комментарий от swwwfactory

>Можно вообще принять, что конструктор всегда принимает массив свойств на входе и забыть про разные варианты конструкторов.

Тут у некоторых людей есть мнение, что конструкторы в реальных проектах вообще [практически] не нужны :)

...

Я, вот, насобачившись за последние несколько лет в PHP как-то тоже к этому пришёл. Конструкторы, конечно, есть, но скрыты в реализациях ORM. Раз написал несколько лет назад - и всё, больше не пользуюсь :) Разве что изредка, несколько раз в год, на низком уровне создание объекта класса работы с БД заюзаю :) Или кеш какой-нибудь «ручной».

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>Тут у некоторых людей есть мнение, что конструкторы в реальных проектах вообще [практически] не нужны :)

ну мнение может быть и есть и люди вполне трезво оценивают ситуацию, но ведь бывает так, что специфика задач реально не требует конструкторов. Например друпал :) или чисто статические классы. Если отказаться от конструктора, т.е. проводить инициализацию класса после создания, то это мягко говоря не очень безопасно и удобно... да и вообще классы без конструкторов это в некотором роде синглетон со статичным методом SingletonClass::newInstance()

Разумеется, где возможно обойтись без конструктора, конечно лучше без него. Некоторые товарищи вообще ООП игнорируют и не пользуются функциями :) и удивляются почему не стоит применять глобальные переменные...

swwwfactory ★★
()
Ответ на: комментарий от swwwfactory

>ведь бывает так, что специфика задач реально не требует конструкторов

Просто фишка в том (озвучиваю мнение этих людей ;) и свой собственный опыт, хотя сам я против конструкторов ничего не имею), что в продвинутых системах редко объекты создаются вручную. Или загрузчики объектов в тех же ORM, или фабрики классов... Вот они и занимаются всей инициализацией.

У меня было веселее. Изначально я плотно загрузил в своём фреймворке конструкторы, хотя и простой задачей - сохранить ID объекта и "страницу" (опциональный параметр отображения). Изредка - преобразовать ID объекта из одного вида в другой (тут объект требовал переопределения конструктора у наследников). Но постепенно, по мере развития фреймворка, получилось так, что из конструктора ушло всё. Сперва ушли дополнительные параметры, потом - препарсинг ID и т.п. Сейчас всё, что делает конструктор - это сохраняет ID. Поскольку хранится он в простом properties, то можно вообще от конструктора отказаться. У меня он не сносится только потому что я не фанатею от тех или иных идей и меня ломает переписать 10 строчек :) Есть оно не просит, и ладно :D

>Если отказаться от конструктора, т.е. проводить инициализацию класса после создания, то это мягко говоря не очень безопасно и удобно...


Вот у меня инициализация, как раз, почти всегда идёт после создания объектов. Дело в том, что источники данных объекта - переопределяемая и сменная сущность. А ООП в PHP не позволяет вводить множественное наследование. Поэтому вносить источник данных в конструктор - это автоматом навязывать единственную линию наследования. Поэтому - сперва объект создаётся, потом, если нужно (признак в каждом класса) - происходит загрузка данных.

>Некоторые товарищи вообще ООП игнорируют и не пользуются функциями :)


Я свою систему изначально необъектной и делал. Тем более, что в PHP4 объекты были совсем уж из рук вон... Но со временем, даже под PHP4 переход на объектную модель упростил проект в разы :) И кода меньше, и скорость выше, и структура прозрачнее...

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

получилось так, что из конструктора ушло всё

в моем случае большинство реализаций конструкторов содержит простой код для определений опций или задания умолчательного поведения т.е. такого вида:

...
public function __construct($conf = array()) {
  ...
  $p1 = (isset($conf['p1'])) ? $conf['p1'] : 'default';
  ...
}
...

Код тривиален, но полностью убрать конструкторы как-то рука не поднимается. Время от времени что-то добавляется и меняется

swwwfactory ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.