Cómo definir un objeto vacío en PHP

384

con una nueva matriz hago esto:

$aVal = array();

$aVal[key1][var1] = "something";
$aVal[key1][var2] = "something else";

¿Existe una sintaxis similar para un objeto?

(object)$oVal = "";

$oVal->key1->var1 = "something";
$oVal->key1->var2 = "something else";
ed209
fuente
13
$var = (object) (boolean) (string) (int) (array) new StdClass; Ya sabes, solo para estar a salvo.
Xeoncross
1
Google ha indexado el título de la pregunta como: Arrays - How to define an empty object in PHP. No tiene nada que ver con las matrices
Kolob Canyon

Respuestas:

848
$x = new stdClass();

Un comentario en el manual lo resume mejor:

stdClass es el objeto PHP predeterminado. stdClass no tiene propiedades, métodos o padre. No es compatible con métodos mágicos y no implementa interfaces.

Cuando lanza un escalar o matriz como Objeto, obtiene una instancia de stdClass. Puede usar stdClass siempre que necesite una instancia de objeto genérico.

zombat
fuente
55
$ o = (objeto) NULL; - Si un objeto se convierte en un objeto, no se modifica. Si un valor de cualquier otro tipo se convierte en un objeto, se crea una nueva instancia de la clase incorporada stdClass. Si el valor era NULL, la nueva instancia estará vacía. Las matrices se convierten en un objeto con propiedades nombradas por claves y los valores correspondientes. Para cualquier otro valor, una variable miembro llamada escalar contendrá el valor.
DDS
11
Solo digo stdClassen mi cabeza como "clase estándar"
sjagr
1
Si sigues olvidando usa mi respuesta :)
RafaSashi
26
Si encuentra "no encontrado": new \stdClass(); PHP Namespace Doc
2540625
3
@IvanCastellanos, ¿podría explicar cómo puede recordar stdClass()la palabra AIDS?
Adam
117

La forma estándar de crear un objeto "vacío" es:

$oVal = new stdClass();

Pero, con PHP> = 5.4, personalmente prefiero usar:

$oVal = (object)[];

Es más corto y personalmente lo considero más claro porque stdClass podría ser engañoso para los programadores novatos (es decir, "¡Hola, quiero un objeto, no una clase!" ...).

Lo mismo con PHP <5.4 es:

$oVal = (object) array();

(object)[]es equivalente a new stdClass().

Vea el manual de PHP ( aquí ):

stdClass : creado mediante la conversión de tipos a objetos.

y ( aquí ):

Si un objeto se convierte en un objeto, no se modifica. Si un valor de cualquier otro tipo se convierte en un objeto, se crea una nueva instancia de la clase incorporada stdClass .


Sin embargo, recuerde que vacío ($ oVal) devuelve falso , como @PaulP dijo:

Los objetos sin propiedades ya no se consideran vacíos.

Con respecto a su ejemplo, si escribe:

$oVal = new stdClass();
$oVal->key1->var1 = "something"; // PHP creates  a Warning here
$oVal->key1->var2 = "something else";

PHP crea la siguiente Advertencia, creando implícitamente la propiedad key1(un objeto en sí mismo)

Advertencia: crear un objeto predeterminado a partir de un valor vacío

Esto podría ser un problema si su configuración (consulte el nivel de informe de errores ) muestra esta advertencia al navegador. Este es otro tema completo, pero un enfoque rápido y sucio podría estar utilizando el operador de control de errores (@) para ignorar la advertencia:

