Comment définir un objet vide en PHP


384

avec un nouveau tableau, je fais ceci:

$aVal = array();

$aVal[key1][var1] = "something";
$aVal[key1][var2] = "something else";

Existe-t-il une syntaxe similaire pour un objet

(object)$oVal = "";

$oVal->key1->var1 = "something";
$oVal->key1->var2 = "something else";

13
$var = (object) (boolean) (string) (int) (array) new StdClass; Vous savez, juste pour être en sécurité.
Xeoncross

1
Google a indexé ce titre de question: Arrays - How to define an empty object in PHP. N'a rien à voir avec les tableaux
Kolob Canyon

Réponses:


848
$x = new stdClass();

Un commentaire dans le manuel le résume le mieux:

stdClass est l'objet PHP par défaut. stdClass n'a pas de propriétés, de méthodes ou de parent. Il ne prend pas en charge les méthodes magiques et n'implémente aucune interface.

Lorsque vous convertissez un scalaire ou un tableau en objet, vous obtenez une instance de stdClass. Vous pouvez utiliser stdClass chaque fois que vous avez besoin d'une instance d'objet générique.


5
$ o = (objet) NULL; - Si un objet est converti en objet, il n'est pas modifié. Si une valeur de tout autre type est convertie en objet, une nouvelle instance de la classe intégrée stdClass est créée. Si la valeur était NULL, la nouvelle instance sera vide. Les tableaux sont convertis en un objet avec des propriétés nommées par des clés et des valeurs correspondantes. Pour toute autre valeur, une variable membre nommée scalaire contiendra la valeur.
DDS

11
Je dis juste stdClassdans ma tête comme "classe standard"
sjagr

1
Si vous oubliez toujours d'utiliser ma réponse :)
RafaSashi

26
Si vous rencontrez "introuvable": new \stdClass(); PHP Namespace Doc
2540625

3
@IvanCastellanos pourriez-vous expliquer comment vous vous souvenez stdClass()du mot AIDS?
Adam

117

La manière standard de créer un objet "vide" est:

$oVal = new stdClass();

Mais, avec PHP> = 5.4, je préfère personnellement utiliser:

$oVal = (object)[];

