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 dans le cas de PHP? Pouvons-nous créer des objets anonymes en PHP?

114
demandé sur Rizier123 2011-06-17 14:28:01

9 réponses

Cela fait quelques années, mais je pense que je dois garder l'information à jour!



en php-7 Il est possible de créer des classes anonymes, donc vous pouvez faire des choses comme ceci:

<?php

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

    var_dump($child instanceof Foo); // true

?>

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

mais je ne sais pas si c'est similaire implémenté en Javscript, il peut donc y avoir quelques différences entre les classes anonymous en javascript et php.

Edit:

à partir des commentaires affichés, voici le lien vers le manuel maintenant: http://php.net/manual/en/language.oop5.anonymous.php

29
répondu Rizier123 2015-12-19 00:54:31

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

tous les objets en PHP ont une classe. La classe "default" est stdClass , et vous pouvez en créer des objets de cette façon:

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

vous pouvez également profiter de lancer un tableau à un objet pour une syntaxe plus commode:

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

cependant, sachez que le casting d'un tableau à un objet est susceptible de donner des résultats "intéressants" pour les clés de tableau qui ne sont pas des noms de variables PHP valides -- par exemple, voici une de mes réponses qui montre ce qui se passe lorsque les clés commencent avec des chiffres.

206
répondu Jon 2017-05-23 12:34:23

Oui, c'est possible! En utilisant cette simple classe PHP Anonymous Object . 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 , donc il n'est pas vraiment anonyme, mais il permet de définir des méthodes à la volée, comme le fait JavaScript.

19
répondu Mihailoff 2012-09-12 15:24:23

jusqu'à récemment, c'est comment j'ai créé des objets à la volée.

$someObj = json_decode("{}");

puis:

$someObj->someProperty = someValue;

mais maintenant je vais avec:

$someObj = (object)[];

puis 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 donc vous devriez besoin d'être conscient de cela. Mais je pense que la première approche (qui est également 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
répondu Zuks 2017-05-03 11:40:52

si vous souhaitez imiter JavaScript, vous pouvez créer une classe Object , et ainsi obtenir le même comportement. Bien sûr, ce n'est pas tout à fait anonyme, mais il fonctionne.

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

qui produira élément 2 . Cela a été volé dans un commentaire sur PHP: Classes et Objets .

7
répondu kba 2011-06-17 10:43:31

Raccourci:

$obj = (object)      ['property' => 'Here we go'];
                 //or//
$obj = (object) array('property' => 'Here we go');
5
répondu T.Todua 2018-07-07 09:46:51

cette même technique peut-elle être appliquée dans le cas de PHP?

non - parce que javascript utilise des prototypes / déclaration directe d'objets - en PHP (et beaucoup d'autres langues OO) un objet ne peut être créé qu'à partir d'une classe.

ainsi la question devient - pouvez-vous créer une classe anonyme.

encore une fois la réponse est non - comment instancier la classe sans pouvoir s'y référer?

1
répondu symcbean 2017-01-27 12:07:36

si vous voulez créer un objet (comme dans javascript) avec des propriétés dynamiques, sans recevoir un avertissement de propriété non définie, quand vous n'avez pas défini de valeur à la 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
répondu fredtma 2015-11-26 15:05:12

pour celui qui veut un objet récursif:

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

echo $o->foo->sub;
0
répondu Jonatas Walker 2018-06-05 12:42:56