Наименее небрежный способ обеспечить обеспечение допустимых значений или диапазон для свойств класса
Вопрос
Скажи гипотетически у меня есть класс ...
класс основной {$ 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
}