$oVal = new stdClass();
@$oVal->key1->var1 = "something"; // the warning is ignored thanks to @
$oVal->key1->var2 = "something else";
cgaldiolo
fuente
3
En lugar de solucionar el problema, estás creando uno nuevo. El problema que necesita solución es que las personas deben saber lo que stdClasshace.
Pacerier
2
Escribí lo que stdClasshace. Utilicé stdClassel código que responde a la pregunta. Lo siento, pero no estoy creando un nuevo problema, esa fue mi opinión personal (como escribí).
cgaldiolo
66
"preferencia personal"! = "problema"
cgaldiolo
44
@Pacerier, no entiendo tu terquedad. La pregunta era 'Cómo definir un objeto vacío en PHP'. Mi respuesta es correcta y escribí para usar "new stdClass ()". El código que le proporcioné al usuario 'ed209' es correcto y usé "new stdClass ()". Además, agregué una opinión personal y utilicé una audaz "personalmente" para dejar en claro que ese no era el camino "estándar". En mi humilde opinión, un problema que merece tantos comentarios debería ser al menos una respuesta incorrecta. En cambio, si se tiene en cuenta una opinión personal un problema, tal vez este es un problema para un intercambio constructivo de ideas.
cgaldiolo
99
Realmente me gusta la taquigrafía(object) []
Rahil Wazir
35

Quiero señalar que en PHP no existe el objeto vacío en sentido:

$obj = new stdClass();
var_dump(empty($obj)); // bool(false)

pero por supuesto $ obj estará vacío.

Por otro lado, la matriz vacía significa vacío en ambos casos

$arr = array();
var_dump(empty($arr));

Cita de la función de registro de cambios vacía

Los objetos sin propiedades ya no se consideran vacíos.

PaulP
fuente
No pude encontrar esa cita en el registro de cambios para vacío.
powpow12
@ powpow12 Solía ​​estar allí . Fue cambiado en 5.0.0.
Stanley Umeanozie
18

php.net dijo que es mejor:

$new_empty_object = new stdClass();
HungryCoder
fuente
Sí, esta es la forma recomendada.
Hudson Pereira
14

Me encanta lo fácil que es crear objetos de tipo anónimo en JavaScript:

//JavaScript
var myObj = {
    foo: "Foo value",
    bar: "Bar value"
};
console.log(myObj.foo); //Output: Foo value

Así que siempre trato de escribir este tipo de objetos en PHP como lo hace javascript :

//PHP >= 5.4
$myObj = (object) [
    "foo" => "Foo value",
    "bar" => "Bar value"
];

//PHP < 5.4
$myObj = (object) array(
    "foo" => "Foo value",
    "bar" => "Bar value"
);

echo $myObj->foo; //Output: Foo value

Pero como esto es básicamente una matriz, no puede hacer cosas como asignar funciones anónimas a una propiedad como lo hace js:

//JavaScript
var myObj = {
    foo: "Foo value",
    bar: function(greeting) {
        return greeting + " bar";
    }
};
console.log(myObj.bar("Hello")); //Output: Hello bar

//PHP >= 5.4
$myObj = (object) [
    "foo" => "Foo value",
    "bar" => function($greeting) {
        return $greeting . " bar";
    }
];
var_dump($myObj->bar("Hello")); //Throw 'undefined function' error
var_dump($myObj->bar); //Output: "object(Closure)"

Bueno, puedes hacerlo, pero IMO no es práctico / limpio:

$barFunc = $myObj->bar;
echo $barFunc("Hello"); //Output: Hello bar

Además, al usar este Synthax puedes encontrar algunas sorpresas divertidas , pero funciona bien en la mayoría de los casos.

Campsjos
fuente
1
Esta debería ser la respuesta aceptada
Mike Aron
11

Además de la respuesta de zombat si sigues olvidando stdClass

   function object(){

        return new stdClass();

    }

Ahora puedes hacer:

$str='';
$array=array();
$object=object();
RafaSashi
fuente
Me encanta esta técnica, aunque la mayoría de los IDE no resaltarán el término "objeto" como una función que podría ser confusa para otros programadores. Pero bueno, ¡funciona para mí!
Brixster
7

Puede usar new stdClass()(que se recomienda):

$obj_a = new stdClass();
$obj_a->name = "John";
print_r($obj_a);

