232 votes

Getter et Setter ?

Je ne suis pas un développeur PHP, donc je me demande si en PHP il est plus populaire d'utiliser des getter/setters explicites, dans un pur style OOP, avec des champs privés (comme je l'aime) :

class MyClass {
    private $firstField;
    private $secondField;

    public function getFirstField() {
        return $this->firstField;
    }
    public function setFirstField($x) {
        $this->firstField = $x;
    }
    public function getSecondField() {
        return $this->secondField;
    }
    public function setSecondField($x) {
        $this->secondField = $x;
    }
}

ou seulement des champs publics :

class MyClass {
    public $firstField;
    public $secondField;
}

Gracias

8 votes

Après avoir essayé quelques codes provenant des réponses, j'ai utilisé le code que vous utilisez dans la question. Quelle tristesse :-(

12 votes

PHPstorm... génère > getters et setters. == win

1 votes

@DevDonkey Pas du tout une victoire. Pour conserver des données structurées, utilisez plutôt des tableaux. @:Mark Ce n'est pas la raison d'être des objets. Les récupérateurs et les régleurs sont diaboliques : yegor256.com/2014/09/16/getters-and-setters-are-evil.html

255voto

Dave Points 2545

Vous pouvez utiliser méthodes magiques php __get y __set .

<?php
class MyClass {
  private $firstField;
  private $secondField;

  public function __get($property) {
    if (property_exists($this, $property)) {
      return $this->$property;
    }
  }

  public function __set($property, $value) {
    if (property_exists($this, $property)) {
      $this->$property = $value;
    }

    return $this;
  }
}
?>

0 votes

@Computerish : Non, c'est le formatage du SO qui a merdé. Je l'ai corrigé maintenant.

0 votes

Oh ok. Je l'ai même surligné pour vérifier s'il avait vraiment mis deux tirets bas :-)

0 votes

@BoltClock a compris ce qui s'est passé @Computerish. Et le lien que je fournis a un meilleur exemple pour __get et __set IMHO, c'est pourquoi je l'ai donné. Merci pour toutes les contributions.

123voto

Wiliam Points 1384

Pourquoi utiliser les getters et setters ?

  1. Évolutivité : Il est plus facile de refactoriser un getter que de rechercher toutes les assignations de var dans le code d'un projet.
  2. Débogage : Vous pouvez mettre des points d'arrêt aux setters et getters.
  3. Nettoyeur : Les fonctions magiques ne sont pas une bonne solution pour écrire moins, votre IDE ne suggérera pas le code. Il vaut mieux utiliser des templates pour écrire rapidement des getters.

direct assignment and getters/setters

7 votes

Si vous utilisez @property, votre IDE vous proposera le code suivant (testé avec PhpStorm 7)

0 votes

Les deux premiers points m'ont déjà convaincu. L'évolutivité et le débogage sont très importants ! Avec l'extensibilité au-delà du refactor, les getter et setter aident à la maintenance !

61voto

magallanes Points 1024

Google a déjà publié un guide sur l'optimisation de PHP et la conclusion était la suivante :

Pas de getter et setter Optimisation de PHP

Et non, vous devez ne pas utiliser de méthodes magiques . Pour PHP, les méthodes magiques sont mauvaises. Pourquoi ?

  1. Ils sont difficiles à déboguer.
  2. Il y a un impact négatif sur les performances.
  3. Ils nécessitent d'écrire plus de code.

PHP n'est pas Java, C++ ou C#. PHP est différent et joue avec différents rôles.

12 votes

J'ai tendance à être d'accord avec cette idée ; que $dog->name = 'fido' est meilleur que $dog->setName('fido') . Lors de la mutation effective d'une propriété (ex : $dog->increaseAge(1) Je peux élaborer la méthode qui effectue la validation nécessaire et mute cette propriété. Mais toutes les actions ne nécessitent pas vraiment une mutation dans ce sens.

17 votes

L'article n'a pas dites " Ne le fais pas. Il est dit "setters et getters naïfs".

2 votes

19voto

netcoder Points 31874

L'encapsulation est importante dans tout langage OO, la popularité n'a rien à voir avec cela. Dans les langages typés dynamiquement, comme PHP, elle est particulièrement utile car il y a peu de moyens de s'assurer qu'une propriété est d'un type spécifique sans utiliser des setters.

En PHP, cela fonctionne :

class Foo {
   public $bar; // should be an integer
}
$foo = new Foo;
$foo->bar = "string";

En Java, ce n'est pas le cas :

class Foo {
   public int bar;
}
Foo myFoo = new Foo();
myFoo.bar = "string"; // error

En utilisant des méthodes magiques ( __get y __set ) fonctionne également, mais uniquement lorsqu'il s'agit d'accéder à une propriété dont la visibilité est inférieure à celle à laquelle la portée actuelle peut accéder. Elle peut facilement vous donner des maux de tête lorsque vous essayez de déboguer, si elle n'est pas utilisée correctement.

7 votes

Getters et setter n'apportent pas d'encapsulation. Encapsulation == les objets font quelque chose avec leurs propres données au lieu de les donner à l'extérieur. Les récupérateurs et les régleurs ne sont pas un outil pour renforcer le type dans les langages typés dynamiquement comme PHP.

16 votes

@smentek : Vous manquez clairement au moins la moitié de ce qu'est réellement l'encapsulation.

4 votes

Comme mise à jour pour ceux qui cherchent, PHP 7.4 viendra avec le support des propriétés typées. Ainsi, vous pourrez déclarer $bar comme un int dans le premier exemple : wiki.php.net/rfc/typed_properties_v2

6voto

joas Points 76
class MyClass {
    private $firstField;
    private $secondField;
    private $thirdField;

    public function __get( $name ) {
        if( method_exists( $this , $method = ( 'get' . ucfirst( $name  ) ) ) )
            return $this->$method();
        else
            throw new Exception( 'Can\'t get property ' . $name );
    }

    public function __set( $name , $value ) {
        if( method_exists( $this , $method = ( 'set' . ucfirst( $name  ) ) ) )
            return $this->$method( $value );
        else
            throw new Exception( 'Can\'t set property ' . $name );
    }

    public function __isset( $name )
    {
        return method_exists( $this , 'get' . ucfirst( $name  ) ) 
            || method_exists( $this , 'set' . ucfirst( $name  ) );
    }

    public function getFirstField() {
        return $this->firstField;
    }

    protected function setFirstField($x) {
        $this->firstField = $x;
    }

    private function getSecondField() {
        return $this->secondField;
    }
}

$obj = new MyClass();

echo $obj->firstField; // works
$obj->firstField = 'value'; // works

echo $obj->getFirstField(); // works
$obj->setFirstField( 'value' ); // not works, method is protected

echo $obj->secondField; // works
echo $obj->getSecondField(); // not works, method is private

$obj->secondField = 'value'; // not works, setter not exists

echo $obj->thirdField; // not works, property not exists

isset( $obj->firstField ); // returns true
isset( $obj->secondField ); // returns true
isset( $obj->thirdField ); // returns false

Prêt !

1 votes

Trop de texte passe-partout. Imaginez que ce genre de choses se retrouve dans tous les cours. À éviter.

0 votes

PHP ne supporte pas les getters et setters pour les mêmes raisons que vous mentionnez. Toute implémentation de ce type affecte sévèrement les performances du script côté serveur.

0 votes

Je pense que cela va à l'encontre des propriétés "privées". On les encapsule, mais on permet aussi d'y accéder directement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X