7
votes

Les objets PHP peuvent-ils être construits et leurs variables définies en une seule opération?

dans Perl, je suis habitué à faire

my $foo = new WhatEver();
$foo->{bar} = 'baz';


4 commentaires

Être un gars Perl moi-même je suis intéressé par cela aussi. Perl ftw.


Voulez-vous dire "objets php" comme dans un stdclass ? Parce que si c'est un constructeur, vous pouvez le faire dans __ construire et transmettre les variables sur l'instanciation exacte?


Donc, pour le perl-inconnu, vous demandez s'il est possible de définir arbitrairement les propriétés d'un objet en passant dans le constructeur? Ce n'est pas - vous devez définir le __ construction () pour accepter les paramètres et les définir manuellement ou la boucle sur un tableau transmis au constructeur pour les définir de manière dynamique.


php.net/manual/fr/language.oop5.php


4 Réponses :


3
votes

Vous pouvez définir votre constructeur comme suit:

 class MyClass {
     public function __construct($obj=null) {
         if ($obj && $obj instanceof Traversable || is_array($obj)) {
             foreach ($obj as $k => $v) {
                if (property_exists($this,$k)) {
                    $this->{$k} = $v;
                }
             }
         }
     }
 }
  • Ceci est inefficace li>
  • Les variables que vous créez ne figureront pas sur aucun logiciel DOC que vous utilisez LI>
  • C'est la porte ouverte à toutes les formes de fabères li> ul>

    Cependant, il présente également les avantages suivants: P>

    • Ceci peut être étendu assez en toute sécurité li>
    • Il vous permet d'utiliser des variables de mise en œuvre paresseux li>
    • Il vous permet également de définir des variables privées, à condition que vous connaissiez leurs noms. C'est plutôt bien à cet égard s'il n'est pas maltraité. Li> ul> p>


8 commentaires

J'ai oublié de mentionner - tout ce qui peut courir dans un foreach peut être transmis en tant que premier argument de ce constructeur.


Tout en dehors d'un tableau normal, ce qui serait le choix évident ici puisque nous recherchons une initialisation concise.


Merci. J'avais totalement oublié la méthode __Construction (). Et bien sûr, les objets PERL ont généralement une nouvelle méthode () la fait aussi, ce n'est pas magique.


Une extension à ceci serait de vérifier Property_exists ($ K, $ ceci) de sorte que seules les propriétés réellement définies dans la classe ont été attribuées.


@Imsop: J'ai gardé l'exemple au minimum. Néanmoins, ajouté ... (aussi, le vôtre a inversé les paramètres. Essayer de me tester? ;-))


@ Sébastienrenrenauld Oh, dérangez, je reçois toujours ces mal - j'ai même apporté la page manuelle et l'ignora d'une manière ou d'une autre! Et oui, certainement facultatif, mais alors soutenir des objets démocratants ainsi que des tableaux (et rejeter explicitement les celles-qui non propres ...)


En fait, désolé de voler, mais ne devrait-il pas être d'instance de parcours pas instanceof arayaccess ? ArrayAccess est destiné à utiliser [] accès élément.


@Imsop: Vous avez raison, bien que des gens implémentent traversable , ils implémentent également arrayaccess . Corriger quand même!



1
votes

Les paramètres passés dans les parenthèses (qui peuvent être omis, au moyen, s'il n'y en a pas), allez à la méthode du constructeur où vous pouvez faire ce que vous voulez avec eux. Si une classe est définie, par exemple, comme ceci:

$foo = new WhatEver('baz');


0 commentaires

1
votes

Il y a quelques façons d'accomplir cela, mais chacun a ses propres inconvénients.

Si vos seigesteurs renvoient une instance de l'objet lui-même, vous pouvez chaîner vos méthodes. P>

my $foo = new WhatEver($bar1, $bar2, $bar3);


5 commentaires

Vous ne pouvez donc le faire avec un tableau indexé et passer par ordre? Et vous pouvez passer dans un tableau associatif, mais cela n'attribuera pas automatiquement des valeurs clés aux noms de variables de votre objet, vous devez l'introduire?


Oui, vous auriez besoin d'itérer. Mais vous avez également la possibilité d'utiliser des méthodes magiques dans PHP5. PHP.net/manual/fr/Language.oop5. surcharge.php # objet.set


@Chrishendry: Si vous pouvez éviter les méthodes magiques, je vous recommande vivement de le faire. Garfieldtech.com/blog/benchmarking-magic a un tas de bonnes choses à ce sujet .


@ Sébastien: intéressant. Je n'aurais pas attendu un tel succès de performance, mais cela a du sens. Merci.


@Chrishendry: Les méthodes magiques ne sont pas simplement mauvaises sur la performance. Ils encouragent également la faute professionnelle (avez-vous déjà hérité d'une classe PHP non documentée qui attribuait des variables de manière dynamique sans déclaration? Absolument. Impossible. Sans lire la classe complète de savoir quoi que ce soit) et de quelques formes de façonneuses (elles sont principalement utilisées par des personnes pour supprimer les avis de variables non déclarés). Decezze et j'avais un peu de discussion sur une autre question au retour - il n'y a que deux méthodes magiques qui ne peuvent être remplacées par de bonnes normes de codage (__wakeup, __invoke).



1
votes

L'hypothèse implicite ici est que les objets ont significatif, probablement public, propriétés qu'il appartient au code d'appel de fournir des valeurs. Ceci n'est en aucun cas une donnée - un aspect clé de l'OOP est l'encapsulation em>, de sorte qu'un accès principal d'un objet est via ses méthodes.

Le mécanisme "correct" pour l'initialisation de l'état d'un objet est son constructeur. , pas une série de missions de propriété. Quels sont les arguments que le constructeur est jusqu'à la définition de la classe. P>

MAINTENANT, un constructeur peut avoir une longue série de paramètres nommés, de sorte que vous puissiez écrire $ foo = neuf autre quoi que ce soit (1, "Bonjour ", FALSE, NULL) CODE> Mais si vous voulez que cela agisse comme des options, il pourrait s'agir d'un seul hachage - en termes de PHP, un tableau - comme argument. p>

Alors, pour répondre La question, oui, si votre constructeur est de la forme Fonction __Construction (options $ $) code>, puis vérifie ou vérifie dans $ options code>. Mais c'est au constructeur que faire avec ces options; par exemple, passe ['user_safe_options' => true] code> peut déclencher un ensemble complet de variables privées à définir sur les valeurs "sûres" documentées " p>

à partir de PHP 5.4 (qui introduit [...] code> comme alternative à tableau (...) code>), il ne faut que quelques coups de caractère supplémentaires que la version Perl: P>

$foo = new WhatEver( ['bar' => 'baz'] );


0 commentaires