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

StackOverflow https://stackoverflow.com/questions/3162870

  •  02-10-2019
  •  | 
  •  

Вопрос

Скажи гипотетически у меня есть класс ...

класс основной {$ prop1 = 2; $ prop2 = 23; ... $ Prop42 = "что"; Функция __Construct ($ arg_array) {foreach ($ arg_array в качестве $ ключа => $ val) {$ this -> $ ключ = $ val; }}}

Скажи, что я создаю и объекту ...

$ Атрибуты = массив («Проп1» => 1, «Проп2» => 35235, «Проп3» => «Тест»); $ O = новые основные ($ атрибуты);

Предоставление значений свойств по умолчанию, если не предоставлено пользователем, очевидно. Но что, если я захочу принуждать произвольные пределы на предоставленные пользователю значения для свойств объекта? Что, если я хочу принять $prop1 быть int, будь не менее 1, и будьте не более 5. И, $prop42 быть типа string, не меньше, чем «а», а не больше, чем «Z»? Для этого, какой был бы самый чистый способ, сохраняя сценарий как можно короткое и сладкое, используя любую возможную язык или трюк?

Я застрял __construct() Проверка поставляемых значений против массива правила, построенного как ...

$ допустимый = массив («PROP1» => массив («Тип» => 'int', 'allable_values' => массив ('min' => 1, 'max' => 5)), "prop2" => массив («Тип» => «int», «Allowable_Values» => Массив (1, 235, 37, 392, 13, 409, 3216)), ... "Prop42" => массив ('Тип' => 'string ', «Allowable_Values» => Array (' min '=>' a ',' max '=>' z ')));

Как вы можете увидеть prop2, Моя функция валидации начинает получать довольно грязную с таким количеством «если я должен учитывать не только диапазоны, но и список разрешенных значений. С помощью кода проверки и этому массиву правила мой сценарий становится довольно громоздким.

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

Это было полезно?

Решение

Я побежал в подобную проблему на днях. Вот что я бы сделал:

   private $props;
   private $rules; 

   function __construct($params) {

      // or you can get the rules from another file, 
      // or a singleton as I suggested

      $this->rules = array (array('type' => 'range', 'min' => 10, 'max' => 20), 
        array('type' => 'in_set', 'allowed' => array(1,2,3)));

      for ($i=0; $i<count($params); $i++) {

         if ($this->check($params[$i], $this->rules($i))
            $this->props[$i] = $params[$i];
         else
            throw new Exception('Error adding prop ' . $i);
      }

   }


   function check($value, $rule) {
      switch($rule['type']) {
         case 'range':
            return ($rule['min'] <= $value && $value <= $rule['max']);  

         case 'in_set':
            return (in_array($value, $rule['allowed']));

         // and so on
      }
   }

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

Редактировать: Кстати, на самом деле нет смысла в типе тестирования в PHP. Это как не очень надежный и ненужный.

Редактировать 2: вместо того, чтобы иметь глобальную переменную с правилами, вы можете использовать Синглтон:

Другие советы

Геттерс и посетители

class Main {
  private $prop1;
  private $prop2;
  private $prop3;

  public function __construct( $p1 , $p2 , $p3 )
  {
    $this->setProp1($p1);
    $this->setProp2($p2);
    $this->setProp3($p3);
  }

  public function setProp1($p1)
  {
    // conditional checking for prop1
    if(!$ok) throw new Exception('problem with prop1');
    $this->prop1 = $p1;
  }

  //.. and so on
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top