Question

Comme nous le savons, la création d'objets anonymes en JavaScript est facile, comme le code ci-dessous:

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

Production:

an alert is raised with value "johnny"

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

Était-ce utile?

La solution

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 cours anonymes, vous pouvez donc 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 la RFC (il est accepté): https://wiki.php.net/rfc/anonymous_classes

Mais je ne sais pas à quel point il est implémenté à Javscript, donc il peut s'agir de quelques différences entre les classes anonymes en JavaScript et PHP.

Éditer:

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

Autres conseils

"Anonyme" n'est pas la terminologie correcte lorsque l'on parle d'objets. Il serait préférable de dire "Objet d'Anonyme taper", mais cela ne s'applique pas à PHP.

Tous les objets de PHP ont une classe. La classe "par défaut" 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 Casser un tableau à un objet Pour une syntaxe plus pratique:

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

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

Oui c'est possible! En utilisant ce simple Objet anonyme PHP classer. Comment ça fonctionne:

// 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 AnObj classe, donc ce n'est pas vraiment anonyme, mais il permet de définir des méthodes à la volée, comme JavaScript.

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

$someObj = json_decode("{}");

Alors:

$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 quelle versions de PHP cela fonctionne, vous devez donc en être conscient. 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 donc obtenir 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];
?>

Qui sortira élément 2. Cela a été volé à Un commentaire sur PHP: classes et objets.

Convertir le tableau en objet:

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

Si vous souhaitez créer un objet (comme dans JavaScript) avec des propriétés dynamiques, sans recevoir un avertissement de propriété non définie, lorsque vous n'avez pas réglé de valeur sur 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

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

Non - Parce que JavaScript utilise des prototypes / déclaration directe des objets - en php (et de nombreuses autres langues OO), un objet ne peut être créé qu'à partir d'une classe.

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

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

Pour celui qui veut un objet récursif:

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

echo $o->foo->sub;

À partir de la documentation PHP, quelques exemples supplémentaires:

<?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 et $ obj3 sont le même type, mais $ obj1! == $ Obj3. De plus, les trois seront json_encode () à un objet JS simple {}:

<?php

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

?>

Les sorties:

[{},{},{}]

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top