2009-12-17 6 views
0

Je ne sais pas si cela est une question triviale, mais dans une classe PHP:créant Dynamiquement variables d'instance dans les classes PHP

MyClass:

class MyClass { 
    public $var1; 
    public $var2; 

    constructor() { ... } 

    public method1() { 

    // Dynamically create an instance variable 
     $this->var3 = "test"; // Public....? 


    } 
} 

principales:

$test = new MyClass(); 
$test->method1(); 
echo $test->var3; // Would return "test" 

Est-ce que cela fonctionne? Comment ferais-je fonctionner ça? Ps. J'ai écrit ceci rapidement donc s'il vous plaît ne tenez pas compte des erreurs que j'ai faites avec la mise en place de la classe ou des méthodes d'appel!

EDIT Que diriez-vous de faire ces variables d'instance que je crée privé ??

EDIT 2 Merci à tous pour répondre - Tout le monde a raison - je viens testé moi-même, mais j'ai eu un examen le lendemain matin et avait cette pensée tout en étudiant que je voulais vérifier si travaillé. Les gens continuent à suggérer que sa mauvaise POO - peut-être mais cela permet un code élégant. Laissez-moi vous expliquer un peu et voir si vous le pensez encore. Voici ce que je suis venu avec:

//PHP User Model: 

class User { 
    constructor() { ... } 

    public static find($uid) { 
     $db->connect(); // Connect to the database 

     $sql = "SELECT STATEMENT ...WHERE id=$uid LIMIT 1;"; 
     $result = $db->query($sql); // Returns an associative array 

     $user = new User(); 

     foreach ($result as $key=>$value) 
      $user->$$key = $value; //Creates a public variable of the key and sets it to value 

     $db->disconnect(); 
    } 
} 

//PHP Controller: 

function findUser($id) { 

    $User = User::find($id); 

    echo $User->name; 
    echo $User->phone; 
    //etc... 

} 

je aurais pu le mettre dans un tableau associatif mais je ne peux nommer jamais correctement ce tableau quelque chose de significatif (par exemple $ user-> data [ « nom »] .... laid.) De toute façon, vous devez savoir ce qui est dans la base de données, donc je ne comprends pas vraiment ce que l'argument est que c'est confus, d'autant plus que vous pouvez var var des objets pour le débogage.

+0

duplication possible de [Pouvez-vous créer dynamiquement des propriétés d'instance en PHP?] (Http://stackoverflow.com/questions/829823/can-you-create-instance-properties-dynamically-in-php) – outis

Répondre

5

Oui cela fonctionnera en effet. Les variables d'instance créées automatiquement bénéficient d'une visibilité publique.

+5

Great! Qu'en est-il de les rendre privés alors ... est-ce possible? – Matt

2

oui cela fonctionne comme vous l'espériez.

+1

Savez-vous comment je rendrais la variable privée? – Matt

+0

Vous ne pouvez pas faire cela. Et je ne vois pas pourquoi voudriez-vous le faire. Une bonne pratique consiste à déclarer toutes les variables que vous utilisez, de toute façon. –

6

Pourquoi vous n'écrivez simplement le code et voyez par vous-même?

<?php 
class Foo 
{ 
    public function __construct() 
    { 
     $this->bar = 'baz'; 
    } 
} 

$foo = new Foo; 
echo $foo->bar; // outputs 'baz' 

et

var_dump($foo); 

donne

object(Foo)#1 (1) { 
    ["bar"] => string(3) "baz" 
} 

mais

$r = new ReflectionObject($foo); 
$p = $r->getProperty('bar'); 
var_dump($p->isPublic()); 

lancera une exception sur 'bar' étant inconnu, alors que

$r = new ReflectionObject($foo); 
$p = $r->getProperties(); 
var_dump($p[0]->isPublic()); 

retournera vrai.

Maintenant, devriez-vous faire ce type d'affectation? La réponse est non. Ce n'est pas une bonne conception de POO. Rappelez-vous, la POO concerne l'encapsulation. Donc, si bar décrit une propriété publique de la classe, rendez-la explicite et déclarez-la dans votre classe en tant que public $bar. S'il est supposé être privé déclarez-le comme private $bar. Mieux encore, n'utilisez pas du tout les propriétés publiques et faites-les protected et ne leur donne accès qu'à travers des getters et setters. Cela rendra l'interface beaucoup plus claire et plus propre car elle transmet ce que l'interaction est supposée être possible avec une instance d'objet.

Affecter des propriétés à la volée ici et là sur votre code rendra le maintien de votre code un cauchemar. Imaginez quelque part le long de la lifecylce de quelqu'un Foo fait ceci:

$foo = new Foo; 
$foo->monkey = 'ugh'; 

echo $foo->monkey; // outputs 'ugh' 

maintenant, de regarder la définition de classe ci-dessus, il n'y a absolument aucun moyen, un développeur peut voir il y a maintenant un singe patché dans Foo. Cela rendra le débogage pénible, surtout si ce type de code est fréquent et distribué sur plusieurs fichiers.

2

Je vous vouliez faire des variables privées à la volée, vous pouvez utiliser les fonctions magiques php pour imiter ce, par exemple

MyClass

<?php 
class MyClass { 
    public $var1; 
    public $var2; 
    private $data = array(); 

    public function __get($key) { 
     // for clarity you could throw an exception if isset($this->data[$key]) 
     // returns false as it is entirely possible for null to be a valid return value 
     return isset($this->data[$key]) ? return $this->data[$key] : null; 
    } 

    public function __set($key, $value) { 
     $this->data[$key] = $value; 
    } 
} 
?> 

principales

<?php 
$test = new MyClass(); 
$test->myVar = 'myVar is technically private, i suppose'; 
echo $this->myVar; // 'myVar is technically private 
?> 

Bien que ces variables créées dynamiquement sont techniquement privées, elles sont en fait publiques accessible ... je ne peux pas imaginer le but de vouloir créer dynamiquement des variables d'instance privées. Je voudrais remettre en question votre conception.

+0

Si vous voulez seulement que la classe y ait accès. Voir ma révision ci-dessus. Si je voulais le numéro de carte de crédit de quelqu'un - peut-être que la base de données pourrait le récupérer - mais je devrais appeler getCreditCard() pour obtenir une version cryptée de celui-ci par exemple ... – Matt

Questions connexes