лучшая практика для инициализации учеников в php

10

У меня есть много кода, как это в моих конструкторах: -

function __construct($params) {

    $this->property = isset($params['property']) ? $params['property'] : default_val;

}

Лучше сделать это, чем указывать значение по умолчанию в определении свойства? то есть public $property = default_val? Иногда есть логика для значения по умолчанию, и некоторые значения по умолчанию берутся из других свойств, именно поэтому я делал это в конструкторе.

Должен ли я использовать сеттеры, чтобы вся логика значений по умолчанию была разделена?

rgvcorley
источник

Ответы:

8

У меня была такая философская дискуссия с собой раньше. Вот где я стою большую часть времени, хотя понимаю, что это ответ, основанный на мнении:

Одна вещь, которую я вижу, которая может помочь ответить на вопрос, это передача $ params, которые могут иметь или не иметь атрибуты / члены массива, которые установлены.

За эти годы я пришел к такому выводу:

Избегайте прохождения массивов.

Почему? Ну, нет никакого способа установить или иметь значения часового, определенные для необязательных переданных аргументов.

Другими словами, с указанным кодом вы не можете сделать что-то вроде этого:

function __construct($arg1 = NULL, $arg2 = DEFAULT_VAL) {

    $this->arg1 = $arg1;

    $this->arg2 = $arg2;

}

$ arg1 и $ arg2 являются необязательными аргументами - если они не переданы, они имеют NULL и DEFAULT_VAL соответственно - нет необходимости явно проверять.

Может быть, это кажется произвольным.

Я думаю, что я понимаю, что вы пытаетесь достичь - передача единственной ссылки, а не тонны аргументов. Это подводит меня к следующему убеждению:

Если не передать «атомарные» переменные (строки, целые числа, литералы), тогда передайте объекты.

Здесь есть преимущества в производительности, поскольку передача объектов осуществляется по ссылке (хотя я думаю, что массивы в PHP примерно одинаковы).

Так что вы можете сделать что-то вроде:

function __construct(MyAwesomeObject $oArg) {

        $this->oArg = $oArg;

    }

Переданный аргумент объекта будет гарантированно иметь «property1», «property2», хотя возможно со значениями по умолчанию.

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

Но мы быстро понимаем, что у нас происходит что-то вроде курицы и яйца: вы создаете объект с переданными аргументами объекта, которые сами должны в какой-то момент создать.

Так, где это оставляет нас? Что ж, я пришел к выводу, что в конечном итоге все классы перестанут, из-за отсутствия лучшего термина, «атомарные» переменные (строки, числа с плавающей запятой, двойные числа, целые числа, ресурсы, которые вы получаете за мою точку зрения), и что я склонен пытаться построить все классы с этими переменными типами или объектами - но не массивами.

Так я ответил на ваш вопрос? наверное не совсем. Но я надеюсь, что проиллюстрировал что-то полезное, хотя и несколько стилистическое. Я думаю, что код немного чище, более читабелен и менее затратен.

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

Надеюсь это поможет.

ekeyser
источник
1
Это хороший момент, и он очень удобен для запросов IDE, но свойств объекта слишком много, чтобы передать их все в качестве параметров. Если у вас есть 7 аргументов, скажем, 5 из которых являются необязательными, то в итоге new object($param1,-some default value so I can specify the next parameter-, $param3);вы получите такие вещи, как, и поэтому ваши значения по умолчанию будут жестко
заданы
3

Хотя я стараюсь избегать передачи массивов в конструктор, иногда я нахожу необходимым обработать значение входящего массива (например, для класса, который читает значения из файла конфигурации).

В таком случае я воспользуюсь функциями массива PHP, чтобы убедиться, что я работаю именно с тем, с чем, я думаю, я работаю:

public function import( array $incoming )
{
  $defaults = array(
      'foo' => DEFAULT_FOO
    , 'bar' => DEFAULT_BAR
    ...
  );

  $values = array_merge($defaults, array_intersect_key($incoming, $defaults));

  ...
}

Эта последняя строка используется array_merge()для перезаписи любых значений $defaultsсоответствующими значениями из $incoming. Я также использую, array_intersect_key()чтобы убедиться, что результирующий массив не содержит никаких дополнительных ключей, которые класс / метод не будет знать, как обрабатывать.


источник
Здравствуйте, каково поведение, если $ defaults содержит массив вместо простых переменных?
Pol Dellaiera
@PolDellaiera Посмотрите на array_merge_recursive.