Anonyme Objekte in PHP erstellen

141

Wie wir wissen, ist das Erstellen anonymer Objekte in JavaScript wie im folgenden Code einfach:

var object = { 
    p : "value", 
    p1 : [ "john", "johnny" ]
};

alert(object.p1[1]);

Ausgabe:

an alert is raised with value "johnny"

Kann dieselbe Technik in PHP angewendet werden? Können wir anonyme Objekte in PHP erstellen?

Sujit Agarwal
quelle
1
Hinweis: Dies ist eine alte Frage, daher ist die akzeptierte Antwort veraltet. Diese angeforderte Funktion wurde jetzt zu PHP 7 hinzugefügt. Siehe die Antwort unten von @ Rizier123.
Simba
@ Simba - Danke, dass du darauf hingewiesen hast. Möchten Sie hier auf dieser Seite eine Antwort auf StackOverflow veröffentlichen, um zukünftigen Besuchern zu helfen?
Sujit Agarwal
1
Ich muss nicht; Es gibt bereits eine Antwort mit dieser Information (siehe unten, von @ Rizier123).
Simba

Antworten:

40

Es ist einige Jahre her, aber ich denke, ich muss die Informationen auf dem neuesten Stand halten!

Seit PHP 7 ist es möglich, anonyme Klassen zu erstellen, sodass Sie folgende Aktionen ausführen können:

<?php

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

    var_dump($child instanceof Foo); // true

?>

Weitere Informationen hierzu finden Sie im Handbuch

Ich weiß jedoch nicht, wie ähnlich es JavaScript implementiert ist, daher kann es einige Unterschiede zwischen anonymen Klassen in JavaScript und PHP geben.

Rizier123
quelle
@risyasin Danke, habe die Antwort aktualisiert und den manuellen Link eingefügt.
Rizier123
Markieren Sie Ihre Antwort als richtig, um mit den neuesten Änderungen in PHP7 Schritt zu halten. Danke @ Rizier123
Sujit Agarwal
3
Dies ist interessant, geht aber nicht wirklich auf die Frage ein, da das OP nach einer bequemen Möglichkeit fragte, ein Objekt mit verschiedenen Mitgliedern zu initialisieren, ohne eine Klasse zu erstellen. Ich bin mir nicht sicher, ob anonyme Klassen in PHP dazu verwendet werden können, und wenn dies möglich ist, haben Sie nicht erklärt, wie.
Amh15
228

"Anonym" ist nicht die richtige Terminologie, wenn es um Objekte geht. Es wäre besser zu sagen "Objekt vom anonymen Typ " , aber dies gilt nicht für PHP.

Alle Objekte in PHP haben eine Klasse. Die "Standard" -Klasse ist stdClass, und Sie können Objekte davon auf folgende Weise erstellen:

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

Sie können auch ein Array in ein Objekt umwandeln, um eine bequemere Syntax zu erhalten:

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

Beachten Sie jedoch, dass das Umwandeln eines Arrays in ein Objekt wahrscheinlich "interessante" Ergebnisse für Array-Schlüssel liefert, die keine gültigen PHP-Variablennamen sind. Hier ist beispielsweise eine Antwort von mir, die zeigt, was passiert, wenn Schlüssel mit Ziffern beginnen.

Jon
quelle
1
Kann ich auch ein Array mit mehreren Werten pushen?
Sujit Agarwal
2
@CodingFreak: Sie können, aber : Wenn das Array Unterarrays enthält und Sie diese auch als Objekte möchten, müssen Sie jedes Objekt explizit in ein Objekt umwandeln.
Jon
21

Ja, es ist möglich! Verwenden dieser einfachen PHP Anonymous Object- Klasse. Wie es funktioniert:

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

Natürlich ist dieses Objekt eine Instanz der AnObjKlasse, daher ist es nicht wirklich anonym, aber es ermöglicht es, Methoden im laufenden Betrieb zu definieren, wie dies bei JavaScript der Fall ist.

