Как исправить уведомление «неопределенный индекс» элегантно? - PullRequest
0 голосов
/ 10 июня 2018

Это, вероятно, общий вопрос, и 99% решений, которые я прочитал, состоит в том, чтобы просто использовать isset, чтобы быть безопасным и многословным.Тем не менее, я все еще думаю, что это не так элегантно, а также немного повторяется.

Чтобы понять мой вопрос немного лучше, вот мой общий код:

  public static function buildObject(array $userProperties) {
    // Here, I'm building a user from an associative array.
    // If the developer passes in an array with missing name or address,
    // this will generate an undefined index notice!

    $user = new User();
    $user->setName($userProperties['name']);
    $user->setAddress($userProperties['address']);
    return $user;
  }

То, что я имеюдо сих пор пробовал:

  1. Добавление в isset() проверок на все установленные вызовы.Это может быть неплохой идеей для этого примера, но у меня есть несколько огромных классов с множеством свойств, и он выглядит и выглядит очень повторяющимся.

  2. Обеспечение безопасности массива за счет циклического изменения свойстви установка их в нуль, если они не присутствуют в массиве.Это не так уж плохо в коде, но выглядит как обходной путь.

  3. Использование оператора null coalesce ?? null.Это также кажется повторяющимся и не слишком читабельным.

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

1 Ответ

0 голосов
/ 10 июня 2018

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

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

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

Или выможет создать объект-конструктор с открытым интерфейсом, так что создание пользователя вообще не требует массива:

 $user = UserBuilder::start()
             ->setName('Foo')
             ->setLastName('Bar')
             ->build();

Но все зависит от специфики вашей реализации, от дополнительной работы, которую вы желаетепройти через это относительное удобство и то, что конкретно вы хотите решить.

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

Например:

function foo(array $arguments) {
    $arguments = array_merge( [
             'name'     => null,
             'lastName' => null,
             'role'     => ROLE_USER
           ],
           $arguments);
}

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

В конце вам придется решить, что работаетдля вас, что вы считаете элегантным, и какая реализация действительно стоит в вашем проекте.

...