2012-05-03 21 views
7

¿Es posible establecer varias propiedades a la vez para un objeto en php? En vez de hacer :Objeto PHP, establecer múltiples propiedades

$object->prop1 = $something; 
$object->prop2 = $otherthing; 
$object->prop3 = $morethings; 

hacer algo como:

$object = (object) array(
    'prop1' => $something, 
    'prop2' => $otherthing, 
    'prop3' => $morethings 
); 

pero sin sobrescribir el objeto.

+3

¿Por qué querrías ofuscar lo que el código está haciendo de esta manera? En algún momento, alguien (** quizás usted **) tendrá que leer este código y hacer algo como esto solo lo hará más difícil de entender. – rdlowrey

+0

¿Por qué no simplemente pegar esto en un archivo php y ejecutarlo? En lugar de preguntar aquí si funcionaría, inténtalo tú mismo. – Yoshi

+2

Simplemente crea una función auxiliar para hacerlo por ti. Pase el objeto y la matriz. –

Respuesta

14

No es como usted quiere. pero esto se puede hacer mediante el uso de un bucle.

$map = array(
    'prop1' => $something, 
    'prop2' => $otherthing, 
    'prop3' => $morethings 
); 

foreach($map as $k => $v) 
    $object->$k = $v; 

Ver solo 2 líneas adicionales.

+1

No son 2 líneas más, pero ** 50% más líneas **; peor si solo hay dos propiedades para establecer. En realidad, son 3 líneas si no hacemos trampa y usamos los preventivos de errores '{' y '}'. – Pacerier

+1

@Pacerier Espero que estés pescando. En un caso de uso real, tales matrices podrían contener cientos de valores. Por supuesto, si entrega solo 2 valores, es un trabajo extra porque son tres líneas. Pero si trabaja con una matriz con 358 valores, esta solución se mantiene en tres líneas. – Holonaut

+0

@Holonaut, debe ser un comentario serio, no un comentario troll. Claro, es probable que existan casos de uso donde haya cientos de valores, pero muchos casos de uso tienen solo dos, tres o cuatro valores. – Pacerier

4

Yo te recomendaría no hazlo. En serio, no.

Su código es MUCHO más limpio de la primera manera, es más claro de sus intenciones, y no está enfocando su código en la medida en que en algún momento en el futuro alguien miraría su código y pensaría "¿Qué diablos era el idiota pensando "?

Si insiste en hacer algo que claramente es el camino equivocado, siempre puede crear una matriz, repetirla y establecer todas las propiedades en un bucle. Aunque no te daré código. Es malvado

+0

No es cierto. Otros lenguajes tienen esta sintaxis y son aclamados como ** código limpio **. Depende de como lo uses. – Pacerier

2

Se puede escribir algunos fijadores para el objeto que devuelven el objeto:

public function setSomething($something) 
{ 
$this->something = $something; 
return $this; //this will return the current object 
} 

A continuación, podría hacer:

$object->setSomething("something") 
     ->setSomethingelse("somethingelse") 
     ->setMoreThings("some more things"); 

que tendría que escribir un regulador para cada propiedad como una función __set no es capaz de devolver un valor

O bien, configure una sola función para aceptar una matriz de propiedades => valores y configure todo? pasar

public function setProperties($array) 
{ 
    foreach($array as $property => $value) 
    { 
    $this->{$property} = $value; 
    } 
    return $this; 
} 

y en la matriz:

$object->setProperties(array('something' => 'someText', 'somethingElse' => 'more text', 'moreThings'=>'a lot more text')); 
+0

"necesita escribir un setter para cada propiedad como una función __set no puede devolver un valor". Vea mi respuesta para una forma de evitar esto. –

8

Usted debe mirar Object Oriented PHP Best Practices:

"ya que las funciones setter regresan $ esto usted puede encadenarlos de este modo:"

$object->setName('Bob') 
     ->setHairColor('green') 
     ->setAddress('someplace'); 

Esto, por cierto, se conoce como fluent interface.

+3

Esto es completamente diferente. Está hablando de atajos para crear ** propiedades de variables ** y eso no tiene nada que ver con tu respuesta. – Pacerier

+0

Si hubiera estado hablando sobre el uso de 'public function __set ($ k, $ v) {$ this -> $ k = $ v; return $ this;} ', then it * still * no funcionaría porque' (($ obj-> k = "v") -> k2) = "v2"; 'es un error de sintaxis. – Pacerier

0

realidad no haría esto .... pero por diversión me gustaría

$object = (object) ($props + (array) $object); 

se termina con un compuesto de stdClass $ objetos propiedades públicas, por lo que pierde su tipo.

+0

Esto anula el objeto que no cumple con el requisito de la pregunta. '$ object === $ old_object' ya no es verdadero. – Pacerier

0

Método objectThis() a las propiedades de matriz de clases de transtypage o array a stdClass. El uso de la página de transposición directa (objeto) eliminaría el índice numérico, pero al usar este método mantendrá el índice numérico.

public function objectThis($array = null) { 
    if (!$array) { 
     foreach ($this as $property_name => $property_values) { 
      if (is_array($property_values) && !empty($property_values)) { 
       $this->{$property_name} = $this->objectThis($property_values); 
      } else if (is_array($property_values) && empty($property_values)) { 
       $this->{$property_name} = new stdClass(); 
      } 
     } 
    } else { 
     $object = new stdClass(); 
     foreach ($array as $index => $values) { 
      if (is_array($values) && empty($values)) { 
       $object->{$index} = new stdClass(); 
      } else if (is_array($values)) { 
       $object->{$index} = $this->objectThis($values); 
      } else if (is_object($values)) { 
       $object->{$index} = $this->objectThis($values); 
      } else { 
       $object->{$index} = $values; 
      } 
     } 
     return $object; 
    } 
} 
+0

la explicación anterior a la muestra del código podría usar alguna mejora –

0

Comprendo que esto es una cuestión de edad, sino para el beneficio de otros que vienen a través de ella, he resuelto esto mismo hace poco y quería compartir el resultado

<?php 
    //Just some setup 
    header('Content-Type: text/plain'); 
    $account = (object) array(
     'email' => 'foo', 
     'dob'=>((object)array(
      'day'=>1, 
      'month'=>1, 
      'year'=>((object)array('century'=>1900,'decade'=>0)) 
     )) 
    ); 
    var_dump($account); 
    echo "\n\n==============\n\n"; 

    //The functions 
    function &getObjRef(&$obj,$prop) { 
     return $obj->{$prop}; 
    } 

    function updateObjFromArray(&$obj,$array){ 
     foreach ($array as $key=>$value) { 
      if(!is_array($value)) 
       $obj->{$key} = $value; 
      else{ 
       $ref = getObjRef($obj,$key); 
       updateObjFromArray($ref,$value); 
      } 
     } 
    } 

    //Test 
    updateObjFromArray($account,array(
     'id' => '123', 
     'email' => '[email protected]', 
     'dob'=>array(
      'day'=>19, 
      'month'=>11, 
      'year'=>array('century'=>1900,'decade'=>80) 
     ) 
    )); 
    var_dump($account); 

Obviamente no hay medidas de seguridad integradas en La advertencia principal es que la función updateObjFromArray asume que para cualquier matriz anidada dentro de $array, la clave correspondiente en $obj ya existe y es un objeto, esto debe ser cierto o tratarlo como si un objeto arrojara un error.

Espero que esto ayude! :)

Cuestiones relacionadas