web-dev-qa-db-ja.com

PHPで静的変数/関数を使用するのはいつですか?

OOP with PHPで自分自身をリフレッシュし、関数や変数を静的に設定する例を見ました。いつ/なぜ変数/他の言語でやったことがありますが、実際に静的を使用したことを思い出すことはありませんが、実際の目的は見つかりませんでした。

71
iaddesign

インスタンスに関連付けられていないメソッド/変数を使用する場合は、staticを使用します。次の場合に発生する可能性があります。

  • あなたの目的やインスタンスとは何の関係もありません(JavaのようなOOPであるが、PHPでは役に立たない)を許可しない言語のツールボックスに役立ちます)。

  • インスタンスへのアクセスを制御します。ほとんどの場合、処理するインスタンスはコードを記述するときに定義されず、実行時になります。 シングルトンパターン が最良の例です。静的メソッドをファクトリーとして使用して、コンテキストに従ってオブジェクトを作成したり、リソースを他のインスタンスと共有したりできます。 E.G:静的メンバーはデータベースレイヤーへのアクセスを許可できるため、アプリの一部はどこからでも同じレイヤーにアクセスし、競合なしに開いたり閉じたりします。

  • パフォーマンスが重要であり、メソッドは何度も実行されます。その場合、インタープリターが各呼び出しでインスタンスのメンバーを検索することを防ぐために、CPU時間をいくらか節約します。ただし、perfsがこのソリューションに来るような問題になった場合は、アーキテクチャを再考するか、コードの重要な部分に高速言語へのバインディングを使用する必要があります。

  • 型に関連するメソッドがありますが、別のメソッドに適用されます。メソッドを最初の型の宣言に書き込むことは理にかなっていますが、別の型のインスタンスを予期するため、静的に設定します。

完璧な例はStringパーサーです:

class MyObject 
{
 static function parse($str)
 {
    $obj = new MyObject();
    // some parsing/setting happens here
    return $obj;
 }
}

// you create an object "MyObject" from a string, so it's more obvious
// to read it this way :
$new_obj = MyObject::parse("This a description of a super cool object");
55
e-satis

静的関数と変数は、次のようにグローバルスコープの変数/関数にアクセスするために使用されます。

_echo myClass::myVariable;
echo myClass::myFunction();
_

静的なものはどこからでもアクセスでき、手続き型関数に非常に似ていますが、selfを使用でき、クラススコープに含まれている点が異なります。

_class myClass{
    static $myVariable = "myVar";
    static function myFunction()
    {
       return "myFunc";
    }
}
_

これを使用する方法の1つは、クラスまたはシングルトンメソッドのインスタンスを1つだけ保持することです。

_class myClass
   {
    static $class = false;
    static function get_connection()
    {
        if(self::$class == false)
        {
            self::$class = new myClass;
        }
        else
        {
            return self::$class;
        }
    }
    private function __construct()
    {
         // my constructor
    }
    // Then create regular class functions.
   }
_

プライベートコンストラクターがあるため、new演算子でインスタンス化できないため、myClass::get_connection()を呼び出してクラスを取得する必要があります。その関数は(クラスのメンバーであるため)新しいクラスを作成できます。次に、クラスを静的変数に格納し、関数を再度呼び出すと、作成されたクラスが返されます。

最終的に、静的キーワードは、スコープに関して物事を静的に保つために使用されます。これは、現在のスコープのために「変更」するものが何もないことを意味します。 Singletonメソッドはこれを少し拡張しますが、どのスコープにいても、常に「同じ」クラスを持っているという同じ考えを保持しています。

PHPドキュメント
静的キーワード
スコープ解決演算子

StackOverflowナレッジ
PHP Global Objects の使用を避ける方法
PHPグローバルを使用せずに関数間で変数を共有する
クラス内のすべての関数でアクセス可能なグローバル変数の作成
データベース接続のグローバルまたはシングルトン
PHPクラス:使用する場合:: vs.->?

22
Tyler Carter

また、メソッドが非常に頻繁に呼び出され、同じことを行う場合、キャッシングに非常に役立ちます。たとえば、

/**
 * Returns true if the user is logged in through shibboleth
 *
 * @return boolean true on success, else false
 */
