Проверка ряда значений через empty

203
08 апреля 2017, 00:44

Есть задача: нужно проверить на предмет наличия значений в ряде переменных. Есть ли какой-то "человеческий" способ или каждую нужно перебирать через empty(или isset) ?

Есть конструкция вида:

    <?if(!empty($cPhone)||!empty($cUrl)||!empty($cDirectionLink['value'])||!empty($cLocation['value']['address'])):?>
<?echo 1;?>
<?else:?>
<?echo 0;?>
<?endif;?>
Answer 1

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

Проблема вашего кода:

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

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

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

Например, в вашем случае, было бы удобно воспользоваться чем-то следующим:

class Validator {
    protected $data;
    public function add($var) {
         $this->data[] = $var;
         return $this;
    }
    public function validate() : bool {
         $result = true;         
         foreach ($data as $item) {
              if (empty($item)) { 
                  $result = false;
              }
         }
         return $result;
    }
}

$validator = new Validator();
$result = $validator->add($cPhone)
                    ->add($cUrl)
                    ->add($cDirectionLink['value'])
                    ->add($cLocation['value']['address'])
                    ->validate();
echo ($result) ? 1 : 0;

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

class Validator {
    protected $data;
    public function add($var) {
         $this->data[] = $var;
         return $this;
    }
    public function validate(callable $call) : bool {
         $result = true;         
         foreach ($this->data as $item) {
              if ($call($item)) { 
                  $result = false;
              }
         }
         return $result;
    }
}

$validator = new Validator();
$result = $validator->add(0)
                    ->validate(function ($a) { return empty($a); });
echo ($result) ? 1 : 0;

Работает на PHP 7.

Answer 2

Ваш код более безопасен, т.к. когда обращаются к функции empty, она проверяет на isset и на empty.

Есть ещё вариант опустить обращение к функции empty и использовать условие:

<?if($cPhone || $cUrl || $cDirectionLink['value'] || $cLocation['value']['address']):?>
    <?echo 1;?>
<?else:?>
    <?echo 0;?>
<?endif;?>

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

READ ALSO
Скрипт лайков на WordPress + Ajax

Скрипт лайков на WordPress + Ajax

Пытаюсь без сторонних плагинов сделать лайкиТак чтобы нажал один раз - "+1" лайк, нажал второй раз - "-1" лайк

309
Запись в массив

Запись в массив

Есть такой функционал

199
Laravel мультиязычность

Laravel мультиязычность

Добрый вечерОпыта в ларе не много

373
Как прикрепить файл к форме заявки woocommerce?

Как прикрепить файл к форме заявки woocommerce?

Всем доброй ночиПоявилась нужда сделать возможным прикрепить 1 файл к форме заявки woocommerce, чтобы при отправке заявки на почту - этот файл прикреплялся

302