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