Pregunta

Como sabemos, crear objetos anónimos en JavaScript es fácil, como el siguiente código:

var object = { 
    p : "value", 
    p1 : [ "john", "johnny" ] } ; 
alert(object.p1[1]) ;

Producción:

an alert is raised with value "johnny"

¿Se puede aplicar esta misma técnica en el caso de PHP?¿Podemos crear objetos anónimos en PHP?

¿Fue útil?

Solución

¡Han pasado algunos años, pero creo que necesito mantener la información actualizada!


En php-7 es posible crear clases anónimas, por lo que puede hacer cosas como esta:

<?php

    class Foo {}
    $child = new class extends Foo {};

    var_dump($child instanceof Foo); // true

?>

Puede leer más sobre esto en el RFC (se acepta): https://wiki.php.net/rfc/anonymous_classes

Pero no sé qué tan similar se implementa a Javscript, por lo que puede haber algunas diferencias entre las clases anónimas en javascript y php.

<×Editar:

A partir de los comentarios publicados, aquí está el enlace al manual ahora: http:// php.net / manual / en / language.oop5.anonymous.php

Otros consejos

"Anónimo" no es la terminología correcta cuando se habla de objetos. Sería mejor decir "objeto de tipo anónimo", pero esto no se aplica a PHP.

Todos los objetos en PHP tienen una clase. La clase "predeterminada" es stdClass , y puede crear objetos de esta manera :

$obj = new stdClass;
$obj->aProperty = 'value';

También puede aprovechar enviar una matriz a un objeto para una sintaxis más conveniente:

$obj = (object)array('aProperty' => 'value');
print_r($obj);

Sin embargo, tenga en cuenta que es probable que la conversión de una matriz a un objeto produzca resultados "interesantes" para aquellas claves de matriz que no son nombres de variable PHP válidos, por ejemplo, aquí una respuesta mía que muestra lo que sucede cuando las teclas comienzan con dígitos.

¡Sí, es posible!Usando este simple Objeto anónimo PHP clase.Cómo funciona:

// define by passing in constructor
$anonim_obj = new AnObj(array(
    "foo" => function() { echo "foo"; }, 
    "bar" => function($bar) { echo $bar; } 
));

$anonim_obj->foo(); // prints "foo"
$anonim_obj->bar("hello, world"); // prints "hello, world"

// define at runtime
$anonim_obj->zoo = function() { echo "zoo"; };
$anonim_obj->zoo(); // prints "zoo"

// mimic self 
$anonim_obj->prop = "abc";
$anonim_obj->propMethod = function() use($anonim_obj) {
    echo $anonim_obj->prop; 
};
$anonim_obj->propMethod(); // prints "abc"

Por supuesto, este objeto es una instancia de AnObj clase, por lo que no es realmente anónimo, pero permite definir métodos sobre la marcha, como lo hace JavaScript.

Hasta hace poco, así era como creaba objetos sobre la marcha.

$someObj = json_decode("{}");

Entonces:

$someObj->someProperty = someValue;

Pero ahora voy con:

$someObj = (object)[];

Entonces, como antes:

$someObj->someProperty = someValue;

Por supuesto, si ya conoce las propiedades y los valores, puede establecerlos dentro como se ha mencionado:

$someObj = (object)['prop1' => 'value1','prop2' => 'value2'];

NB: No sé en qué versiones de PHP funciona esto, por lo que deberías tenerlo en cuenta.Pero creo que el primer enfoque (que también es corto si no hay propiedades para establecer en la construcción) debería funcionar para todas las versiones que tienen json_encode / json_decode

Si desea imitar JavaScript, puede crear una clase Object, y así obtener el mismo comportamiento.Por supuesto, esto ya no es del todo anónimo, pero funcionará.

<?php 
class Object { 
    function __construct( ) { 
        $n = func_num_args( ) ; 
        for ( $i = 0 ; $i < $n ; $i += 2 ) { 
            $this->{func_get_arg($i)} = func_get_arg($i + 1) ; 
        } 
    } 
} 

$o = new Object( 
    'aProperty', 'value', 
    'anotherProperty', array('element 1', 'element 2')) ; 
echo $o->anotherProperty[1];
?>

Eso generará elemento 2 .Esto fue robado de un comentario sobre PHP: clases y objetos .

Convertir matriz en objeto:

$obj = (object)  ['myProp' => 'myVal'];

Si desea crear un objeto (como en javascript) con propiedades dinámicas, sin recibir una advertencia de propiedad no definida, cuando no ha establecido un valor para la propiedad

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

¿Se puede aplicar esta misma técnica en el caso de PHP?

No, porque javascript usa prototipos / declaración directa de objetos, en PHP (y muchos otros lenguajes OO) un objeto solo se puede crear a partir de una clase.

Entonces la pregunta es: ¿puedes crear una clase anónima?

De nuevo, la respuesta es no: ¿cómo crearías una instancia de la clase sin poder hacer referencia a ella?

Para alguien que quiere un objeto recursivo:

$o = (object) array(
    'foo' => (object) array(
        'sub' => '...'
    )
);

echo $o->foo->sub;

De la documentación de PHP, algunos ejemplos más:

<?php

$obj1 = new \stdClass; // Instantiate stdClass object
$obj2 = new class{}; // Instantiate anonymous class
$obj3 = (object)[]; // Cast empty array to object

var_dump($obj1); // object(stdClass)#1 (0) {}
var_dump($obj2); // object(class@anonymous)#2 (0) {}
var_dump($obj3); // object(stdClass)#3 (0) {}

?>

$ obj1 y $ obj3 son del mismo tipo, pero $ obj1!== $ obj3.Además, los tres json_encode () se convertirán en un objeto JS simple {}:

<?php

echo json_encode([
    new \stdClass,
    new class{},
    (object)[],
]);

?>

Resultados:

[{},{},{}]

https://www.php.net/manual/en/language.types.object.php

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top