Qual è il problema con un carattere di sottolineatura principale nei metodi di classe PHP?


155

Osservando varie librerie PHP ho notato che molte persone scelgono di aggiungere un prefisso ad alcuni metodi di classe con un singolo trattino basso, come

public function _foo()

...invece di...

public function foo()

Mi rendo conto che alla fine questo dipende dalle preferenze personali, ma mi chiedevo se qualcuno avesse avuto un'idea di da dove provenga questa abitudine.

Il mio pensiero è che probabilmente è stato riportato da PHP 4, prima che i metodi di classe potessero essere contrassegnati come protetti o privati, come un modo per implicare "non chiamare questo metodo al di fuori della classe". Tuttavia, mi è anche venuto in mente che forse ha origine da qualche parte (una lingua) che non conosco o che potrebbe esserci un buon ragionamento dietro cui trarrebbe beneficio dalla conoscenza.

Eventuali pensieri, intuizioni e / o opinioni sarebbero apprezzati.


9
Aggiornamento 2014: sintassi obsoleta ufficialmente: github.com/php-fig/fig-standards/blob/master/accepted/…
Sliq

Risposte:


155

È dai brutti tempi di Object Oriented PHP (PHP 4). L'implementazione di OO era piuttosto negativa e non includeva cose come i metodi privati. Per compensare, gli sviluppatori PHP hanno preceduto i metodi che dovevano essere privati ​​con un carattere di sottolineatura. In alcune classi precedenti vedrai/**private*/ __foo() { di dargli un peso extra.

Non ho mai sentito parlare di sviluppatori che precedono tutti i loro metodi con caratteri di sottolineatura, quindi non posso iniziare a spiegare quali sono le cause.


12
Metto un carattere di sottolineatura prima dei metodi nei miei controller che sono privati ​​della classe e non utilizzati nel routing. Poiché lavoro con il mio framework, questo aggiunge sicurezza poiché imposto la politica di nessun carattere di sottolineatura principale sui nomi dei controller all'interno delle rotte. Questo raramente supera 1-2 metodi per controller.
Robert K,

6
Per convenzione, con perl, il metodo che inizia con un trattino basso è privato. Ma è solo una convenzione. In effetti, questi metodi sono ancora accessibili dall'esterno della classe.
Luc M

I caratteri di sottolineatura hanno ancora meno senso se una classe di estensione decide di rendere pubblico il metodo protetto dei genitori. È un caso limite, ma succede. Gli sviluppatori di API possono anche scegliere di esporre un metodo privato come pubblico, il che significa che dovrebbero modificare il nome del metodo oltre a modificare il modificatore di accesso. Nessun problema, ma comunque un fastidio.
Johan Fredrik Varen,

Johan - il refactoring è un fastidio? Il mio editor ha una funzione chiamata "Trova e sostituisci". Funziona alla grande!
DaveWalley,

È una convenzione C # che puoi usare per aggiungere un prefisso ai membri privati ​​con esattamente un carattere di sottolineatura. Pertanto è stata una convenzione Zend Framework 1 (2012) a farlo allo stesso modo.
alpham8

73

Credo che la fonte più autorevole per questo tipo di convenzioni per PHP in questo momento sia la PSR-2: Coding Style Guide perché Zend Framework fa parte di PSR :

I nomi delle proprietà NON DOVREBBERO essere preceduti da un singolo trattino basso per indicare la visibilità protetta o privata.


9
L'uso di una convenzione di denominazione non è un motivo per amare una lingua, credo.
sepehr,

4
Quando ho letto per la prima volta di questo, ho capito il motivo per cui puoi guardare un metodo e sapere se è pubblico o privato. Il che avrebbe avuto molto più senso se fosse un requisito piuttosto che una convenzione. Perché se un programmatore di una squadra aggiunge un carattere di sottolineatura laddove non necessario, o lo rende pubblico con un carattere di sottolineatura, si finisce con molta confusione. A quanto pare, questo proviene da PHP4, come sottolinea Jeremy, e #ZF ha basato la loro convenzione sulla convenzione PEAR. PEAR lo ha rimosso e credo che #ZF seguirà l'esempio.
joedevon,

Questa risposta è corretta È in tutto il maledetto posto a Magento e, come notato da Sliq in basso, è una convenzione che è stata generalmente deprecata.
siliconrockstar,

Ecco il link aggiornato al riguardo. framework.zend.com/manual/1.12/it/…
Shapeshifter l'

FYI (e @joedevon) Zend 2.4 è stato rilasciato qualche mese fa e usano ancora la sottolineatura per framework privato e protetto.zend.com/manual/current/en/ref/… .
James,

40

Ora, nel 2013, questo è uno stile "ufficialmente" cattivo secondo le linee guida di codifica PSR-2:

I nomi delle proprietà NON DOVREBBERO essere preceduti da un singolo trattino basso per indicare la visibilità protetta o privata »

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


6
in base a PSR-2-> "NON DOVREBBE" significa "NON RACCOMANDARE" non proibito. In alcuni casi, questo significa che può essere accettabile. Documento PSR -> ietf.org/rfc/rfc2119.txt
ahmed hamdy

14

Ero fortemente contrario al prefisso dei metodi privati ​​/ protetti con il trattino basso poiché puoi usare la parola chiave privata / protetta per questo e IDE lo segnerà per te.

