12

PHP 5.3+

長い質問で申し訳ありませんが、これを完全に学びたいです。

クラスをオブジェクトとしてインスタンス化せずに、静的メソッド内から非静的の同じクラスメソッドを呼び出すことはできないことを私は知っています。

class Person 
{
    private $people_array;

    function data_all_get()
    { // touch database, return array of people
      $this->people_array = // etc dbquery results
    }

    static function showPeople()
    {  // call class method
       $people_data = $this->data_all_get();
       // Fatal error: Using $this when not in object context
    }
} // end class Person

SO を検索したところ、興味深いアプローチがいくつか見つかりましたが、それぞれのアプローチがコード環境にどのように影響するのか疑問に思っていました。

私の質問は以下のとおりです。

クラスを静的メソッド内のオブジェクトとしてインスタンス化して、非静的メソッドにアクセスすることができます

static function showPeople()
{  // instantiate as object
   $person = New Person();
   // call class method
   $people_data = $this->data_all_get();
}

Q1 - これによりどのような問題が発生する可能性がありますか? 私の状況では、クラスにはコンストラクターがないため、他のクラス メソッドや変数はインスタンスの影響を受けません。この新しいオブジェクトは、スクリプトの実行中にメモリ内のスペースを少し占有するだけでしょうか? 悪くないようです...


もう1つのオプションは、「data_all_get」メソッドを静的メソッドに変換することです。これにより、静的メソッド「showPeople」内から呼び出すことができます。

self::showPeople()

「data_all_get」メソッドは、プライベート var の値を設定するために、すでに設定されている場合はデータベースへのトリップを減らすために、オブジェクトとしてインスタンス化されるときに、クラス内の他のメソッドによって使用されています。これはおそらくコンストラクター関数の一部である可能性があることはわかっていますが、この「Person」オブジェクトをphpスクリプトリクエストごとに複数回インスタンス化する必要はありません。クラスは主に、関数と変数をグループ化して編成するために使用されます.. .

Q2 - 「data_all_get」を静的メソッドにすることの意味は何ですか? いずれかがあります?メソッドが静的であるが、プライベート var $people_array (静的ではない) の値を設定する場合、オブジェクトを一度に 2 回インスタンス化する必要がある場合、var を更新または上書きできると思います。スクリプト リクエストですね。さらに、プロパティは静的ではないため、クラスの他のメソッドがアクセスできます。

Q3 - 静的メソッド「data_all_get」を「何も壊さずに」何度でも呼び出すことができますか (読み込まれた質問 IK)。

Q4 - 静的メソッドが呼び出されるたびに追加のメモリを使用するだけですか?

ありがとうございました

4

1 に答える 1

13
class Person 
{
    private static $people_array;

    static public function data_all_get()
    { 
         self::$people_array = //DBStuff
    }

    static public function showPeople()
    {  
        $people_data = self::data_all_get();
    }
 }

ほんの少しのメモ、おそらく明らかなものもあります。1)何も返さないので、明らかに上記のコードは失敗します。言うまでもなく、上記のコードには何の問題もありません。Q1 への回答として、グローバル変数を使用して関数呼び出しのペアを取得し、それらをクラス内にカプセル化しただけです。これをインスタンス化されたクラスとして使用したり、使用しないことをお勧めします。最終的なコードが読みにくくなり、人々がそれを見ているときに理解するのが難しくなるためです。

これを複数回インスタンス化することが心配な場合は、シングルトン デザイン パターンを参照することをお勧めしますが、一般に、ある時点でクラスをインスタンス化する予定がある場合は、これらを静的に呼び出す理由を再検討します。そもそも。私にとって「気分が悪い」ことを除いて、言うまでもなく、それには何も問題はありません。

Q2) data_all_get を静的配列にすることの唯一の意味は、静的プロパティを参照していることです。これは、インスタンス化された場合、このプロパティにアクセスできなくなることを意味します。また、このクラスの複数のバージョンをインスタンス化する機能を失い (それが重要な場合)、基本的に people_array をグローバル変数に変えています。それは必ずしも悪いことではありませんが、残りの機能が何をしているのかを知らなければ、その意味を知ることは困難です。

Q3) 複数回実行する唯一の問題は、A) people 配列にあるものを一掃すること、および B) 複数の DB 呼び出しです。他のコードがどのようなものであるかを確認しないと、この質問に答えることはほぼ不可能です。

Q4) ここにリストされているサイズのメソッドのメモリは、話す価値がないという点で無視できます。問題は、DB 呼び出し自体と、そこでアクセスされている行数です。

最後に、showPeople は data_all_get とまったく同じことを行うため、このコードを今書いているのは少し奇妙です。$people_array が空かどうかを確認するロジックを showPeople 内に記述し、空である場合は data_all_get を実行し、そうでない場合は people_array を返します。これにより、追加の DB 読み取りが回避されます。とにかく毎回DBを読みに行くなら、data_all_getが$people_arrayを返すようにすることもできます。その場合、これはクラス内にある必要はありません。 dbで見つけます。

于 2012-10-24T15:28:33.300 に答える