O co chodzi z wiodącym podkreśleniem w metodach klas PHP?

155

Przeglądając różne biblioteki PHP, zauważyłem, że wiele osób decyduje się na poprzedzanie niektórych metod klasowych pojedynczym podkreśleniem, na przykład

public function _foo()

...zamiast...

public function foo()

Zdaję sobie sprawę, że ostatecznie sprowadza się to do osobistych preferencji, ale zastanawiałem się, czy ktoś ma jakiś wgląd w to, skąd pochodzi ten nawyk.

Wydaje mi się, że jest to prawdopodobnie przenoszone z PHP 4, zanim metody klasowe mogłyby zostać oznaczone jako chronione lub prywatne, w celu zasugerowania „nie wywołuj tej metody spoza klasy”. Jednak przyszło mi również do głowy, że może pochodzi skądś (język), którego nie znam lub że może kryć się za tym rozsądne uzasadnienie, którego znajomość przyniosłaby mi korzyści.

Wszelkie przemyślenia, spostrzeżenia i / lub opinie będą mile widziane.

brak gotówki
źródło
9
Aktualizacja 2014: Jest to oficjalnie przestarzała składnia: github.com/php-fig/fig-standards/blob/master/accepted/...
Sliq

Odpowiedzi:

155

Pochodzi ze złych, starych czasów Object Oriented PHP (PHP 4). Ta implementacja OO była dość zła i nie obejmowała rzeczy takich jak metody prywatne. Aby to zrekompensować, programiści PHP poprzedzili metody, które miały być prywatne, podkreśleniem. W niektórych starszych klasach zobaczysz, /**private*/ __foo() {jak nadać mu trochę wagi.

Nigdy nie słyszałem o programistach poprzedzających wszystkie swoje metody podkreśleniami, więc nie mogę zacząć wyjaśniać, co to powoduje.

Jeremy DeGroot
źródło
12
Umieszczam podkreślenie przed metodami w moich kontrolerach, które są prywatne dla klasy i nieużywane w routingu. Ponieważ pracuję z własną strukturą, zwiększa to bezpieczeństwo, ponieważ wymuszam zasadę braku wiodącego podkreślenia w nazwach kontrolerów w trasach. Ale rzadko przekracza to 1-2 metody na kontroler.
Robert K
6
Zgodnie z konwencją, w perlu metody zaczynające się od podkreślenia są prywatne. Ale to tylko konwencja. W rzeczywistości te metody są nadal dostępne spoza klasy.
Luc M
Podkreślenia mają jeszcze mniej sensu, jeśli klasa rozszerzająca zdecyduje się upublicznić chronioną metodę swojego rodzica. To skrajna sprawa, ale się zdarza. Deweloperzy API mogą również zdecydować się na ujawnienie metody prywatnej jako publicznej, co oznacza, że ​​oprócz zmiany modyfikatora dostępu musieliby refaktoryzować nazwę metody. Nic wielkiego, ale mimo to uciążliwe.
Johan Fredrik Varen
Johan - refaktoryzacja jest uciążliwa? Mój edytor ma funkcję „Znajdź i zamień”. Działa świetnie!
DaveWalley
Jest to konwencja języka C #, której można użyć, aby poprzedzić prywatnych członków dokładnie jednym podkreśleniem. Dlatego konwencja Zend Framework 1 (2012) zakładała zrobienie tego w ten sam sposób.
alpham8
73

Uważam, że obecnie najbardziej miarodajnym źródłem tego rodzaju konwencji PHP byłby PSR-2: Przewodnik po stylach kodowania, ponieważ Zend Framework jest częścią PSR :

Nazwy właściwości NIE POWINNY być poprzedzane pojedynczym podkreśleniem, aby wskazać widoczność chronioną lub prywatną.

joedevon
źródło
9
Myślę, że używanie konwencji nazewnictwa nie jest powodem do kochania języka.
wrzesień
4
Kiedy po raz pierwszy o tym przeczytałem, zrozumiałem powód, dla którego warto spojrzeć na metodę i wiedzieć, czy jest ona publiczna czy prywatna. Co miałoby dużo więcej sensu, gdyby był to raczej wymóg niż konwencja. Ponieważ jeśli jeden programista w zespole doda podkreślenie, gdzie nie jest potrzebne, lub upubliczni go z podkreśleniem, skończysz z dużym zamieszaniem. Jak się okazuje, pochodzi to z PHP4, jak podkreśla Jeremy, & #ZF oparł swoją konwencję na konwencji PEAR. PEAR usunął go i wierzę, że #ZF pójdzie w jego ślady.
joedevon
Ta odpowiedź jest poprawna. To cholerne miejsce w Magento i jak zauważył poniżej Sliq, jest to konwencja, która została ogólnie przestarzała.
siliconrockstar
Oto zaktualizowany link dotyczący tego. framework.zend.com/manual/1.12/en/…
Shapeshifter
FYI (i @joedevon) Zend 2.4 został wydany kilka miesięcy temu i nadal używają podkreślenia dla prywatnych i chronionych framework.zend.com/manual/current/en/ref/… .
James
40

Teraz, w 2013 roku, jest to „oficjalnie” zły styl według wytycznych kodowania PSR-2:

Nazwy właściwości NIE POWINNY być poprzedzane pojedynczym podkreśleniem w celu wskazania widoczności chronionej lub prywatnej "

Źródło: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md

Sliq
źródło
6
zgodnie z PSR-2-> „NIE POWINIENEŚ” oznacza „NIE POLECAĆ” nie jest zabronione To oznacza w niektórych przypadkach może być akceptowalne. PSR Doc -> ietf.org/rfc/rfc2119.txt
ahmed hamdy
14

Byłem zdecydowanie przeciwny dodawaniu przedrostków do metod prywatnych / chronionych podkreśleniem, ponieważ możesz użyć do tego słowa kluczowego private / protected, a IDE oznaczy je za Ciebie.

I nadal jestem, ale znalazłem jeden powód, dla którego może to być dobra praktyka. Wyobraź sobie, że masz sposób publiczny addFoo()i wewnątrz tej metodzie masz jakąś część zadania, która jest wspólna z innymi metodami addFooWhenBar(), addFooWhenBaz()... teraz, że najlepszą nazwą stosowaną metodą byłoby addFoo(), ale to jest już zajęta, więc trzeba wymyślić jakiś brzydka nazwa jak addFooInternal()lub addFooCommon()lub ... ale _addFoo()metoda prywatna wygląda na najlepszą.

umpirsky
źródło
Tak, zgodził się. Przyszedłem tutaj, aby zobaczyć, co inni myślą o podkreśleniach, ponieważ rzadko ich używałem i zawsze czuję się źle, ale ten przykład jest taki, jaki miałem. Użyłem ich również w niektórych przypadkach wzorca metody szablonu, w którym metoda publiczna wywołuje abstrakcyjne metody chronione, które zostały nadpisane przez dzieci, co jest podobnym pomysłem. Czasami metoda publiczna i abstrakcyjna metoda chroniona, którą wywołuje, są tak podobne lub powiązane, że nazwanie ich w inny sposób wydaje się dziwniejsze niż zwykłe dodawanie przedrostka _ do abstrakcyjnej.
John Pancoast
12

Podkreślenia wiodące są zwykle używane w przypadku prywatnych nieruchomości i metod . Nie jest to technika, którą zwykle stosuję, ale pozostaje popularna wśród niektórych programistów.

jonstjohn
źródło
10

Używam wiodącego podkreślenia w klasie PHP 5, którą piszę dla metod prywatnych. Jest to mała wizualna wskazówka dla programisty, że dany element klasy jest prywatny. Ten typ podpowiedzi nie jest tak przydatny, gdy używasz IDE, które rozróżnia członków publicznych i prywatnych. Podniosłem to z moich dni C #. Stare zwyczaje...

GloryFish
źródło
5

Uważam, że twoje pierwotne założenie było słuszne. Zauważyłem, że w niektórych językach powszechną praktyką jest dodawanie znaku podkreślenia do metod / elementów itp., Które mają pozostać prywatne w stosunku do „obiektu”. To tylko wizualny sposób na powiedzenie, chociaż możesz, nie powinieneś tego nazywać!

Quintin Robinson
źródło
5

Szukałem tej samej odpowiedzi, przeprowadziłem kilka badań i właśnie odkryłem, że frameworki php sugerują różne style:

Code Igniter

Oficjalny podręcznik zawiera sekcję dotyczącą stylu kodowania, która zachęca do tej praktyki :

Metody i zmienne prywatne

Metody i zmienne, do których dostęp jest możliwy tylko wewnętrznie, takie jak funkcje narzędziowe i pomocnicze, których metody publiczne używają do abstrakcji kodu, powinny być poprzedzone podkreśleniem.

public function convert_text()

private function _convert_text()

Inne frameworki robią to samo, na przykład

Cakephp:

robi to samo :

Widoczność członków

Użyj prywatnych i chronionych słów kluczowych PHP5 dla metod i zmiennych. Ponadto niepubliczne nazwy metod lub zmiennych zaczynają się od pojedynczego podkreślenia (_). Przykład:

class A
{
    protected $_iAmAProtectedVariable;

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

    private $_iAmAPrivateVariable;

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

I również

GRUSZKA

robi to samo :

Członkowie klasy prywatnej są poprzedzeni pojedynczym podkreśleniem. Na przykład:

$_status    _sort()     _initTree()

Podczas

Drupal

styl kodu specjalnie ostrzega przed tym :

  1. Chronione lub prywatne właściwości i metody nie powinny używać przedrostka podkreślenia.

Symfonia

z drugiej strony oświadcza :

Symfony przestrzega standardów określonych w dokumentach PSR-0, PSR-1, PSR-2 i PSR-4.

m.ardito
źródło
Bardzo dokładna odpowiedź.
Colonelclick
4

Znam to z Pythona, gdzie poprzedzanie zmiennych podkreśleniem powoduje, że kompilator tłumaczy pewną losową sekwencję liter i cyfr przed rzeczywistą nazwą zmiennej. Oznacza to, że każda próba uzyskania dostępu do zmiennej spoza klasy spowodowałaby błąd „zmienna niezdefiniowana”.

Nie wiem jednak, czy nadal jest to konwencja używana w Pythonie

Mateusz
źródło
3

W Drupalu (php CMS) podkreślenia mogą być używane do zapobiegania wywoływaniu hooków ( https://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7 ).

Jeśli mam moduł o nazwie „my_module” i chcę nazwać funkcję my_module_insert, zostanie to „zaczepione” o funkcję hook_insert. Aby temu zapobiec, mogę zmienić nazwę mojej funkcji na _my_module_insert.

ps Sposób działania hooków w Drupalu umożliwia omyłkowe zaimplementowanie hooków, co jest bardzo złe.

maho
źródło
1
Przez pewien czas uważałem to za wadę projektową Drupala. Bardziej sensowne byłoby jawne rejestrowanie punktów zaczepienia, aby uniknąć nieporozumień i błędnych operacji. Założenie jest ogólnie złą rzeczą, a konstrukcje, które kolidują z normalnym programowaniem lub przejmują je, są zwykle złą architekturą.
mopsyd
3

Drupal i używanie podkreślenia:

Ogólnie rzecz biorąc, podkreślenie ma na celu proste zaznaczenie faktu, że funkcja byłaby prawdopodobnie wywoływana tylko przez powiązaną funkcję nadrzędną ...

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

Oczywiście tylko prosty przykład ...

user3613677
źródło
0

Używanie podkreślenia tylko w celu zapamiętania, że ​​nie będziemy „modyfikować zmiennej” / „wywoływać funkcji” poza klasą.

Ponieważ deklarujemy zmienne const pisane dużymi literami, dzięki czemu widząc nazwę zmiennej można się domyślić, że jest to zmienna const. Podobnie jak zmienna, której nie chcemy modyfikować poza klasą, deklarujemy ją z podkreśleniem dla naszej własnej konwencji.

Tassawer
źródło
Co rozumiesz przez „zmienne stałe”? Jak możesz zdefiniować stałą, która jest zmienna?
Nico Haase
-21

Nazywa się je „metodami magicznymi” .

Tristan
źródło
39
_foo()z jednym początkowym podkreśleniem nie jest metodą magiczną. Metody magiczne są oznaczone dwoma kolejnymi wiodącymi podkreśleniami. Pytanie dotyczy tylko jednego.
BoltClock