Domanda

Di 'ipoteticamente ho una classe ...

class Main {

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

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

Say creo e l'oggetto ...

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

Fornire per i valori di proprietà di default se non fornito dall'utente è evidente. Ma cosa succede se voglio far rispettare i limiti arbitrari sui valori forniti dall'utente per le proprietà degli oggetti? Che cosa devo fare per far rispettare $prop1 di essere di int, essere inferiore a 1, ed essere non superiore a 5. E, $prop42 essere di tipo string, non meno di 'A', e non superiore a 'Z'? A tal fine, quale sarebbe il modo più pulito, mantenendo lo script come breve e dolce possibile, utilizzando ogni possibile caratteristica del linguaggio o trucco?

Sono bloccato in __construct() il controllo dei valori forniti da una vasta regola costruita in questo modo ...

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

Come si può vedere dalla prop2, la mia funzione di convalida sta cominciando a diventare piuttosto disordinato con tanti 'if-then-iterare-nuovo' blocchi devo conto non solo varia, ma un elenco di valori consentiti. Con il codice di convalida e questa regola array, il mio script è sempre piuttosto ingombrante.

La domanda è: come posso strutturare la mia proprietà di classe o di classe o il codice di convalida o di qualsiasi altro aspetto del mio script di essere il più breve e conciso possibile per consentire gamma di proprietà e l'applicazione del valore? C'è una caratteristica del linguaggio o di trucco per gestire questo più elegante? Ho raggiunto un muro di mattoni, il limite di questa lingua? Ci sono esempi di altre lingue che si possono facilmente implementare questo che possono fornire qualche indizio?

È stato utile?

Soluzione

mi sono imbattuto in un problema simile l'altro giorno. Ecco quello che vorrei fare:

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

Se si dispone di molti parametri, è possibile utilizzare un array e iterare attraverso quella. Se le regole di validazione stanno andando sempre essere la stessa, è possibile metterli in un file e di carico separato che nel costruttore o qualsiasi altra cosa.

EDIT: A proposito, non c'è davvero alcun senso prove di tipo in PHP. E 'sia poco affidabile e non necessaria.

EDIT 2: Invece di avere una variabile globale con le regole, è possibile utilizzare un Singleton :

Altri suggerimenti

getter e 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
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top