2011-11-22 46 views
11

我對PHP中的構造函數如何工作有點困惑。PHP的構造函數和靜態函數

我有一個構造函數,當我實例化一個新的對象時被調用的類。

$foo = new Foo($args); 

__construct($params)是所謂的類Foo並執行相應的初始化代碼。

但是,當我使用該類來調用一個靜態函數時,再次調用該構造函數。

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

這將導致構造函數執行,運行,我只打算當我創建一個新的Foo對象的對象初始化代碼。

我錯過了構造函數的工作原理嗎?或者當我使用該類進行靜態函數調用時,有沒有辦法阻止__construct()執行?

我應該用「工廠」函數來做對象初始化嗎?如果是這樣,那麼構造函數的重點是什麼?

::編輯:: 我有一個表格,用戶可以上傳照片到相冊(create_photo.php)和他們可以查看專輯(view_photos.php)的區域。表格提交後:

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

Photo構造函數創建並保存照片。然而在view_photo.php中,當我打電話時:

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

這是造成Photo的構造函數運行!

+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固定^ _ ^很好的捕獲 – Neal

6

假設 PHP 5。因爲我們創建了一個新的對象PHP調用X

不同的目標,不同的路徑

  1. 創建一個類(對象)的新實例

    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 hasl在課堂內部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)第一次,我們構造具有$ PAR集到一個新的對象gino

第二次使用該工廠$單身已經有一個我們返回的值。沒有創建新對象(沒有調用__construct,使用更少的內存& cpu)。

課程的值是一個對象}這種 myClassA不要忘記:

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

講究單身:

What is so bad about singletons?

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

通過我的答案如果我不想提升/降級單身人士。只需從問題中的單詞,我做了這個計算:

「static」+「__ construct」=「singleton」!

+0

你應該添加關於singletons ans tatic類的免責聲明: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」。不是gine和pino,因爲構造函數只運行一次! – Miguel

1

這裏是我的解決辦法

我把方法construct()在靜態類。請注意,它與我在常規課程中使用的__construct()不同。

每個類都在自己的文件中,所以我首次使用類時會延遲加載該文件。這給了我第一次使用類的事件。

spl_autoload_register(function($class) { 

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

    if (method_exists($class, 'construct')) { 
     $class::construct(); 
    } 
});