Il est plus court et je le considère personnellement plus clair car stdClass pourrait être trompeur pour les programmeurs débutants (c'est-à-dire "Hé, je veux un objet, pas une classe!" ...).

La même chose avec PHP <5.4 est:

$oVal = (object) array();

(object)[]est équivalent à new stdClass().

Voir le manuel PHP ( ici ):

stdClass : créé par transtypage en objet.

et ( ici ):

Si un objet est converti en objet, il n'est pas modifié. Si une valeur de tout autre type est convertie en objet, une nouvelle instance de la classe intégrée stdClass est créée .


Cependant, rappelez-vous que vide ($ oVal) retourne faux , comme @PaulP l'a dit:

Les objets sans propriétés ne sont plus considérés comme vides.

Concernant votre exemple, si vous écrivez:

$oVal = new stdClass();
$oVal->key1->var1 = "something"; // PHP creates  a Warning here
$oVal->key1->var2 = "something else";

PHP crée l'avertissement suivant, créant implicitement la propriété key1(un objet lui-même)

Avertissement: création d'un objet par défaut à partir d'une valeur vide

Cela pourrait être un problème si votre configuration (voir niveau de rapport d'erreurs ) affiche cet avertissement au navigateur. C'est un autre sujet entier, mais une approche rapide et sale pourrait être d'utiliser l' opérateur de contrôle d'erreur (@) pour ignorer l'avertissement:

$oVal = new stdClass();
@$oVal->key1->var1 = "something"; // the warning is ignored thanks to @
$oVal->key1->var2 = "something else";

3
Au lieu de résoudre le problème, vous en créez un nouveau. Le problème qui doit être résolu est que les gens devraient savoir ce qui se stdClasspasse.
Pacerier

2
J'ai écrit ce qui stdClassfait. J'ai utilisé stdClasssur le code qui répond à la question. Je suis désolé mais je ne crée pas de nouveau problème, c'était mon opinion personnelle (comme je l'ai écrit).
cgaldiolo

6
"préférence personnelle"! = "problème"
cgaldiolo

4
@Pacerier, je ne comprends pas votre entêtement. La question était «Comment définir un objet vide en PHP». Ma réponse est correcte et j'ai écrit pour utiliser "new stdClass ()". Le code que j'ai fourni à l'utilisateur 'ed209' est correct et j'ai utilisé "new stdClass ()". De plus, j'ai ajouté une opinion personnelle et j'ai utilisé un "personnellement" gras pour être clair que ce n'était pas la voie "standard" à suivre. À mon humble avis, un problème qui mérite tant de commentaires devrait au moins être une mauvaise réponse. Au lieu de cela, si vous considérez une opinion personnelle comme un problème, c'est peut - être un problème pour un partage constructif d'idées.
cgaldiolo

9
J'aime vraiment la sténographie(object) []
Rahil Wazir

35

Je tiens à souligner qu'en PHP, il n'y a rien de tel qu'un objet vide dans le sens:

$obj = new stdClass();
var_dump(empty($obj)); // bool(false)

mais bien sûr $ obj sera vide.

D'autre part, un tableau vide signifie vide dans les deux cas

$arr = array();
var_dump(empty($arr));

Citation de la fonction changelog vide

Les objets sans propriétés ne sont plus considérés comme vides.


Je n'ai pas pu trouver cette citation dans le journal des modifications pour vide.
powpow12

@ powpow12 Il était là . Il a été modifié en 5.0.0.
Stanley Umeanozie


14

J'aime à quel point il est facile de créer des objets de type anonyme en JavaScript:

//JavaScript
var myObj = {
    foo: "Foo value",
    bar: "Bar value"
};
console.log(myObj.foo); //Output: Foo value

J'essaie donc toujours d'écrire ce genre d'objets en PHP comme le fait javascript :

//PHP >= 5.4
$myObj = (object) [
    "foo" => "Foo value",
    "bar" => "Bar value"
];

//PHP < 5.4
$myObj = (object) array(
    "foo" => "Foo value",
    "bar" => "Bar value"
);

echo $myObj->foo; //Output: Foo value

Mais comme il s'agit essentiellement d'un tableau, vous ne pouvez pas faire des choses comme assigner des fonctions anonymes à une propriété comme js:

//JavaScript
var myObj = {
    foo: "Foo value",
    bar: function(greeting) {
        return greeting + " bar";
    }
};
console.log(myObj.bar("Hello")); //Output: Hello bar

//PHP >= 5.4
$myObj = (object) [
    "foo" => "Foo value",
    "bar" => function($greeting) {
        return $greeting . " bar";
    }
];
var_dump($myObj->bar("Hello")); //Throw 'undefined function' error
var_dump($myObj->bar); //Output: "object(Closure)"

Eh bien, vous pouvez le faire, mais l'OMI n'est pas pratique / propre:

$barFunc = $myObj->bar;
echo $barFunc("Hello"); //Output: Hello bar

En outre, en utilisant ce synthax, vous pouvez trouver des surprises amusantes , mais cela fonctionne très bien dans la plupart des cas.


1
Cela devrait être la réponse acceptée
Mike Aron

11

En plus de la réponse de zombat si vous continuez à oublier stdClass

   function object(){

        return new stdClass();

    }

Vous pouvez maintenant:

$str='';
$array=array();
$object=object();

J'adore cette technique, bien que la plupart des IDE ne mettent pas en évidence le terme "objet" comme une fonction qui pourrait être source de confusion pour d'autres programmeurs. Mais bon, ça marche pour moi!
Brixster

7

Vous pouvez utiliser new stdClass()(ce qui est recommandé):

$obj_a = new stdClass();
$obj_a->name = "John";
print_r($obj_a);

// outputs:
// stdClass Object ( [name] => John ) 

Ou vous pouvez convertir un tableau vide en un objet qui produit une nouvelle instance vide de la classe intégrée stdClass:

$obj_b = (object) [];
$obj_b->name = "John";
print_r($obj_b);

// outputs: 
// stdClass Object ( [name] => John )  

Ou vous pouvez convertir la nullvaleur en un objet qui produit une nouvelle instance vide de la classe intégrée stdClass:

$obj_c = (object) null;
$obj_c->name = "John";
print($obj_c);

// outputs:
// stdClass Object ( [name] => John ) 

5

pour accéder aux données dans une stdClass de la même manière que vous le faites avec un tableau associatif, utilisez simplement la syntaxe {$ var}.

$myObj = new stdClass;
$myObj->Prop1 = "Something";
$myObj->Prop2 = "Something else";

// then to acces it directly

echo $myObj->{'Prop1'};
echo $myObj->{'Prop2'};

// or what you may want

echo $myObj->{$myStringVar};

4

Comme d'autres l'ont souligné, vous pouvez utiliser stdClass. Cependant, je pense qu'il est plus propre sans le (), comme ceci:

$obj = new stdClass;

Cependant, sur la base de la question, il semble que ce que vous voulez vraiment, c'est pouvoir ajouter des propriétés à un objet à la volée. Vous n'avez pas besoin d'utiliser stdClass pour cela, bien que vous le puissiez. Vous pouvez vraiment utiliser n'importe quelle classe. Créez simplement une instance d'objet de n'importe quelle classe et commencez à définir les propriétés. J'aime créer ma propre classe dont le nom est simplement o avec quelques fonctionnalités étendues de base que j'aime utiliser dans ces cas et qui est agréable pour s'étendre à partir d'autres classes. Fondamentalement, c'est ma propre classe d'objets de base. J'aime aussi avoir une fonction simplement nommée o (). Ainsi:

class o {
  // some custom shared magic, constructor, properties, or methods here
}

function o() {
  return new o;
}

Si vous n'aimez pas avoir votre propre type d'objet de base, vous pouvez simplement demander à o () de renvoyer une nouvelle stdClass. Un avantage est que o est plus facile à retenir que stdClass et est plus court, que vous l'utilisiez comme nom de classe, nom de fonction ou les deux. Même si vous n'avez pas de code à l'intérieur de votre classe o, il est toujours plus facile à mémoriser que la stdClass maladroitement capitalisée et nommée (qui peut invoquer l'idée d'une `` classe de maladies sexuellement transmissibles ''). Si vous personnalisez la classe o, vous pourriez trouver une utilisation pour la fonction o () au lieu de la syntaxe du constructeur. Il s'agit d'une fonction normale qui renvoie une valeur, qui est moins limitée qu'un constructeur. Par exemple, un nom de fonction peut être transmis sous forme de chaîne à une fonction qui accepte un paramètre appelable. Une fonction prend également en charge le chaînage. Vous pouvez donc faire quelque chose comme:

C'est un bon début pour une "langue" de base sur laquelle construire d'autres couches linguistiques, la couche supérieure étant écrite en DSL internes complètes. C'est similaire au style de développement lisp, et PHP le supporte bien mieux que la plupart des gens ne le pensent. Je me rends compte que c'est un peu une tangente pour la question, mais la question touche à ce que je pense est la base pour utiliser pleinement la puissance de PHP.


2
@Pacerier, vous parlez de l'absence de parenthèses? ;) cis.upenn.edu/~matuszek/General/JavaSyntax/parentheses.html
still_dreaming_1

1
C'est une faute de frappe, ça devrait être une parenthèse.
Pacerier


4

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.

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

4

Vous pouvez également essayer de cette façon.

<?php
     $obj = json_decode("{}"); 
     var_dump($obj);
?>

Production:

object(stdClass)#1 (0) { }

4

Utilisez un objet générique et mappez-y des paires de valeurs clés.

$oVal = new stdClass();
$oVal->key = $value

Ou transformez un tableau en objet

$aVal = array( 'key'=>'value' );
$oVal = (object) $aVal;

3

Si vous ne voulez pas faire ça:

$myObj = new stdClass();
$myObj->key_1 = 'Hello';
$myObj->key_2 = 'Dolly';

Vous pouvez utiliser l'une des options suivantes:

PHP> = 5,4

$myObj = (object) [
    'key_1' => 'Hello',
    'key_3' => 'Dolly',
];

PHP <5,4

$myObj = (object) array(
    'key_1' => 'Hello',
    'key_3' => 'Dolly',
);

3

Voici un exemple avec l'itération:

<?php
$colors = (object)[];
$colors->red = "#F00";
$colors->slateblue = "#6A5ACD";
$colors->orange = "#FFA500";

foreach ($colors as $key => $value) : ?>
    <p style="background-color:<?= $value ?>">
        <?= $key ?> -> <?= $value ?>
    </p>
<?php endforeach; ?>

0

Vous avez cette technique mauvaise mais utile:

$var = json_decode(json_encode([]), FALSE);

0

stdClass est l'objet PHP par défaut. stdClass n'a pas de propriétés, de méthodes ou de parent. Il ne prend pas en charge les méthodes magiques et n'implémente aucune interface.

Lorsque vous convertissez un scalaire ou un tableau en objet, vous obtenez une instance de stdClass. Vous pouvez utiliser stdClass chaque fois que vous avez besoin d'une instance d'objet générique.

<?php
// ways of creating stdClass instances
$x = new stdClass;
$y = (object) null;        // same as above
$z = (object) 'a';         // creates property 'scalar' = 'a'
$a = (object) array('property1' => 1, 'property2' => 'b');
?>

stdClass n'est PAS une classe de base! Les classes PHP n'héritent pas automatiquement d'aucune classe. Toutes les classes sont autonomes, sauf si elles étendent explicitement une autre classe. PHP diffère de nombreux langages orientés objet à cet égard.

<?php
// CTest does not derive from stdClass
class CTest {
    public $property1;
}
$t = new CTest;
var_dump($t instanceof stdClass);            // false
var_dump(is_subclass_of($t, 'stdClass'));    // false
echo get_class($t) . "\n";                   // 'CTest'
echo get_parent_class($t) . "\n";            // false (no parent)
?>

Vous ne pouvez pas définir une classe nommée 'stdClass' dans votre code. Ce nom est déjà utilisé par le système. Vous pouvez définir une classe nommée 'Object'.

Vous pouvez définir une classe qui étend stdClass, mais vous n'en tirerez aucun avantage, car stdClass ne fait rien.

(testé sur PHP 5.2.8)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.