// outputs:
// stdClass Object ( [name] => John ) 

O puede convertir una matriz vacía en un objeto que produce una nueva instancia vacía de la clase incorporada stdClass:

$obj_b = (object) [];
$obj_b->name = "John";
print_r($obj_b);

// outputs: 
// stdClass Object ( [name] => John )  

O puede convertir el nullvalor en un objeto que produzca una nueva instancia vacía de la clase incorporada stdClass:

$obj_c = (object) null;
$obj_c->name = "John";
print($obj_c);

// outputs:
// stdClass Object ( [name] => John ) 
Amr
fuente
5

para acceder a los datos en una clase estándar de la misma manera que lo hace con una matriz asociativa, simplemente use la sintaxis {$ var}.

$myObj = new stdClass;
$myObj->Prop1 = "Something";
$myObj->Prop2 = "Something else";

// then to acces it directly

echo $myObj->{'Prop1'};
echo $myObj->{'Prop2'};

// or what you may want

echo $myObj->{$myStringVar};
GCoro
fuente
4

Como otros han señalado, puede usar stdClass. Sin embargo, creo que es más limpio sin el (), así:

$obj = new stdClass;

Sin embargo, según la pregunta, parece que lo que realmente desea es poder agregar propiedades a un objeto sobre la marcha. No necesita usar stdClass para eso, aunque puede hacerlo. Realmente puedes usar cualquier clase. Simplemente cree una instancia de objeto de cualquier clase y comience a configurar las propiedades. Me gusta crear mi propia clase cuyo nombre es simplemente o con alguna funcionalidad extendida básica que me gusta usar en estos casos y es agradable para extender desde otras clases. Básicamente es mi propia clase de objeto base. También me gusta tener una función simplemente llamada o (). Al igual que:

class o {
  // some custom shared magic, constructor, properties, or methods here
}

function o() {
  return new o;
}

Si no le gusta tener su propio tipo de objeto base, simplemente puede hacer que o () devuelva una nueva stdClass. Una ventaja es que o es más fácil de recordar que stdClass y es más corto, independientemente de si lo usa como nombre de clase, nombre de función o ambos. Incluso si no tiene ningún código dentro de su clase o, aún es más fácil de memorizar que stdClass (que puede invocar la idea de una 'clase de enfermedad de transmisión sexual'). Si personaliza la clase o, puede encontrar un uso para la función o () en lugar de la sintaxis del constructor. Es una función normal que devuelve un valor, que es menos limitado que un constructor. Por ejemplo, un nombre de función se puede pasar como una cadena a una función que acepta un parámetro invocable. Una función también admite el encadenamiento. Entonces puedes hacer algo como:

Este es un gran comienzo para un "lenguaje" base para construir otras capas de lenguaje sobre las cuales la capa superior se escribe en DSL internos completos. Esto es similar al estilo de desarrollo lisp, y PHP lo admite mucho mejor de lo que la mayoría de la gente piensa. Me doy cuenta de que esto es un poco tangente a la pregunta, pero la pregunta toca lo que creo que es la base para utilizar completamente el poder de PHP.

still_dreaming_1
fuente
2
@Pacerier, ¿te refieres a la falta de paréntesis? ;) cis.upenn.edu/~matuszek/General/JavaSyntax/parentheses.html
still_dreaming_1
1
Eso es un error tipográfico, debe ser sin paréntesis.
Pacerier
@Pacerier good point english.stackexchange.com/questions/130219/…
still_dreaming_1
4

Si desea crear un objeto (como en javascript) con propiedades dinámicas, sin recibir una advertencia de propiedad indefinida.

