web-dev-qa-db-fra.com

Création d'objets anonymes en php

Comme nous le savons, créer des objets anonymes en JavaScript est facile, comme le code ci-dessous:

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

Sortie:

an alert is raised with value "johnny"

Cette même technique peut-elle être appliquée en cas de PHP? Peut-on créer des objets anonymes en PHP?

120
Sujit Agarwal

Cela fait quelques années, mais je pense que je dois garder les informations à jour!


Dans php-7, il est possible de créer des classes anonymes, vous pouvez donc faire les choses suivantes:

<?php

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

    var_dump($child instanceof Foo); // true

?>

Vous pouvez en savoir plus à ce sujet dans le RFC (c'est accepté): https://wiki.php.net/rfc/anonymous_classes

Mais je ne sais pas à quel point il est similaire à Javscript, donc quelques différences peuvent exister entre les classes anonymes en javascript et php.

Modifier:

À partir des commentaires postés, voici le lien au manuel: http://php.net/manual/fr/language.oop5.anonymous.php

31
Rizier123

"Anonyme" n'est pas la bonne terminologie quand on parle d'objets. Il serait préférable de dire "objet de type anonyme", mais cela ne s'applique pas à PHP.

Tous les objets dans PHP ont une classe. La classe "par défaut" est stdClass , et vous pouvez créer des objets de cette façon:

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

Vous pouvez également tirer parti de transtyper un tableau en objet pour une syntaxe plus pratique:

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

Toutefois, sachez que le fait de transformer un tableau en objet génère des résultats "intéressants" pour les clés de tableau qui ne sont pas des noms de variable valides PHP - par exemple, voici une de mes réponses qui montre Que se passe-t-il lorsque les clés commencent par des chiffres?.

214
Jon

Oui c'est possible! En utilisant ce simple PHP Anonymous Object class. Comment ça marche:

// 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"

Bien sûr, cet objet est une instance de la classe AnObj, il n'est donc pas vraiment anonyme, mais il permet de définir des méthodes à la volée, comme le fait JavaScript.

19
Mihailoff

Jusqu'à récemment, c'est ainsi que j'ai créé des objets à la volée.

$someObj = json_decode("{}");

Ensuite:

$someObj->someProperty = someValue;

Mais maintenant je vais avec:

$someObj = (object)[];

Alors comme avant:

$someObj->someProperty = someValue;

Bien sûr, si vous connaissez déjà les propriétés et les valeurs, vous pouvez les définir à l'intérieur comme cela a été mentionné:

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

NB: Je ne sais pas sur quelles versions de PHP cela fonctionne, vous devez donc en être conscient. Mais je pense que la première approche (qui est aussi courte s'il n'y a pas de propriétés à définir à la construction) devrait fonctionner pour toutes les versions qui ont json_encode/json_decode

13
Zuks

Si vous souhaitez imiter JavaScript, vous pouvez créer une classe Object et obtenir ainsi le même comportement. Bien sûr, ce n’est plus tout à fait anonyme, mais cela fonctionnera.

<?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];
?>

Cela produira élément 2. Cela a été volé à un commentaire sur PHP: Classes and Objects .

7
kba

Sténographie:

$obj = (object)      ['property' => 'Here we go'];
                 //or//
$obj = (object) array('property' => 'Here we go');
5
T.Todua

Si vous souhaitez créer un objet (comme en javascript) avec des propriétés dynamiques, sans recevoir d'avertissement de propriété non définie, lorsque vous n'avez pas défini de valeur pour propriété 

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
0
fredtma

Pour celui qui veut un objet récursif:

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

echo $o->foo->sub;
0
Jonatas Walker

Cette même technique peut-elle être appliquée en cas de PHP?

Non - car javascript utilise des prototypes/déclarations directes d'objets - en PHP (et dans de nombreux autres langages OO), un objet ne peut être créé qu'à partir d'une classe.

La question devient alors - pouvez-vous créer une classe anonyme?.

Encore une fois, la réponse est non - comment voulez-vous instancier la classe sans pouvoir la référencer?

0
symcbean