manera descuidada menos para hacer cumplir valores admisibles o rangos de propiedades de clase

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

  •  02-10-2019
  •  | 
  •  

Pregunta

Say hipotéticamente que tiene una clase ...

class Main {

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

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

Say creo y objeto ...

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

Proporcionar a los valores predeterminados de la propiedad si no suministrados por el usuario es obvia. Pero lo que si quiero hacer cumplir los límites arbitrarios en los valores suministrados por el usuario para las propiedades del objeto? ¿Y si quiero hacer cumplir $prop1 a ser de int, no será inferior a 1, y no será superior a 5. Y, $prop42 a ser de tipo string, no menos que 'A', y no mayor de 'Z'? Para este propósito, ¿cuál sería la manera más limpia, manteniendo el guión lo más corto y dulce como sea posible, usando cualquier posible característica del lenguaje o truco?

Estoy atascado en la comprobación de los valores suministrados __construct() contra una variedad regla construido como tal ...

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

Como se puede ver por prop2, mi función de validación está comenzando a causar problemas bonita con tantos 'si-entonces reiterar de nuevo' bloques ya que tengo que representan no sólo varía, pero una lista de valores permitidos. Con el código de validación y esta matriz regla, mi guión es cada vez más voluminosos.

La pregunta es, ¿cómo la estructura I mis propiedades de la clase o de clase o el código de validación o cualquier otro aspecto de mi guión sea lo más corto y conciso como sea posible para permitir rango de propiedad y el cumplimiento de valor? ¿Hay una característica del lenguaje o un truco para manejar esto de manera más elegante? Yo he llegado a una pared de ladrillo, el límite de este lenguaje? ¿Hay ejemplos de otros idiomas que pueden implementar fácilmente este que pueden proporcionar alguna pista?

¿Fue útil?

Solución

me encontré con un problema similar, el otro día. Esto es lo que haría:

   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 usted tiene muchos parámetros, se puede utilizar una matriz y iterar a través de eso. Si las reglas de validación siempre van a ser los mismos, se puede poner en un archivo y cargar por separado que en su constructor o lo que sea.

Edit: Por cierto, no hay realmente ningún punto en el ensayo de tipo en PHP. Es a la vez no muy fiables e innecesaria.

EDIT 2: En lugar de tener una variable global con las reglas, se puede utilizar un Singleton :

Otros consejos

captadores y definidores

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
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top