Mihailoff
quelle
Mit create_function können Sie anonyme Funktionen emulieren.
Mihailoff
Ich denke, er wollte nur eine nette Möglichkeit, ein stdClass-Objekt mit einigen Werten zu initialisieren. Können Sie das mit Ihrem Ansatz tun?
Amh15
18

Bis vor kurzem habe ich auf diese Weise Objekte im laufenden Betrieb erstellt.

$someObj = json_decode("{}");

Dann:

$someObj->someProperty = someValue;

Aber jetzt gehe ich mit:

$someObj = (object)[];

Dann wie vorher:

$someObj->someProperty = someValue;

Wenn Sie die Eigenschaften und Werte bereits kennen, können Sie sie natürlich wie erwähnt festlegen:

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

NB: Ich weiß nicht, auf welchen PHP-Versionen dies funktioniert, daher müssen Sie sich dessen bewusst sein. Ich denke jedoch, dass der erste Ansatz (der auch kurz ist, wenn beim Erstellen keine Eigenschaften festgelegt werden müssen) für alle Versionen mit json_encode / json_decode funktionieren sollte

Zuks
quelle
1
Wie unterscheidet sich das von $ someObj = new \ stdClass ()?
JamesNZ
9

Array in Objekt konvertieren (dies ist jedoch für Unterkinder nicht rekursiv):

$obj = (object)  ['myProp' => 'myVal'];
T.Todua
quelle
7

Wenn Sie JavaScript imitieren möchten, können Sie eine Klasse erstellen Objectund erhalten so das gleiche Verhalten. Natürlich ist das nicht mehr ganz anonym, aber es wird funktionieren.

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

Das wird Element 2 ausgeben . Dies wurde aus einem Kommentar zu PHP gestohlen : Klassen und Objekte .

kba
quelle
3

Die Unterstützung für anonyme Klassen ist seit PHP 7.0 verfügbar und entspricht am ehesten dem in der Frage angegebenen JavaScript-Beispiel.

<?php
$object = new class {
    var $p = "value";
    var $p1 = ["john", "johnny"];
};

echo $object->p1[1];

Die Sichtbarkeitserklärung für Eigenschaften kann nicht weggelassen werden (ich habe sie nur verwendet, varweil sie kürzer als ist public.)

Wie bei JavaScript können Sie auch Methoden für die Klasse definieren:

<?php
$object = new class {
    var $p = "value";
    var $p1 = ["john", "johnny"];
    function foo() {return $this->p;}
};

echo $object->foo();
miken32
quelle
1

Aus der PHP-Dokumentation einige weitere Beispiele:

<?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 und $ obj3 sind vom gleichen Typ, aber $ obj1! == $ obj3. Außerdem werden alle drei json_encode () für ein einfaches JS-Objekt {} verwenden:

<?php

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

?>

Ausgänge:

[{},{},{}]

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

Ivan Ivković
quelle
0

Wenn Sie ein Objekt (wie in Javascript) mit dynamischen Eigenschaften erstellen möchten, ohne eine Warnung vor undefinierten Eigenschaften zu erhalten, wenn Sie keinen Wert für property festgelegt haben

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
Fredtma
quelle
0

Kann dieselbe Technik bei PHP angewendet werden?

Nein - da Javascript Prototypen / direkte Deklaration von Objekten verwendet - kann in PHP (und vielen anderen OO-Sprachen) ein Objekt nur aus einer Klasse erstellt werden.

Die Frage lautet also: Können Sie eine anonyme Klasse erstellen?

Wieder lautet die Antwort nein - wie würden Sie die Klasse instanziieren, ohne darauf verweisen zu können?

Symcbean
quelle
Sie benötigen keinen Namen, um eine Instanz einer anonymen Klasse zu erstellen. Java: Object var = new Object() { ... };- C ++:class { ... } var;
TheOperator
1
Sie können jetzt anonyme Klassen in PHP erstellen.
Victor
0

Für jemanden, der ein rekursives Objekt will:

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

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

Anoynmus-Objekt- Wiki


$object=new class (){


};
dılo sürücü
quelle