¿Cuál es el trato con un guión bajo destacado en los métodos de clase PHP?

155

Al revisar varias bibliotecas PHP, noté que muchas personas eligen prefijar algunos métodos de clase con un solo guión bajo, como

public function _foo()

...en vez de...

public function foo()

Me doy cuenta de que, en última instancia, esto se reduce a la preferencia personal, pero me preguntaba si alguien tenía alguna idea de dónde proviene este hábito.

Creo que probablemente se está transfiriendo de PHP 4, antes de que los métodos de clase se puedan marcar como protegidos o privados, como una forma de implicar "no llame a este método desde fuera de la clase". Sin embargo, también se me ocurrió que tal vez se origina en algún lugar (un idioma) con el que no estoy familiarizado o que puede haber un buen razonamiento detrás de esto que me beneficiaría saber.

Cualquier pensamiento, ideas y / u opiniones serán apreciadas.

sin efectivo
fuente
9
Actualización 2014: es una sintaxis oficialmente desactualizada: github.com/php-fig/fig-standards/blob/master/accepted/…
Sliq

Respuestas:

155

Es de los viejos tiempos de PHP orientado a objetos (PHP 4). Esa implementación de OO fue bastante mala y no incluyó cosas como métodos privados. Para compensar, los desarrolladores de PHP introdujeron métodos que pretendían ser privados con un guión bajo. En algunas clases anteriores, verás que le /**private*/ __foo() {das un poco de peso extra.

Nunca he oído hablar de desarrolladores que introduzcan todos sus métodos con guiones bajos, por lo que no puedo comenzar a explicar qué causa eso.

Jeremy DeGroot
fuente
12
Coloco un guión bajo antes de los métodos en mis controladores que son privados para la clase y no se utilizan en el enrutamiento. Debido a que trabajo con mi propio marco, esto agrega seguridad ya que impongo la política de no subrayar los nombres de los controladores dentro de las rutas. Pero esto rara vez supera los 1-2 métodos por controlador.
Robert K
66
Por convención, con perl, el método que comienza con un guión bajo es privado. Pero es solo una convención. De hecho, estos métodos aún son accesibles desde fuera de la clase.
Luc M
Los guiones bajos tienen aún menos sentido si una clase que se extiende decide hacer público el método protegido de sus padres. Es un caso marginal, pero sucede. Los desarrolladores de API también pueden optar por exponer un método privado como público, lo que significa que tendrían que refactorizar el nombre del método además de cambiar el modificador de acceso. No es gran cosa, pero una molestia, no obstante.
Johan Fredrik Varen
Johan: ¿refactorizar es una molestia? Mi editor tiene una función llamada "Buscar y reemplazar". ¡Funciona genial!
DaveWalley
Es una convención de C # que puede usar para prefijar miembros privados con exactamente un guión bajo. Por lo tanto, fue una convención Zend Framework 1 (2012) hacerlo de la misma manera.
alpham8
73

Creo que la fuente más autorizada para este tipo de convenciones para PHP en este momento sería la Guía de estilo de codificación PSR-2 porque el Marco Zend es parte de PSR :

Los nombres de propiedad NO DEBEN tener el prefijo de un solo guión bajo para indicar visibilidad protegida o privada.

joedevon
fuente
9
Creo que usar una convención de nombres no es una razón para amar un idioma.
sepehr
44
Cuando leí por primera vez sobre esto, entendí la razón para que pueda ver un método y saber si es público o privado. Lo que habría tenido mucho más sentido si fuera un requisito más que una convención. Porque si 1 programador en un equipo agrega un guión bajo cuando no es necesario, o hace público uno con un guión bajo, terminas con mucha confusión. Como resultado, esto vino de PHP4 como señala Jeremy, y #ZF basó su convención fuera de la convención PEAR. PEAR lo ha eliminado y creo que #ZF hará lo mismo.
joedevon
Esta respuesta es correcta. Está en todo el maldito lugar en Magento, y como lo señala Sliq a continuación, es una convención que generalmente ha quedado en desuso.
siliconrockstar
Aquí está el enlace actualizado sobre esto. framework.zend.com/manual/1.12/en/…
Shapeshifter
FYI (y @joedevon) Zend 2.4 se lanzó hace unos meses, y todavía usan guiones bajos para framework.zend.com/manual/current/en/ref/… privado y protegido .
James
40

Ahora, en 2013, este es un estilo "oficialmente malo" según la directriz de codificación PSR-2:

Los nombres de propiedad NO DEBEN tener el prefijo de un solo guión bajo para indicar visibilidad protegida o privada.

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

Sliq
fuente
66
de acuerdo con PSR-2-> "NO DEBE" significa "NO RECOMENDAR" no está prohibido Eso significa que en algunos casos puede ser aceptable. PSR Doc -> ietf.org/rfc/rfc2119.txt
ahmed hamdy
14

Estaba totalmente en contra de prefijar métodos privados / protegidos con guión bajo ya que puede usar palabras clave privadas / protegidas para eso e IDE lo marcará por usted.

Y todavía lo estoy, pero encontré una razón por la cual puede ser una buena práctica. Imagine que tiene un método público addFoo()y dentro de ese método tiene una parte de la tarea que es común con otros métodos addFooWhenBar(), addFooWhenBaz()... Ahora, el mejor nombre para ese método común sería addFoo(), pero ya está en uso, por lo que debe encontrar algunos nombre feo como addFooInternal()o addFooCommon()o ... pero _addFoo()el método privado parece el mejor.

Umpirsky
fuente
Si, de acuerdo. De hecho, vine aquí para ver lo que otros pensaban sobre los guiones bajos porque rara vez los he usado, y siempre se siente mal, pero este ejemplo es una vez que lo he hecho. También los he usado para algunos casos del patrón de método de plantilla donde un método público recurre a métodos abstractos protegidos que los niños han anulado, lo cual es una idea similar. A veces, un método público y un método protegido abstracto que llama son tan similares o relacionados que nombrarlos de manera diferente parece más extraño que simplemente prefijar un _ al abstracto.
John Pancoast
12

Los guiones bajos principales se usan generalmente para propiedades y métodos privados . No es una técnica que suelo emplear, pero sigue siendo popular entre algunos programadores.

jonstjohn
fuente
10

Utilizo un guión bajo destacado en la clase PHP 5 que escribo para métodos privados. Es una pequeña señal visual para el desarrollador que un miembro particular de la clase es privado. Este tipo de sugerencia no es tan útil cuando se utiliza un IDE que distingue a los miembros públicos y privados por usted. Lo recogí de mis días C #. Viejos hábitos ...

GloryFish
fuente
5

Creo que su suposición original era correcta, he encontrado que es una práctica común para algunos idiomas prefijar un guión bajo a métodos / miembros, etc. que deben mantenerse en privado con el "objeto". ¡Solo una forma visual de decir que aunque puedes, no deberías llamar a esto!

Quintin Robinson
fuente
5

Estaba buscando la misma respuesta, investigué un poco y acabo de descubrir que los frameworks php sugieren diferentes estilos:

Code Igniter

El manual oficial tiene una sección de estilo de codificación que fomenta esta práctica :

Métodos privados y variables

Los métodos y variables a los que solo se accede internamente, como las funciones de utilidad y de ayuda que utilizan sus métodos públicos para la abstracción de código, deben ir precedidos de un guión bajo.

public function convert_text()

private function _convert_text()

Otros marcos hacen lo mismo, como

Cakephp:

hace lo mismo :

Visibilidad de miembros

Utilice las palabras clave privadas y protegidas de PHP5 para métodos y variables. Además, los métodos no públicos o nombres de variables comienzan con un solo guión bajo (_). Ejemplo:

class A
{
    protected $_iAmAProtectedVariable;

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

    private $_iAmAPrivateVariable;

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

Y también

PERA

hace lo mismo :

Los miembros de la clase privada están precedidos por un solo guión bajo. Por ejemplo:

$_status    _sort()     _initTree()

Mientras

Drupal

el estilo de código advierte específicamente contra esto :

  1. Las propiedades y métodos protegidos o privados no deben usar un prefijo de subrayado.

Sinfonía

por otro lado, declara :

Symfony sigue los estándares definidos en los documentos PSR-0, PSR-1, PSR-2 y PSR-4.

m.ardito
fuente
Respuesta muy completa.
coronelclick
4

Lo sé por python, donde el prefijo de sus variables con un guión bajo hace que el compilador traduzca una secuencia aleatoria de letras y números delante del nombre real de la variable. Esto significa que cualquier intento de acceder a la variable desde fuera de la clase daría como resultado un error de "variable indefinida".

Sin embargo, no sé si esta es la convención para usar en Python

Mateo
fuente
3

En Drupal (un PHP CMS), los guiones bajos se pueden utilizar para evitar que se llamen ganchos ( https://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7 ).

Si tengo un módulo llamado "my_module" y quiero nombrar una función my_module_insert, se "enganchará" en la función hook_insert. Para evitar eso, puedo cambiar el nombre de mi función a _my_module_insert.

ps La forma en que los ganchos funcionan en Drupal es posible implementar un gancho por error, lo cual es muy malo.

maho
fuente
1
Lo he considerado un defecto de diseño de Drupal desde hace algún tiempo. Tendría más sentido registrar explícitamente sus ganchos para evitar confusiones y operaciones erráticas. La suposición generalmente es algo malo, y las construcciones que interfieren con la programación normal o las secuestran generalmente son de mala arquitectura.
mopsyd
3

Drupal, y usando guión bajo:

De manera general, el guión bajo es simplemente marcar el hecho de que una función probablemente solo sea llamada por una función padre relacionada ...

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>';
}

Por supuesto, solo un simple ejemplo ...

usuario3613677
fuente
0

Usando subrayado solo para recordar el propósito de que no 'modificaremos la variable' / 'llamaremos a la función' fuera de la clase.

Como declaramos variables const en mayúsculas para que al ver el nombre de la variable podamos adivinar que es una variable const. Similar a la variable que no queremos modificar fuera de la clase, la declaramos con guión bajo para nuestra propia convención.

Tassawer
fuente
¿Qué quieres decir con "variables constantes"? ¿Cómo podrías definir una constante que sea variable?
Nico Haase
-21

Se llaman "métodos mágicos" .

Tristan
fuente
39
_foo()con un solo guión bajo no es un método mágico. Los métodos mágicos se denotan por dos guiones bajos consecutivos. La pregunta aquí habla solo de uno.
BoltClock