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?
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
"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.
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.
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
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 .
Raccourci:
$obj = (object) ['property' => 'Here we go'];
//or//
$obj = (object) array('property' => 'Here we go');
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?
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
pour celui qui veut un objet récursif:
$o = (object) array(
'foo' => (object) array(
'sub' => '...'
)
);
echo $o->foo->sub;