Moins de rigueur façon à respecter les valeurs admissibles ou des plages de propriétés de classe

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

  •  02-10-2019
  •  | 
  •  

Question

Dis hypothétiquement J'ai une classe ...

class Main {

    $prop1 = 2;
    $prop2 = 23;
    ...
    $prop42 = "what";

    function __construct($arg_array) {
        foreach ($arg_array as $key => $val) {
            $this->$key = $val;
            }
        }
    }

Dis créer et objet ...

$attributes = array("prop1"=>1, "prop2"=>35235, "prop3"=>"test");
$o = new Main($attributes);

Fournir des valeurs de propriété par défaut si non fourni par l'utilisateur est évidente. Mais si je veux appliquer des limites arbitraires sur les valeurs fournies par l'utilisateur pour les propriétés de l'objet? Et si je veux faire respecter $prop1 être de int, pas moins de 1 et pas supérieur à 5. Et, $prop42 être de type string, pas moins de « A », et pas plus que « Z »? A cet effet, quelle serait la meilleure façon, en gardant le script aussi court et doux que possible, en utilisant une fonctionnalité de langage possible ou astuce?

Je suis coincé dans les valeurs fournies contrôle de __construct() contre un ensemble de règles construit comme si ...

$allowable = array(
    "prop1" => array(
        'type' => 'int',
        'allowable_values' => array(
            'min' => 1,
            'max' => 5
            )
        ),
    "prop2" => array(
        'type' => 'int',
        'allowable_values' => array(
            1,
            235,
            37,
            392,
            13,
            409,
            3216
            )
        ),
    ...
    "prop42" => array(
        'type' => 'string',
        'allowable_values' => array(
            'min' => 'A',
            'max' => 'Z'
            )
        )
    );

Comme vous pouvez le voir prop2, ma fonction de validation commence à être assez en désordre avec tant de « if-then-itérer-nouveau » blocs que je dois compte pour les gammes non seulement, mais une liste de valeurs autorisées. Avec le code de validation et ce tableau de règles, mon script devient assez volumineux.

La question est, comment puis-je structurer mes propriétés de classe ou de classe ou le code de validation ou tout autre aspect de mon script pour être aussi bref et concis que possible pour permettre gamme de biens et de l'application de la valeur? Y at-il une fonctionnalité de langage ou astuce pour gérer cette plus élégante? Ai-je atteint un mur de briques, la limite de cette langue? Y a-t-il des exemples d'autres langues qui peuvent facilement mettre en œuvre ce qui peut fournir quelques indices?

Était-ce utile?

La solution

je suis tombé sur un problème similaire, l'autre jour. Voici ce que je ferais:

   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
      }
   }

Si vous avez beaucoup de paramètres, vous pouvez utiliser un tableau et itérer à travers cela. Si vos règles de validation vont toujours être les mêmes, vous pouvez les mettre dans un fichier séparé et la charge que dans votre constructeur ou autre.

EDIT: Soit dit en passant, il n'y a vraiment pas de point dans l'essai du type en PHP. Il est à la fois pas très fiable et inutile.

EDIT 2: Au lieu d'avoir une variable globale avec les règles, vous pouvez utiliser un

Autres conseils

accesseurs

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
}
scroll top