class stdClass {

public function __construct(array $arguments = array()) {
    if (!empty($arguments)) {
        foreach ($arguments as $property => $argument) {
            if(is_numeric($property)):
                $this->{$argument} = null;
            else:
                $this->{$property} = $argument;
            endif;
        }
    }
}

public function __call($method, $arguments) {
    $arguments = array_merge(array("stdObject" => $this), $arguments); // Note: method argument 0 will always referred to the main class ($this).
    if (isset($this->{$method}) && is_callable($this->{$method})) {
        return call_user_func_array($this->{$method}, $arguments);
    } else {
        throw new Exception("Fatal error: Call to undefined method stdObject::{$method}()");
    }
}

public function __get($name){
    if(property_exists($this, $name)):
        return $this->{$name};
    else:
        return $this->{$name} = null;
    endif;
}

public function __set($name, $value) {
    $this->{$name} = $value;
}

}

$obj1 = new stdClass(['property1','property2'=>'value']); //assign default property
echo $obj1->property1;//null
echo $obj1->property2;//value

$obj2 = new stdClass();//without properties set
echo $obj2->property1;//null
fredtma
fuente
4

Puedes probar de esta manera también.

<?php
     $obj = json_decode("{}"); 
     var_dump($obj);
?>

Salida:

object(stdClass)#1 (0) { }
Mukesh Jeengar
fuente
4

Use un objeto genérico y asigne pares de valores clave.

$oVal = new stdClass();
$oVal->key = $value

O lanzar una matriz en un objeto

$aVal = array( 'key'=>'value' );
$oVal = (object) $aVal;
Anthony Awuley
fuente
3

Si no quieres hacer esto:

$myObj = new stdClass();
$myObj->key_1 = 'Hello';
$myObj->key_2 = 'Dolly';

Puede usar uno de los siguientes:

PHP> = 5.4

$myObj = (object) [
    'key_1' => 'Hello',
    'key_3' => 'Dolly',
];

PHP <5.4

$myObj = (object) array(
    'key_1' => 'Hello',
    'key_3' => 'Dolly',
);
Vasil Nikolov
fuente
3

Aquí un ejemplo con la iteración:

<?php
$colors = (object)[];
$colors->red = "#F00";
$colors->slateblue = "#6A5ACD";
$colors->orange = "#FFA500";

foreach ($colors as $key => $value) : ?>
    <p style="background-color:<?= $value ?>">
        <?= $key ?> -> <?= $value ?>
    </p>
<?php endforeach; ?>
Fingerman
fuente
0

Tienes esta técnica mala pero útil:

$var = json_decode(json_encode([]), FALSE);
Kerollmops
fuente
0

stdClass es el objeto PHP predeterminado. stdClass no tiene propiedades, métodos o padre. No es compatible con métodos mágicos y no implementa interfaces.

Cuando lanza un escalar o matriz como Objeto, obtiene una instancia de stdClass. Puede usar stdClass siempre que necesite una instancia de objeto genérico.

<?php
// ways of creating stdClass instances
$x = new stdClass;
$y = (object) null;        // same as above
$z = (object) 'a';         // creates property 'scalar' = 'a'
$a = (object) array('property1' => 1, 'property2' => 'b');
?>

¡stdClass NO es una clase base! Las clases de PHP no se heredan automáticamente de ninguna clase. Todas las clases son independientes, a menos que extiendan explícitamente otra clase. PHP difiere de muchos lenguajes orientados a objetos a este respecto.

<?php
// CTest does not derive from stdClass
class CTest {
    public $property1;
}
$t = new CTest;
var_dump($t instanceof stdClass);            // false
var_dump(is_subclass_of($t, 'stdClass'));    // false
echo get_class($t) . "\n";                   // 'CTest'
echo get_parent_class($t) . "\n";            // false (no parent)
?>

No puede definir una clase llamada 'stdClass' en su código. Ese nombre ya lo usa el sistema. Puede definir una clase llamada 'Objeto'.

Podría definir una clase que extienda stdClass, pero no obtendría ningún beneficio, ya que stdClass no hace nada.

(probado en PHP 5.2.8)

Harshal Lonare
fuente