Am wenigsten schlampig Weise zulässige Werte oder Bereiche für Klasseneigenschaften zu erzwingen

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

  •  02-10-2019
  •  | 
  •  

Frage

Say hypothetisch habe ich eine Klasse ...

class Main {

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

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

Say I erstellen und Objekt ...

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

für Standardeigenschaftswerte Providing, wenn nicht durch den Benutzer geliefert, ist offensichtlich. Aber was, wenn ich will auf gelieferten Werte für Eigenschaften Objekt Benutzer beliebige Grenzen erzwingen? Was passiert, wenn ich $prop1 erzwingen möchten von int sein, nicht weniger als 1 und nicht größer als 5. Und $prop42 vom Typ string zu sein, nicht weniger als ‚A‘, und nicht mehr als ‚Z‘? Zu diesem Zweck, was der sauberste Weg wäre, das Skript so kurz und süß wie möglich zu halten, indem jede mögliche Sprache-Funktion oder Trick?

Ich bin in __construct() Überprüfung gelieferten Werte gegen eine Regel Array wie so ...

gebaut stecken
$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'
            )
        )
    );

Wie Sie prop2 sehen können, meine Validierungsfunktion mit so vielen ziemlich chaotisch zu bekommen beginnt, ‚if-then-iterate-wieder‘ Blöcke, wie ich Konto haben nicht nur für Bereiche, sondern eine Liste der zulässigen Werte. Mit dem Validierungscode und dieser Regel Array, mein Skript wird immer ziemlich sperrig.

Die Frage ist, wie kann ich meine Klasse oder Klasseneigenschaften oder der Validierungscode oder andere Aspekte meines Skript strukturieren so kurz und prägnant wie möglich sein Eigentum Bereich und Wert Durchsetzung zu ermöglichen? Gibt es eine Sprache-Funktion oder Trick, um damit zu umgehen eleganter? Habe ich erreicht eine Mauer, die Grenze dieser Sprache? Gibt es Beispiele aus anderen Sprachen, die diese leicht implementieren können, die einen Hinweis liefern können?

War es hilfreich?

Lösung

Ich lief in ein ähnliches Problem den anderen Tag. Hier ist, was ich tun würde:

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

Wenn Sie viele Parameter haben, können Sie ein Array und durchlaufen diese verwenden. Wenn Ihre Validierungsregeln immer werden die gleichen sein, können Sie sie in einer separaten Datei und Last legen, dass in Ihrem Konstruktor oder was auch immer.

EDIT: Übrigens, gibt es wirklich keinen Sinn, bei der Prüfung Typ in PHP. Es ist beides nicht sehr zuverlässig und unnötig.

EDIT 2: Statt eine globale Variable mit den Regeln zu haben, können Sie ein

Andere Tipps

Getter und Setter

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