Яка угода з провідним підкресленням методів класу PHP?


155

Переглядаючи різні бібліотеки PHP, я помітив, що багато людей обирають префікс деяких методів класу за допомогою одного підкреслення, наприклад

public function _foo()

...замість...

public function foo()

Я усвідомлюю, що в кінцевому рахунку це зводиться до особистих переваг, але мені було цікаво, чи хтось розуміє, звідки ця звичка походить.

Думаю, що це, ймовірно, переноситься з PHP 4, перш ніж методи класу можуть бути позначені як захищені або приватні, як спосіб натякнути на "не викликати цей метод поза класом". Однак мені також спало на думку, що, можливо, воно походить десь (мова), з якою я не знайомий, або що за цим можуть бути обґрунтовані міркування, які я б з користю знав.

Будь-які думки, уявлення та / або думки були б вдячні.


9
Оновлення 2014 року: це офіційно застарілий синтаксис: github.com/php-fig/fig-standards/blob/master/accepted/…
Sliq

Відповіді:


155

Це з старих поганих часів об'єктно-орієнтованого PHP (PHP 4). Така реалізація ОО була досить поганою, і вона не включала речі, як приватні методи. Щоб отримати компенсацію, розробники PHP наперед встановили методи, які мали бути приватними із підкресленням. У деяких старших класах ви побачите, /**private*/ __foo() {щоб надати цьому додаткову вагу.

Я ніколи не чув, щоб розробники домагалися всіх своїх методів підкресленнями, тому не можу почати пояснювати, що це викликає.


12
Я розміщую підкреслення перед методами у своїх контролерах, які є приватними для класу та не використовуються в маршрутизації. Оскільки я працюю зі своїм власним фреймворком, це додає безпеки, оскільки я виконую політику відсутності провідного підкреслення імен контролерів у маршрутах. Але це рідко перевищує 1-2 способи на контролер.
Роберт К

6
За умовою, за допомогою perl, метод, що починається з підкреслення, є приватним. Але це лише умовність. Фактично, ці методи все ще доступні поза класом.
Люк М

Підкреслення має ще менше сенсу, якщо розширений клас вирішить оприлюднити захищений метод його батьків. Це крайній випадок, але це буває. Розробники API також можуть викрити приватний метод як публічний, тобто їм доведеться переробляти ім'я методу на додаток до зміни модифікатора доступу. Ніякого великого, але все ж неприємності.
Йохан Фредрік Варен

Йохан - рефакторинг - це неприємність? Мій редактор має функцію під назвою "Знайти та замінити". Чудово працює!
DaveWalley

Це умова C #, яку ви можете використовувати для префіксації приватних членів точно з одним підкресленням. Тому це було так, як це було зроблено в Zend Framework 1 (2012).
alpham8

73

Я вважаю, що найавторитетнішим джерелом подібних конвенцій для PHP зараз було б PSR-2: Посібник зі стилів кодування, оскільки Zend Framework є частиною PSR :

Імена властивостей НЕ БУДЬ вказуватись окремим підкресленням для вказівки захищеної або приватної видимості.


9
Використання конвенції про іменування - я не думаю, що це привід любити мову.
sepehr

4
Коли я вперше прочитав про це, я зрозумів причину, щоб ви могли подивитися на метод і знати, чи є він державним чи приватним. Що мало б набагато більше сенсу, якби це була вимога, а не конвенція. Тому що, якщо один програміст команди додає підкреслення, якщо це зайве, або оприлюднює його з підкресленням, ви закінчитеся з великою плутаниною. Як виявляється, це походить від PHP4, як вказує Джеремі, & #ZF спирається на конвенцію PEAR. PEAR видалив його, і я вважаю, що #ZF піде за цим прикладом.
joedevon

Ця відповідь правильна. Це все прокляте місце в Магенто, і як зазначає Sliq нижче, це конвенція, яка, як правило, застаріла.
siliconrockstar

Ось оновлене посилання щодо цього. Framework.zend.com/manual/1.12/uk/…
Shapeshifter

FYI (і @joedevon) Zend 2.4 був випущений кілька місяців тому, і вони все ще використовують підкреслення для приватних і захищених Framework.zend.com/manual/current/en/ref/… .
Джеймс

40

Тепер, у 2013 році, це "офіційно" поганий стиль за принципом кодування PSR-2:

Назви властивостей НЕ БУДЬ вказуватися одним підкресленням, щоб вказувати на захищену або приватну видимість "

Джерело: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md


6
відповідно до PSR-2-> "БУДЕ НЕ" означає "НЕ РЕКОМЕНДУЙ" не заборонено. Це означає, що в деяких випадках може бути прийнятним. PSR Doc -> ietf.org/rfc/rfc2119.txt
ахмед хамді

14

Я був категорично проти префіксації приватних / захищених методів підкресленням, оскільки ви можете використовувати приватне / захищене ключове слово для цього, і IDE позначатиме це для вас.