protected function is_logged_in() {

    //Check shibboleth headers
    if (!empty($_SERVER['HTTP_SHIB_IDENTITY_PROVIDER']) || !empty($_SERVER['Shib-Identity-Provider'])) {
        if (!empty($_SERVER[$this->core->dbconfig("shib_auth", self::SHIB_AUTH_CONFIG_UID)])) {
            return true;
        }
    }
    return false;
}

このメソッドはフレームワーク内で非常に頻繁に呼び出され、すべての呼び出しに対して、構成$ _SERVERキーのデータベースルックアップを実行します

そのため、ページが処理されている間、1ページのロードで10回呼び出すことがありますが、データベース呼び出しは10回ありますが、次のように変更しました:

/**
 * Returns true if the user is logged in through shibboleth
 *
 * @return boolean true on success, else false
 */
protected function is_logged_in() {
    static $logged_in = null;
    if($logged_in != null) {
        return $logged_in;
    }

    //Check shibboleth headers
    if (!empty($_SERVER['HTTP_SHIB_IDENTITY_PROVIDER']) || !empty($_SERVER['Shib-Identity-Provider'])) {
        if (!empty($_SERVER[$this->core->dbconfig("shib_auth", self::SHIB_AUTH_CONFIG_UID)])) {
            $logged_in = true;
            return true;
        }
    }
    $logged_in = false;
    return false;
}

そのため、ログインして結果をキャッシュする場合、通常の動作を一度だけすべてのページの読み込みをチェックします。次回はキャッシュされた値を返すだけです。この機能は、パフォーマンスを向上させるために頻繁に使用します。

お役に立てれば。

10
prdatur

ただし、ここにランダムがあります 静的メソッドとインスタンスメソッドの違いのかなり良い説明

投稿から:

インスタンスメソッドは、特定のオブジェクトインスタンスの状態に依存するため、インスタンスメソッドです。インスタンスメソッドは、メソッドが呼び出す動作がその特定のインスタンスの状態に依存するため、特定のインスタンスに関連付けられています。

メソッドを静的として宣言する場合、そのメソッドをクラスメソッドとして定義します。クラスメソッドは、特定のインスタンスではなく、クラスに適用されます。クラスメソッドによって引き起こされる動作は、特定のインスタンスの状態に依存しません。実際、静的メソッドはこの参照にアクセスできないため、静的メソッドはインスタンスの状態に依存できません。代わりに、クラスメソッドの動作は、すべてのオブジェクトがクラスレベルで共有する状態に依存するか、すべての状態にまったく依存しません。

メソッドがオブジェクトインスタンスの状態に依存する場合、インスタンスメソッドである必要があります。メソッドがクラスのすべてのインスタンスに対して一般的であるか、オブジェクトの状態に依存しない場合、メソッドは静的メソッドである必要があります。インスタンスメソッドが最も一般的に使用されます。ただし、静的メソッドは、ユーティリティクラスやファクトリクラスにとって、他の多くの用途に非常に役立ちます。

7
lance

一般的に静的関数を使用すると、速度だけでなくメモリも最適化でき、メソッドのスコープを変更しないでください。本質的に静的である必要があり、オブジェクトの静的プロパティ、メソッドを開始せずにアクセスできるため、平均してメモリを節約できます。

3
ujwal dhakal

静的要素には、有用な多くの特性があります。

  1. まず、スクリプト内のどこからでも利用できます(クラスにアクセスできると仮定)。つまり、クラスのインスタンスをオブジェクトからオブジェクトに渡したり、さらに悪いことに、インスタンスをグローバル変数に保存したりする必要なく、機能にアクセスできます。

  2. 次に、クラスのすべてのインスタンスで静的プロパティを使用できるため、型のすべてのメンバーが使用できるようにする値を設定できます。

  3. 最後に、静的プロパティまたはメソッドにアクセスするためにインスタンスが必要ないという事実は、単純な関数を取得するためにオブジェクトをインスタンス化することからあなたを救うことができます。

1
Dhairya Lakhera

現在の実行で作成されたインスタンスの数のカウンターなど、すべてのインスタンスでデータを共有する場合。

0
palash140

訪問: http://verraes.net/2014/06/when-to-use-static-methods-in-php/

静的メソッドは、名前空間付きグローバル関数にすぎません。名前空間は、私たち全員が同意できると思いますが、素晴らしいです。グローバル関数については、常にそれらを使用します。 PHP=のネイティブ関数は、基本的な構成要素を形成します。

0
Hamm