Qual é o problema com um sublinhado líder nos métodos de classe PHP?

155

Ao examinar várias bibliotecas PHP, notei que muitas pessoas optam por prefixar alguns métodos de classe com um único sublinhado, como

public function _foo()

...ao invés de...

public function foo()

Percebo que, no final das contas, isso se resume à preferência pessoal, mas fiquei imaginando se alguém teria alguma ideia de onde esse hábito vem.

Meu pensamento é que provavelmente está sendo transferido do PHP 4, antes que os métodos de classe possam ser marcados como protegidos ou privados, como uma maneira de sugerir "não chame esse método de fora da classe". No entanto, também me ocorreu que talvez ele se origine em algum lugar (um idioma) com o qual eu não esteja familiarizado ou que possa haver um bom raciocínio por trás dele que eu me beneficiaria de saber.

Quaisquer pensamentos, idéias e / ou opiniões serão apreciados.

nocash
fonte
9
Atualização 2014: Está sintaxe oficialmente desatualizada: github.com/php-fig/fig-standards/blob/master/accepted/…
Sliq

Respostas:

155

É dos velhos tempos do PHP Orientado a Objetos (PHP 4). Essa implementação do OO foi muito ruim e não incluiu coisas como métodos privados. Para compensar, os desenvolvedores de PHP precederam métodos que deveriam ser privados com um sublinhado. Em algumas aulas mais antigas, você verá /**private*/ __foo() {um peso extra.

Eu nunca ouvi falar de desenvolvedores precedendo todos os seus métodos com sublinhados, então não posso começar a explicar o que causa isso.

Jeremy DeGroot
fonte
12
Coloco um sublinhado antes dos métodos em meus controladores, que são privados da classe e não utilizados no roteamento. Como trabalho com minha própria estrutura, isso adiciona segurança à medida que imponho a política de nenhum sublinhado principal nos nomes dos controladores nas rotas. Mas isso raramente excede 1-2 métodos por controlador.
Robert K
6
Por convenção, com perl, o método que começa com um sublinhado é privado. Mas é apenas uma convenção. De fato, esses métodos ainda são acessíveis de fora da classe.
Luc M
Os sublinhados fazem ainda menos sentido se uma classe estendida decidir tornar público o método protegido de seu pai. É um caso extremo, mas acontece. Os desenvolvedores de API também podem optar por expor um método privado como público, o que significa que eles teriam que refatorar o nome do método, além de alterar o modificador de acesso. Nada demais, mas um incômodo.
Johan Fredrik Varen
Johan - refatorar é um incômodo? Meu editor possui um recurso chamado "Localizar e substituir". Funciona bem!
DaveWalley
É uma convenção C # que você pode usar para prefixar membros privados com exatamente um sublinhado. Portanto, era uma convenção do Zend Framework 1 (2012) fazer da mesma maneira.
precisa saber é o seguinte
73

Acredito que a fonte mais autorizada para esses tipos de convenções para PHP no momento seria o PSR-2: Coding Style Guide, porque o Zend Framework faz parte do PSR :

Os nomes de propriedades NÃO DEVEM ser prefixados com um único sublinhado para indicar visibilidade protegida ou privada.

joedevon
fonte
9
Usar uma convenção de nomenclatura não é uma razão para amar um idioma, eu acho.
sepehr
4
Quando li sobre isso pela primeira vez, entendi o motivo, para que você possa analisar um método e saber se é público ou privado. O que teria feito muito mais sentido se fosse uma exigência e não uma convenção. Como se um programador em uma equipe adiciona um sublinhado onde não é necessário ou torna público um com um sublinhado, você acaba com muita confusão. Como se vê, isso veio do PHP4, como Jeremy aponta, & #ZF baseou sua convenção fora da convenção PEAR. A PEAR a removeu e acredito que o #ZF seguirá o exemplo.
joedevon
Esta resposta está correta. Está em todo o lugar maldito em Magento, e como observado por Sliq abaixo, é uma convenção que geralmente foi preterida.
Siliconrockstar 23/02
Aqui está o link atualizado sobre isso. framework.zend.com/manual/1.12/en/…
Shapeshifter
O FYI (e @joedevon) Zend 2.4 foi lançado há alguns meses e ainda usa sublinhado para framework privado e protegido.zend.com/manual/current/en/ref/… .
James
40

Agora, em 2013, isso é "oficialmente" um estilo ruim, segundo a diretriz de codificação PSR-2:

Os nomes de propriedades NÃO DEVEM ser prefixados com um único sublinhado para indicar visibilidade protegida ou privada`

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

Sliq
fonte
6
de acordo com PSR-2-> "NÃO DEVE" significar "NÃO RECOMENDAR" não proibido Isso significa que em alguns casos pode ser aceitável. PSR Doc -> ietf.org/rfc/rfc2119.txt
Ahmed Hamdy
14

Fui fortemente contra a prefixação de métodos privados / protegidos com sublinhado, pois você pode usar uma palavra-chave privada / protegida para isso e o IDE marcará isso para você.

E ainda estou, mas encontrei um motivo pelo qual pode ser uma boa prática. Imagine que você tem um método público addFoo()e, dentro desse método, você tem alguma parte da tarefa que é comum a outros métodos addFooWhenBar(), addFooWhenBaz()... Agora, o melhor nome para esse método comum seria addFoo(), mas já está sendo usado, então você deve criar algumas nome feio como addFooInternal()ou addFooCommon()ou ... mas _addFoo()o método privado parece o melhor.

umpirsky
fonte
Sim, concordou. Na verdade, eu vim aqui para ver o que os outros pensam sobre sublinhados, porque raramente os usei, e sempre parece errado, mas esse exemplo é uma vez. Também os usei para alguns casos do padrão de método de modelo em que um método público chama métodos abstratos de proteção que as crianças substituíram, o que é uma idéia semelhante. Às vezes, um método público e um método abstrato protegido que ele chama são tão semelhantes ou relacionados que nomeá-los de maneira diferente parece mais estranho do que apenas prefixar um _ ao abstrato.
John Pancoast
12

Os sublinhados principais geralmente são usados ​​para propriedades e métodos privados . Não é uma técnica que costumo empregar, mas permanece popular entre alguns programadores.

jonstjohn
fonte
10

Eu uso um sublinhado líder na classe PHP 5 que escrevo para métodos privados. É uma pequena dica visual para o desenvolvedor que um determinado membro da classe é privado. Esse tipo de dica não é tão útil ao usar um IDE que distingue membros públicos e privados para você. Peguei nos meus dias de C #. Velhos hábitos...

GloryFish
fonte
5

Acredito que sua suposição original estava correta, achei uma prática comum que alguns idiomas prefixassem um sublinhado de métodos / membros etc. que devem ser mantidos em sigilo no "objeto". Apenas uma maneira visual de dizer, embora você possa, você não deveria estar ligando para isso!

Quintin Robinson
fonte
5

Eu estava procurando a mesma resposta, fiz algumas pesquisas e acabei de descobrir que os frameworks php sugerem estilos diferentes:

Code Igniter

O manual oficial possui uma seção de estilo de codificação que incentiva essa prática :

Métodos privados e variáveis

Métodos e variáveis ​​que são acessados ​​apenas internamente, como funções de utilitário e auxiliar que seus métodos públicos usam para abstração de código, devem ser prefixados com um sublinhado.

public function convert_text()

private function _convert_text()

Outras estruturas fazem o mesmo, como

Cakephp:

faz o mesmo :

Visibilidade do membro

Use as palavras-chave privadas e protegidas do PHP5 para métodos e variáveis. Além disso, nomes de métodos ou variáveis ​​não públicos começam com um único sublinhado (_). Exemplo:

class A
{
    protected $_iAmAProtectedVariable;

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

    private $_iAmAPrivateVariable;

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

E também

PERA

faz o mesmo :

Os membros da classe privada são precedidos por um único sublinhado. Por exemplo:

$_status    _sort()     _initTree()

Enquanto

Drupal

O estilo do código alerta especificamente contra isso :

  1. Propriedades e métodos protegidos ou particulares não devem usar um prefixo de sublinhado.

Sinfonia

por outro lado, declara :

O Symfony segue os padrões definidos nos documentos PSR-0, PSR-1, PSR-2 e PSR-4.

m.ardito
fonte
Resposta muito completa.
colonelclick
4

Eu sei disso em python, onde o prefixo de suas variáveis ​​com um sublinhado faz com que o compilador traduza alguma sequência aleatória de letras e números na frente do nome da variável real. Isso significa que qualquer tentativa de acessar a variável de fora da classe resultaria em um erro "variável indefinida".

Não sei se essa ainda é a convenção a ser usada em python, embora

Mateus
fonte
3

No Drupal (um php CMS), sublinhados podem ser usados ​​para impedir que os ganchos sejam chamados ( https://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7 ).

Se eu tiver um módulo chamado "my_module" e desejar nomear uma função my_module_insert, ele "ganchará" a função hook_insert. Para impedir que eu possa renomear minha função para _my_module_insert.

ps Como o hooks funciona no Drupal, é possível implementar um hook por engano, o que é muito ruim.

maho
fonte
1
Eu considerei isso uma falha de design drupal por algum tempo. Seria mais sensato registrar explicitamente seus ganchos para evitar confusão e operação errática. A suposição é geralmente uma coisa ruim, e as construções que interferem na programação normal ou as sequestram geralmente são de arquitetura pobre.
Mpsyd
3

Drupal e usando sublinhado:

De maneira geral, o sublinhado é simples para marcar o fato de que uma função provavelmente seria chamada apenas por uma função pai 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>';
}

Claro, apenas um exemplo simples ...

user3613677
fonte
0

Usando sublinhado apenas para lembrar que não 'modificaremos a variável' / 'chamaremos a função' fora da classe.

Como declaramos variáveis ​​const em todas as letras maiúsculas, de modo que, ao ver o nome da variável, possamos adivinhar que é uma variável const. Semelhante à variável que não queremos modificar fora da classe, a declaramos com sublinhado para nossa própria convenção.

Tassawer
fonte
O que você quer dizer com "variáveis ​​const"? Como você pode definir uma constante variável?
Nico Haase
-21

Eles são chamados de "métodos mágicos" .

Tristan
fonte
39
_foo()com um único sublinhado à esquerda não é um método mágico. Os métodos mágicos são indicados por dois sublinhados principais consecutivos. A pergunta aqui fala sobre apenas um.
BoltClock