¿Creando un objeto predeterminado a partir de un valor vacío en PHP?
On diciembre 1, 2020 by adminConsidere el siguiente código.
$car = (object)[ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car->{"other"}->{"exterior"}->{$key} = $prop; }
Este es un escenario en el que «d le gusta agregar propiedades a un objeto, unas pocas capas de profundidad a la vez, mientras se itera a través de otros datos. Si no existe, simplemente lo creará, si lo hace, lo anulará. ¡PERFECTO!
Desafortunadamente, esto arrojará la advertencia:
Creando un objeto predeterminado a partir de un valor vacío
Podría resolver el problema comprobando primero si la propiedad existe así:
foreach($exteriorProperties as $key => $prop){ if(!isset($car->other)) $car->other = (object)[]; if(!isset($car->other->exterior)) $car->other->exterior = (object)[]; $car->other->exterior->{$key} = $prop; }
Este no es mi ideal solución. Me pregunto si hay una solución más elegante. Actualmente, estoy usando esto:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
para suprimir las advertencias, pero me preocupa la compatibilidad en el futuro.
No ¿Alguien tiene una solución más elegante para este escenario?
Comentarios
- No ' t use matrices como la respuesta a continuación sugiere, use el objeto correctamente. Las matrices solo son buenas para el código local, compartidas fuera de un archivo o clase significa que está escribiendo claves manualmente, tener que recordarlas, perder una o dos, error tipográfico. Un buen IDE con autocompletar y objetos con getter / setter son un mundo de desarrollo feliz.
Respuesta
Sí, use matrices.
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
De todos modos, la conversión de objetos solo convertirá la matriz más externa. Las matrices anidadas siguen siendo matrices.
\is_array($car->general); // true
¿Por qué necesitas que sean objetos sin forma de todos modos? Definir clases para esos objetos o tratarlos como matrices es la respuesta simple.
Por cierto, $car->{"other"}
es una forma realmente extraña de escribir $car->other
…
Comentarios
- Supongo que ' tienes razón, solo Odio quedar encerrado en matrices todo el tiempo. El
$car->{'other'}
se debe a que la mayoría de mis claves de propiedad provienen de variables de cadena. como$car->{$var1}->{$var2}
Responder
Sí, puede evitar las operaciones condicionales iteradas procesando todos los datos como matrices.
Código: ( Demo )
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
Cuando solo convierte el nivel superior de tipo de objeto a tipo de matriz, puede lanzarlo con (array)
. Si necesita convertir todos los niveles, json codifica todo el objeto, luego decodifica esa cadena en una matriz. Cuando haya terminado de procesar, use las funciones json_
para revertir los datos al tipo de objeto.
Todavía encuentro esto un poco torpe (quizás tan torpe como su enfoque condicional). El beneficio de lo anterior está en la recursividad; Si la profundidad de sus datos cambia, no necesitará modificar el script de procesamiento. Pregúntese si realmente necesita usar un objeto. Si la codificación se simplifica con un tipo de datos diferente, quizás tenga que reconsiderar / refactor.
Ps DEFINITIVAMENTE no escribe el operador stfu (@
) en su código. En casi todas las implementaciones, la técnica es evitable (este es uno de esos casos) y los proyectos con tal sintaxis son categorizados / presumidos como de baja calidad por desarrolladores expertos.
Comentarios
- Gracias, buena valoración. Desafortunadamente, no pude elegir nada más que objetos ya que un programador anterior lo ha codificado como tal.
Deja una respuesta