E lo sono ancora, ma ho trovato una ragione per cui può essere una buona pratica. Immagina di avere un metodo pubblico addFoo()e all'interno di quel metodo hai una parte del compito che è comune con altri metodi addFooWhenBar(), addFooWhenBaz()... Ora, il nome migliore per quel metodo comune sarebbe addFoo(), ma è già stato preso, quindi devi trovare un po ' brutto nome come addFooInternal()o addFooCommon()o ... ma il _addFoo()metodo privato sembra il migliore.


Sì, d'accordo. In realtà sono venuto qui per vedere cosa ne pensavano gli altri dei caratteri di sottolineatura perché li ho usati solo raramente e mi sembra sempre sbagliato, ma questo esempio è una volta che ho. Li ho anche usati per alcuni casi del modello di modello in cui un metodo pubblico fa appello a metodi protetti astratti che i bambini hanno scavalcato, il che è un'idea simile. A volte un metodo pubblico e un metodo protetto astratto che chiama sono così simili o correlati che nominarli in modo diverso sembra più strano del semplice prefisso di _ a quello astratto.
John Pancoast,

12

I caratteri di sottolineatura principali vengono generalmente utilizzati per proprietà e metodi privati . Non è una tecnica che di solito utilizzo, ma rimane popolare tra alcuni programmatori.


10

Uso un carattere di sottolineatura principale nella classe PHP 5 che scrivo per metodi privati. È un piccolo segnale visivo allo sviluppatore che un determinato membro della classe è privato. Questo tipo di suggerimento non è utile quando si utilizza un IDE che distingue i membri pubblici e privati ​​per te. L'ho raccolto dai miei giorni C #. Vecchie abitudini ...


5

Credo che la tua ipotesi originale fosse corretta, ho trovato che per alcune lingue è una prassi comune anteporre un carattere di sottolineatura a metodi / membri ecc. Che devono essere mantenuti privati ​​dell '"oggetto". Solo un modo visivo per dire, anche se puoi, non dovresti chiamarlo così!


5

Stavo cercando la stessa risposta, ho fatto qualche ricerca e ho appena scoperto che i framework php suggeriscono stili diversi:

Accenditore di codice

Il manuale ufficiale ha una sezione di stile di codifica che incoraggia questa pratica :

Metodi e variabili privati

I metodi e le variabili a cui si accede solo internamente, come le funzioni di utilità e di supporto utilizzate dai metodi pubblici per l'astrazione del codice, devono essere preceduti da un trattino basso.

public function convert_text()

private function _convert_text()

Altri framework fanno lo stesso, come

CakePHP:

fa lo stesso :

Visibilità dei membri

Usa le parole chiave private e protette di PHP5 per metodi e variabili. Inoltre, i nomi di metodi o variabili non pubblici iniziano con un singolo trattino basso (_). Esempio:

class A
{
    protected $_iAmAProtectedVariable;

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

    private $_iAmAPrivateVariable;

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

E anche

PERA

fa lo stesso :

I membri della classe privata sono preceduti da un singolo trattino basso. Per esempio:

$_status    _sort()     _initTree()

Mentre

Drupal

lo stile di codice mette specificamente in guardia contro questo :

  1. Le proprietà e i metodi protetti o privati ​​non devono utilizzare un prefisso di sottolineatura.

Sinfonia

d'altra parte, dichiara :

Symfony segue gli standard definiti nei documenti PSR-0, PSR-1, PSR-2 e PSR-4.


Risposta molto approfondita.
Colonelclick,

4

Lo so da Python, dove il prefisso delle variabili con un trattino basso fa sì che il compilatore traduca una sequenza casuale di lettere e numeri davanti al nome della variabile attuale. Ciò significa che qualsiasi tentativo di accedere alla variabile dall'esterno della classe comporterebbe un errore "variabile non definita".

Non so se questa è ancora la convenzione da usare in Python


3

In Drupal (un php CMS) i caratteri di sottolineatura possono essere utilizzati per impedire la chiamata di hook ( https://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7 ).

Se ho un modulo chiamato "my_module" e voglio nominare una funzione my_module_insert, si "aggancerebbe" alla funzione hook_insert. Per evitare ciò, posso rinominare la mia funzione in _my_module_insert.

ps Il modo in cui funzionano gli hook in Drupal è possibile implementare un hook per errore, il che è molto male.


1
Ho considerato questo come un difetto di progettazione di drupal per qualche tempo. Avrebbe più senso registrare esplicitamente i tuoi hook per evitare confusione e operazioni errate. Il presupposto è generalmente negativo e i costrutti che interferiscono con la normale programmazione o li dirottano sono di solito un'architettura scadente.
mopsyd,

3

Drupal e usando il trattino basso:

In generale, il carattere di sottolineatura è semplicemente quello di contrassegnare il fatto che una funzione sarebbe probabilmente chiamata solo da una funzione genitore correlata ...

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

Certo, solo un semplice esempio ...


0

Usando la sottolineatura solo per ricordare che non "modificheremo la variabile" / "chiameremo la funzione" al di fuori della classe.

Mentre dichiariamo variabili const in tutte le maiuscole in modo che mentre si vede il nome della variabile possa indovinare che si tratta di una variabile const. Simile alla variabile che non vogliamo modificare al di fuori della classe, la dichiariamo con trattino basso per la nostra convenzione.


Cosa intendi con "variabili costanti"? Come hai potuto definire una costante che è variabile?
Nico Haase,

-21

Sono chiamati "metodi magici" .


39
_foo()con un singolo trattino basso non è un metodo magico. I metodi magici sono indicati da due caratteri di sottolineatura iniziali consecutivi. La domanda qui parla solo di uno.
BoltClock
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.