2011-11-22 23 views
11

PHPでコンストラクタがどのように動作するのかちょっと混乱します。PHPのコンストラクタと静的関数

私は、新しいオブジェクトをインスタンス化するときに呼び出されるコンストラクタを持つクラスを持っています。

$foo = new Foo($args); 

__construct($params)Fooクラスで呼び出されると、適切な初期化コードを実行します。

しかし、クラスを使用して静的関数を呼び出すと、コンストラクタが再度呼び出されます。

$bar = Foo::some_function(); //runs the constructor from Foo 

は、これは私が新しいFooオブジェクトを作成するときのためにのみ意図されたオブジェクトの初期化コードを実行し、コンストラクターが実行させます。

コンストラクタの動作のポイントがありませんか?または、静的関数呼び出しを行うためにクラスを使用するときに__construct()が実行されないようにする方法がありますか?

オブジェクト初期化の代わりに「ファクトリ」関数を使用する必要がありますか?もしそうなら、コンストラクタのポイントは何ですか?

:: EDIT :: 私は、ユーザーが写真をアルバム(create_photo.php)とアルバムを見ることができる領域(view_photos.php)にアップロードできるフォームを持っています。フォーム提出時:

$photo = new Photo($_FILES['photo'], $_POST['arg1'], ect..); 

フォトコンストラクタが写真を作成して保存します。しかし、view_photo.phpで、私が電話すると:

$photo = Photo::find_by_id($_POST['id']) //user-defined function to query database 

これは、写真のコンストラクタを実行させています!

+8

これは正しいものではありません。静的呼び出しによってコンストラクタが呼び出される完全なコードを提供してください! – mAu

+0

実際のコードを表示してください。あなたが書いているものが正しいとは思わない。 –

+0

コンストラクタはどのように見えますか、どの動作から実行すると結論付けていますか? – markus

答えて

16

あなたの質問を複製するものは何もありません。

参照デモ:http://codepad.org/h2TMPYUV

コード:

class Foo { 
    function __construct(){ 
     echo 'hi!'; 
    } 
    static function bar(){ 
     return 'there'; 
    } 
} 

echo Foo::bar(); //output: "there" 
+2

それは '__construct()'ではいけませんか?結果は同じですが... – jeroen

+0

@jeroen fixed^_^nice catch – Neal

6

仮定 PHP 5。X

異なる目標、異なるパス

  1. 私たちは、新しいオブジェクトのPHPの呼び出しを作成するので(オブジェクト)

    class myClassA 
    { 
        public $lv; 
    
        public function __construct($par) 
        { 
         echo "Inside the constructor\n"; 
         $this->lv = $par; 
        } 
    } 
    
    $a = new myClassA(11); 
    $b = new myClassA(63); 
    

    をクラスの新しいインスタンスを作成します。

    __construct($par)を。新しいオブジェクトの

    、そう:

    $a->lv == 11 
    
    $b->lv == 63 
    
  2. class myClassB 
    { 
        public static $sv; 
    
        public static function psf($par) 
        { 
         self::$sv = $par; 
        } 
    } 
    
    myClassB::psf("Hello!"); 
    $rf = &myClassB::$sv; 
    myClassB::psf("Hi."); 
    

    は現在$rf == "Hi."

    機能またはvariabilesが::によってアクセスされる静的に定義しなければならないクラスの関数を使用し、 "psf"を呼び出すオブジェクトが作成されず、 "クラス変数" svにはonlクラス内のy 1インスタンス。工場を使用して

  3. (myClassAは上記です)工場で作成されたシングルトンを使用

    class myClassC 
    { 
    
        private static $singleton; 
    
        public static function getInstance($par){ 
    
         if(is_null(self::$singleton)){ 
    
          self::$singleton = new myClassA($par); 
    
         } 
    
         return self::$singleton; 
    
        } 
    
    } 
    
    $g = myClassC::getInstance("gino"); 
    echo "got G\n"; 
    
    $p = myClassC::getInstance("pino"); 
    echo "got P\n"; 
    

のgetInstanceは)我々が$パーセットを持つ新しいオブジェクトを構築する最初の時間ジノ

工場を2回目に使用する$ singletonには、すでに返されている値があります。新しいオブジェクトは作成されません(__constructが呼び出され、メモリが少なくなります&cpuが使用されます)。

もちろんの値はmyClassA INSTANCEOFオブジェクトで、忘れないでください:シングルトンへ

myClassC::$singleton->lv == "gino"

ご注意:

What is so bad about singletons?

http://www.youtube.com/watch?v=-FRm3VPhseI

をすることで私のans私はシングルトンを昇格/降格させたくありません。単に質問の言葉から、私はこの計算を作った:

"static" + "__ construct" = "singleton"!私は静的クラスでメソッドconstruct()を入れ

+0

シングルトンやクラスに関する免責事項を追加してください:http://stackoverflow.com/questions/137975/what-is-so-bad -about-singletonsとhttp://www.youtube.com/watch?v=-FRm3VPhseI –

+0

$ g = myClassC :: getInstance( "gino");次に$ p = myClassC :: getInstance( "pino"); 、$ g-> lvおよび$ p-> lvの値は同じ= "gino"です。ジンとピノではない。コンストラクタは一度だけ実行されるからだ! – Miguel

1

は、ここに私の回避策です。注目すべきは、通常のクラスで使用する__construct()とは異なります。

各クラスは独自のファイルになっていますので、クラスの最初の使用時にそのファイルを読み込みません。これは、クラスの最初の使用のイベントを私に与える。

spl_autoload_register(function($class) { 

    include_once './' . $class . '.php'; 

    if (method_exists($class, 'construct')) { 
     $class::construct(); 
    } 
}); 
関連する問題