Quel est le problème avec un soulignement de premier plan dans les méthodes de classe PHP?

155

En examinant diverses bibliothèques PHP, j'ai remarqué que beaucoup de gens choisissent de préfixer certaines méthodes de classe avec un seul trait de soulignement, tel que

public function _foo()

...au lieu de...

public function foo()

Je me rends compte qu'en fin de compte, cela revient à une préférence personnelle, mais je me demandais si quelqu'un avait un aperçu de l'origine de cette habitude.

Ma pensée est qu'elle est probablement reportée de PHP 4, avant que les méthodes de classe ne puissent être marquées comme protégées ou privées, comme une manière d'impliquer "n'appelez pas cette méthode de l'extérieur de la classe". Cependant, il m'est également venu à l'esprit que peut-être que cela provient de quelque part (une langue) que je ne connais pas ou qu'il peut y avoir un bon raisonnement derrière cela que je gagnerais à connaître.

Toutes les pensées, idées et / ou opinions seraient appréciées.

pas d'argent
la source
9
Mise à jour 2014: sa syntaxe est officiellement obsolète: github.com/php-fig/fig-standards/blob/master/accepted
...

Réponses:

155

C'est du mauvais vieux temps de PHP orienté objet (PHP 4). Cette implémentation d'OO était assez mauvaise et n'incluait pas des choses comme les méthodes privées. Pour compenser, les développeurs PHP ont précédé les méthodes qui étaient censées être privées d'un trait de soulignement. Dans certaines classes plus anciennes, vous verrez /**private*/ __foo() {pour lui donner un poids supplémentaire.

Je n'ai jamais entendu parler de développeurs faisant précéder toutes leurs méthodes de traits de soulignement, je ne peux donc pas commencer à expliquer ce qui cause cela.

Jeremy DeGroot
la source
12
Je place un trait de soulignement avant les méthodes de mes contrôleurs qui sont privées pour la classe et inutilisées dans le routage. Étant donné que je travaille avec mon propre cadre, cela ajoute de la sécurité car j'applique la politique de non-soulignement principal sur les noms de contrôleur dans les routes. Mais cela dépasse rarement 1-2 méthodes par contrôleur.
Robert K
6
Par convention, avec perl, les méthodes commençant par un trait de soulignement sont privées. Mais ce n'est qu'une convention. En fait, ces méthodes sont toujours accessibles depuis l'extérieur de la classe.
Luc M
Les soulignements ont encore moins de sens si une classe étendue décide de rendre publique la méthode protégée de son parent. C'est un cas extrême, mais ça arrive. Les développeurs d'API peuvent également choisir d'exposer une méthode privée comme publique, ce qui signifie qu'ils devront refactoriser le nom de la méthode en plus de modifier le modificateur d'accès. Pas de gros problème, mais néanmoins une nuisance.
Johan Fredrik Varen
Johan - le refactoring est une nuisance? Mon éditeur a une fonctionnalité appelée "Rechercher et remplacer". Fonctionne très bien!
DaveWalley
C'est une convention C # que vous pouvez utiliser pour préfixer les membres privés avec exactement un trait de soulignement. Par conséquent, c'était une convention Zend Framework 1 (2012) de le faire de la même manière.
alpham8
73

Je pense que la source la plus fiable pour ce type de conventions pour PHP à l'heure actuelle serait le PSR-2: Coding Style Guide car le Zend Framework fait partie de PSR :

Les noms de propriété NE DEVRAIENT PAS être précédés d'un seul trait de soulignement pour indiquer une visibilité protégée ou privée.

Joedevon
la source
9
Utiliser une convention de dénomination n'est pas une raison d'aimer une langue, je pense.
sepehr
4
Quand j'ai lu pour la première fois à ce sujet, j'ai compris la raison d'être pour que vous puissiez regarder une méthode et savoir si elle est publique ou privée. Ce qui aurait eu beaucoup plus de sens s'il s'agissait d'une exigence plutôt que d'une convention. Parce que si un programmeur dans une équipe ajoute un trait de soulignement là où il n'est pas nécessaire, ou en rend un public avec un trait de soulignement, vous vous retrouvez avec beaucoup de confusion. Il s'avère que cela vient de PHP4 comme le souligne Jeremy, & #ZF a basé sa convention sur la convention PEAR. PEAR l'a supprimé et je pense que #ZF suivra.
joedevon
Cette réponse est correcte. C'est partout dans Magento, et comme indiqué par Sliq ci-dessous, c'est une convention qui est généralement obsolète.
siliconrockstar
Voici le lien mis à jour à ce sujet. framework.zend.com/manual/1.12/en/…
Shapeshifter
FYI (et @joedevon) Zend 2.4 est sorti il ​​y a quelques mois, et ils utilisent toujours le soulignement pour le framework privé et protégé.zend.com/manual/current/en/ref/… .
James
40

Maintenant, en 2013, c'est "officiellement" un mauvais style selon la directive de codage PSR-2:

Les noms de propriété NE DEVRAIENT PAS être précédés d'un seul trait de soulignement pour indiquer une visibilité protégée ou privée.

Source: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md

Sliq
la source
6
selon PSR-2-> "NE DEVRAIT PAS" signifie "NE PAS RECOMMANDER" non interdit Cela signifie dans certains cas peut être acceptable. PSR Doc -> ietf.org/rfc/rfc2119.txt
ahmed hamdy
14

J'étais fermement contre le préfixe des méthodes privées / protégées avec un trait de soulignement car vous pouvez utiliser un mot-clé privé / protégé pour cela et l'EDI le marquera pour vous.

Et je le suis toujours, mais j'ai trouvé une raison pour laquelle cela peut être une bonne pratique. Imaginez que vous ayez une méthode publique addFoo()et à l'intérieur de cette méthode, vous avez une partie de la tâche qui est commune avec d'autres méthodes addFooWhenBar(), addFooWhenBaz()... Maintenant, le meilleur nom pour cette méthode commune serait addFoo(), mais il est déjà pris, vous devez donc en trouver vilain nom comme addFooInternal()ou addFooCommon()ou ... mais _addFoo()la méthode privée semble la meilleure.

umpirsky
la source
Ouais, d'accord. En fait, je suis venu ici pour voir ce que les autres pensaient des soulignés parce que je ne les ai que rarement utilisés, et cela me semble toujours faux, mais cet exemple est une fois que j'ai. Je les ai également utilisés pour certains cas du modèle de méthode de modèle où une méthode publique appelle des méthodes protégées abstraites que les enfants ont surchargées, ce qui est une idée similaire. Parfois, une méthode publique et une méthode protégée abstraite qu'elle appelle sont si similaires ou liées que les nommer différemment semble plus étrange que de simplement préfixer un _ à l'abstrait.
John Pancoast
12

Les traits de soulignement de premier plan sont généralement utilisés pour les propriétés et méthodes privées . Ce n'est pas une technique que j'emploie habituellement, mais qui reste populaire parmi certains programmeurs.

Jonstjohn
la source
10

J'utilise un trait de soulignement principal dans la classe PHP 5 que j'écris pour les méthodes privées. C'est un petit signal visuel pour le développeur qu'un membre de classe particulier est privé. Ce type d'indication n'est pas aussi utile lorsque vous utilisez un IDE qui distingue les membres publics et privés pour vous. Je l'ai ramassé de mes jours C #. Vieilles habitudes...

GloryFish
la source
5

Je crois que votre hypothèse originale était correcte, j'ai trouvé que c'est une pratique courante pour certaines langues de préfixer un trait de soulignement aux méthodes / membres, etc. qui sont censées rester privées de l '"objet". Juste une façon visuelle de dire, même si vous le pouvez, vous ne devriez pas appeler ça!

Quintin Robinson
la source
5

Je cherchais la même réponse, j'ai fait quelques recherches, et je viens de découvrir que les frameworks php suggèrent différents styles:

Allumeur de code

Le manuel officiel a une section de style de codage qui encourage cette pratique :

Méthodes et variables privées

Les méthodes et les variables qui ne sont accessibles qu'en interne, telles que les fonctions utilitaires et d'assistance que vos méthodes publiques utilisent pour l'abstraction de code, doivent être précédées d'un trait de soulignement.

public function convert_text()

private function _convert_text()

D'autres frameworks font de même, comme

Cakephp:

fait la même chose :

Visibilité des membres

Utilisez les mots-clés privés et protégés de PHP5 pour les méthodes et les variables. En outre, les méthodes non publiques ou les noms de variables commencent par un seul trait de soulignement (_). Exemple:

class A
{
    protected $_iAmAProtectedVariable;

    protected function _iAmAProtectedMethod()
    {
       /* ... */
    }

    private $_iAmAPrivateVariable;

    private function _iAmAPrivateMethod()
    {
        /* ... */
    }
}

Et aussi

POIRE

fait la même chose :

Les membres privés de la classe sont précédés d'un seul trait de soulignement. Par exemple:

$_status    _sort()     _initTree()

Tandis que

Drupal

le style de code met spécifiquement en garde contre ceci :

  1. Les propriétés et méthodes protégées ou privées ne doivent pas utiliser de préfixe de soulignement.

Symphonie

d'autre part, déclare :

Symfony suit les normes définies dans les documents PSR-0, PSR-1, PSR-2 et PSR-4.

m.ardito
la source
Réponse très complète.
colonelclick
4

Je le connais depuis python, où le préfixe de vos variables avec un trait de soulignement oblige le compilateur à traduire une séquence aléatoire de lettres et de chiffres devant le nom de la variable réelle. Cela signifie que toute tentative d'accès à la variable depuis l'extérieur de la classe entraînerait une erreur "variable non définie".

Je ne sais pas si c'est toujours la convention à utiliser en python, cependant

Matthieu
la source
3

Dans Drupal (un CMS php), les traits de soulignement peuvent être utilisés pour empêcher les hooks d'être appelés ( https://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7 ).

Si j'ai un module appelé "my_module" et que je veux nommer une fonction my_module_insert, il "accrocherait" la fonction hook_insert. Pour éviter cela, je peux renommer ma fonction en _my_module_insert.

ps La façon dont les hooks fonctionnent dans Drupal, il est possible d'implémenter un hook par erreur, ce qui est très mauvais.

maho
la source
1
J'ai considéré cela comme un défaut de conception de Drupal pendant un certain temps. Il serait plus judicieux d'enregistrer explicitement vos hooks pour éviter toute confusion et opération erratique. L'hypothèse est généralement une mauvaise chose et les constructions qui interfèrent avec la programmation normale ou les détournent sont généralement une architecture médiocre.
mopsyd
3

Drupal et en utilisant un trait de soulignement:

D'une manière générale, le trait de soulignement consiste simplement à marquer le fait qu'une fonction ne serait probablement appelée que par une fonction parent liée ...

function mymodule_tool($sting="page title"){
    $out ='';
    //do stuff 
    $out  .= _mymodule_tool_decor($sting);
    return $out;
}

function _mymodule_tool_decor($sting){
    return '<h1>'.$string.'</h1>';
}

Bien sûr, juste un exemple simple ...

user3613677
la source
0

Utiliser le trait de soulignement juste pour se souvenir que nous ne «modifierons pas la variable» / «n'appellerons la fonction» en dehors de la classe.

Comme nous déclarons les variables const en toutes majuscules afin que tout en voyant le nom de la variable puisse deviner qu'il s'agit d'une variable const. Similaire à la variable que nous ne voulons pas modifier en dehors de la classe, nous la déclarons avec un soulignement pour notre propre convention.

Tassawer
la source
Qu'entendez-vous par «variables const»? Comment définir une constante variable?
Nico Haase
-21

Ils sont appelés «méthodes magiques» .

Tristan
la source
39
_foo()avec un seul trait de soulignement n'est pas une méthode magique. Les méthodes magiques sont indiquées par deux traits de soulignement consécutifs. La question ici ne parle que d'un seul.
BoltClock