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)の古き良き時代のものです。そのOOの実装はかなり悪かったため、プライベートメソッドなどは含まれていませんでした。これを補うために、PHP開発者は、アンダースコアを使用して非公開にすることを目的としたメソッドを前置きしました。いくつかの古いクラスでは/**private*/ __foo() {、いくつかの追加の重みを与えることがわかります。

開発者がすべてのメソッドの前にアンダースコアを付けるのを聞いたことがないので、その原因を説明することはできません。


12
私は、クラスでプライベートであり、ルーティングで使用されていないコントローラーのメソッドの前にアンダースコアを配置します。私は独自のフレームワークを使用しているため、ルート内のコントローラー名に先行アンダースコアを付けないというポリシーを適用することで、これによりセキュリティが追加されます。ただし、これがコントローラあたり1-2のメソッドを超えることはめったにありません。
Robert K

6
慣例により、perlでは、アンダースコアで始まるメソッドはプライベートです。しかし、それは単なる慣例です。実際、これらのメソッドはクラスの外部からもアクセスできます。
Luc M

拡張クラスが親の保護されたメソッドをパブリックにすることを決定した場合、アンダースコアはさらに意味がありません。それはエッジケースですが、それは起こります。API開発者は、プライベートメソッドをパブリックとして公開することもできます。つまり、アクセス修飾子を変更することに加えて、メソッド名をリファクタリングする必要があります。大したことはありませんが、それでも迷惑です。
Johan Fredrik Varen 2017

ヨハン-リファクタリングは厄介ですか?私のエディタには「検索と置換」という機能があります。よく働く!
DaveWalley 2017年

これは、プライベートメンバーの前に1つのアンダースコアを付けるために使用できるC#の規則です。したがって、同じ方法で行うのはZend Framework 1(2012)の慣習でした。
alpham8

73

Zend FrameworkはPSRの一部であるため、現時点でのPHPのこれらの種類の規則の最も信頼できるソースは、PSR-2:Coding Style Guideであると考えています。

保護された、またはプライベートな可視性を示すために、プロパティ名の前に単一の下線を付けることはできません。


9
命名規則を使用することは、言語を愛する理由ではないと私は思います。
sepehr

4
これについて初めて読んだとき、その理由を理解して、メソッドを見て、それがパブリックかプライベートかを確認できるようにしました。慣習というよりも要件であるならば、それはまったく意味のあることだったでしょう。チームの1人のプログラマが不要な場所にアンダースコアを追加したり、アンダースコアを使用して公開したりすると、混乱が生じます。結局のところ、Jeremyが指摘するように、これはPHP4からのものであり、&#ZFはPEARの規則に基づいた規則に基づいています。PEARはそれを削除したので、#ZFもそれに続くと思います。
joedevon

この答えは正しいです。それはMagentoのいまいましい場所の至る所にあり、以下のSliqで言及されているように、それは一般的に非推奨となっている規約です。
Siliconrockstar、2015

これに関する更新されたリンクは次のとおりです。framework.zend.com/manual/1.12/en/...
多相の戦士

FYI(および@joedevon)Zend 2.4は数か月前にリリースされましたが、プライベートおよび保護されたFramework.zend.com/manual/current/en/ref/…にはまだアンダースコアが使用されています。
James

40

さて、2013年には、これはPSR-2コーディングガイドラインによる「公式に」悪いスタイルです。

プロパティ名には、保護またはプライベートの可視性を示すために、単一のアンダースコアをプレフィックスとして付けないでください `

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


6
よるとPSR-2- >平均おすすめ「NOT」「SHOULD NOTは」いくつかのケースでは平均が許容することができることを禁じられていません。PSR Doc-
ahmed hamdy

14

プライベート/保護されたメソッドの前にアンダースコアを付けることには強く反対しました。プライベート/保護されたキーワードを使用でき、IDEがマークを付けてくれるからです。

そして、私はまだですが、良い実践になり得る理由を見つけました。あなたが公共のメソッドを持っていることを想像addFoo()し、そのメソッド内で使用すると、他の方法と共通であるタスクの一部を持ってaddFooWhenBar()addFooWhenBaz()今...、その一般的な方法のための最高の名前は次のようになりますaddFoo()が、あなたは、いくつかを考え出す必要がありますので、それはすでに、取られますaddFooInternal()or addFooCommon()または...のような醜い名前ですが、_addFoo()privateメソッドは最適な方法のように見えます。


ええ、同意しました。私は実際にここに来て、他の人がアンダースコアについて考えたことを確認しました。私がそれらを使用することはほとんどなく、それは常に間違っていると感じているからです。また、テンプレートメソッドパターンのいくつかのケースでそれらを使用しましたが、パブリックメソッドが、子がオーバーライドした保護された抽象メソッドを呼び出す場合も同様です。ときどき、パブリックメソッドとそれが呼び出す抽象保護メソッドが非常に似ているか関連しているため、抽象メソッドの前に_を付けるだけでは、名前の付け方が変わって見える場合があります。
ジョンパンコースト2017

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()

ながら

Drupal

コードスタイルは特にこれに対して警告します

  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という名前を付けたい場合は、関数hook_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変数」とはどういう意味ですか?変数である定数をどのように定義できますか?
ニコHaase

-21

それらは"マジックメソッド"と呼ばれます。


39
_foo()単一の先行アンダースコアを使用することは、魔法の方法ではありません。マジックメソッドは、2つの連続する先行アンダースコアで示されます。ここでの質問は1つだけについて話します。
BoltClock
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.