І я все ще є, але я знайшов одну причину, чому це може бути хорошою практикою. Уявіть, що у вас є публічний методaddFoo() і всередині цього методу у вас є частина завдань, яка є спільною для інших методів addFooWhenBar(), addFooWhenBaz()... Тепер найкраща назва цього звичайного методу була б addFoo(), але вона вже прийнята, тому ви повинні придумати деякі потворне ім’я, як addFooInternal()або addFooCommon()чи ..., але _addFoo()приватний метод виглядає найкращим.


Так, погодився. Я насправді прийшов сюди, щоб побачити, що інші думають про підкреслення, тому що я їх рідко використовував, і це завжди буває неправильно, але цей приклад є один раз у мене. Я також використовував їх для деяких випадків шаблону методу шаблонів, коли публічний метод закликає абстрактні захищені методи, які діти перекрили, що є подібною ідеєю. Іноді публічний метод і абстрактно захищений метод, який він викликає, настільки схожі або пов'язані з цим, що називати їх по-різному здається більш дивними, ніж просто префіксація _ до абстрактного.
Джон Панкост

12

Провідні підкреслення зазвичай використовуються для приватних властивостей та методів . Це не техніка, яку я зазвичай використовую, але все ще залишається популярною серед деяких програмістів.


10

Я використовую провідне підкреслення в класі PHP 5, який я пишу для приватних методів. Це невелика візуальна підказка для розробника про те, що конкретний член класу є приватним. Цей тип натяку не настільки корисний при використанні IDE, що відрізняє публічних та приватних членів для вас. Я взяв його з моїх C # днів. Старі звички ...


5

Я вважаю, що ваше первісне припущення було правильним, я вважаю, що для деяких мов звичайною практикою є приставки підкреслення до методів / членів тощо, які повинні бути приватними для "об'єкта". Просто візуальний спосіб сказати, хоча ви можете, ви не повинні це називати!


5

Я шукав ту саму відповідь, я робив деякі дослідження, і я тільки що виявив, що фреймворки PHP пропонують різні стилі:

Код запалювача

В офіційному посібнику є розділ стилю кодування, який заохочує цю практику :

Приватні методи та змінні

Методи та змінні, до яких можна отримати доступ лише внутрішньо, такі як корисні та допоміжні функції, які використовуються вашими загальнодоступними методами для абстрагування коду, мають бути встановлені підкресленням.

public function convert_text()

private function _convert_text()

Інші рамки роблять те саме, як

Cakephp:

робить те ж саме :

Видимість учасника

Використовуйте приватні та захищені ключові слова PHP5 для методів та змінних. Крім того, непублічні методи або назви змінних починаються з одного підкреслення (_). Приклад:

class A
{
    protected $_iAmAProtectedVariable;

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

    private $_iAmAPrivateVariable;

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

І також

МІСЦЕ

робить те ж саме :

Для членів приватного класу передує один підкреслення. Наприклад:

$_status    _sort()     _initTree()

Поки

Друпал

стиль коду спеціально застерігає від цього :

  1. Захищені або приватні властивості та методи не повинні використовувати префікс підкреслення.

Симфонія

з іншого боку, заявляє :

Symfony відповідає стандартам, визначеним у документах PSR-0, PSR-1, PSR-2 та PSR-4.


Дуже ретельна відповідь.
colonelclick

4

Я знаю це з python, де префіксація ваших змінних підкресленням змушує компілятор перекладати якусь випадкову послідовність букв і цифр перед фактичним іменем змінної. Це означає, що будь-яка спроба отримати доступ до змінної за межами класу призведе до помилки "невизначена змінна".

Я не знаю, чи все-таки це умова використовувати в python


3

У Drupal (php CMS) підкреслення можна використовувати для запобігання виклику гачків ( https://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7 ).

Якщо у мене є модуль під назвою "my_module" і я хочу назвати функцію my_module_insert, він би "зачепився" на функцію mock_insert. Щоб запобігти тому, що я можу перейменувати свою функцію на _my_module_insert.

ps Спосіб роботи гачків у Drupal можна реалізувати гачок помилково, що дуже погано.


1
Я певний час вважав це недоліком дизайну drupal. Було б більше сенсу чітко зареєструвати свої гачки, щоб уникнути плутанини та нерегулярної роботи. Припущення, як правило, погана річ, і конструкції, які перешкоджають нормальному програмуванню або захоплюють їх, як правило, погана архітектура.
Мопсид

3

Drupal та за допомогою підкреслення:

Загалом підкреслення полягає в тому, щоб просто відзначити той факт, що функцію, ймовірно, може викликати лише пов'язана батьківська функція ...

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

Звичайно, просто простий приклад ...


0

Використання підкреслення лише для пам’яті, що ми не будемо «змінювати змінну» / «викликати функцію» поза класом.

Оскільки ми оголошуємо змінні const у всіх великих літерах, так що, переглядаючи ім'я змінної, можна здогадатися, що це змінна const. Подібну змінну, яку ми не хочемо змінювати поза класом, ми оголошуємо її підкресленням для власної конвенції.


Що ви маєте на увазі під "змінними const"? Як ви могли визначити константу, яка є змінною?
Ніко Хааз

-21

Їх називають "магічними методами" .


39
_foo()з єдиним провідним підкресленням не є магічним методом. Магічні методи позначаються двома послідовними провідними підкресленнями. Питання тут говорить лише про одне.
BoltClock
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.