2011-11-22 46 views
11

Tôi hơi bối rối về cách các hàm tạo hoạt động trong PHP.Các hàm tạo PHP và hàm tĩnh

Tôi có một lớp với một hàm tạo được gọi khi tôi khởi tạo một đối tượng mới.

$foo = new Foo($args); 

__construct($params) được gọi trong lớp Foo và nó thực thi mã khởi tạo thích hợp.

Tuy nhiên khi tôi sử dụng lớp để gọi hàm tĩnh, hàm tạo được gọi lại.

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

Điều này làm cho hàm tạo thực thi, chạy mã khởi tạo đối tượng mà tôi chỉ định khi tạo đối tượng Foo mới.

Tôi có thiếu điểm của cách các nhà thầu hoạt động không? Hoặc có cách nào để ngăn không cho __construct() thực thi khi tôi sử dụng lớp để thực hiện cuộc gọi chức năng tĩnh không?

Tôi có nên sử dụng chức năng "nhà máy" thay vì thực hiện khởi tạo đối tượng không? Nếu vậy, điểm của nhà xây dựng là gì?

:: EDIT :: Tôi có một biểu mẫu nơi người dùng có thể tải ảnh lên album (create_photo.php) và khu vực nơi họ có thể xem album (view_photos.php). Khi gửi biểu mẫu:

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

Trình tạo ảnh tạo và lưu ảnh. Tuy nhiên, trong view_photo.php, khi tôi gọi:

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

Điều này khiến cho trình tạo ảnh của bạn chạy!

+8

Điều đó không đúng. Vui lòng cung cấp mã đầy đủ nơi hàm tạo được gọi bằng một cuộc gọi tĩnh! – mAu

+0

Hiển thị mã thực của bạn. Những gì bạn đang viết không chính xác. –

+0

Làm thế nào để các nhà xây dựng trông giống như, từ những hành vi nào bạn kết luận rằng nó chạy? – markus

Trả lời

16

Tôi không thấy gì lặp lại câu hỏi của bạn.

Xem Demo: http://codepad.org/h2TMPYUV

Code:

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

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

Không nên là '__construct()'? Kết quả là như nhau mặc dù ... – jeroen

+0

@jeroen cố định^_^đẹp bắt – Neal

6

Assumption PHP 5.x

mục tiêu khác nhau, con đường khác nhau

  1. tạo một đối tượng mới của một lớp (đối tượng)

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

    bởi vì chúng tôi tạo ra một cuộc gọi mới đối tượng PHP:

    __construct($par);

    của đối tượng mới, vì vậy:

    $a->lv == 11 
    
    $b->lv == 63 
    
  2. sử dụng một chức năng của một lớp

    class myClassB 
    { 
        public static $sv; 
    
        public static function psf($par) 
        { 
         self::$sv = $par; 
        } 
    } 
    
    myClassB::psf("Hello!"); 
    $rf = &myClassB::$sv; 
    myClassB::psf("Hi."); 
    

    tại $rf == "Hi."

    chức năng hoặc variabiles phải được xác định tĩnh để được truy cập bởi ::, không có đối tượng nào được tạo ra gọi là "psf", "biến lớp" sv có onl y 1 dụ bên trong lớp.

  3. sử dụng một singleton tạo ra bởi một nhà máy (myClassA là ở trên)

    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"; 
    

Sử dụng nhà máy (getInstance) lần đầu tiên chúng ta xây dựng một đối tượng mới có $ mệnh thiết lập để gino.

Sử dụng nhà máy lần thứ hai $ singleton đã có giá trị mà chúng tôi trả lại. Không có đối tượng mới nào được tạo (không có __construct được gọi, ít bộ nhớ hơn & cpu được sử dụng).

Giá trị dĩ nhiên là một đối tượng instanceof myClassA và đừng quên: sự chú ý

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

Pay để độc thân:

What is so bad about singletons?

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

Bằng ans của tôi Tôi không muốn quảng bá/giảm hạng singleton. Chỉ cần từ các từ trong câu hỏi, tôi đã thực hiện phép tính này:

"tĩnh" + "__ construct" = "singleton"!

+0

bạn nên đã thêm một tuyên bố từ chối trách nhiệm liên quan đến singletons ans tatic classes: http://stackoverflow.com/questions/137975/what-is-so-bad -about-singletons và http://www.youtube.com/watch?v=-FRm3VPhseI –

+0

chỉ để làm rõ $ g = myClassC :: getInstance ("gino"); và sau đó $ p = myClassC :: getInstance ("pino"); , giá trị $ g-> lv và $ p-> lv giống nhau = "gino". không phải gine và pino, bởi vì hàm tạo chỉ chạy một lần! – Miguel

1

Đây là tôi workaround:

tôi đặt phương pháp construct() trong lớp tĩnh. Chú ý, nó khác với __construct() mà tôi sử dụng trong các lớp thông thường.

Mỗi lớp có tệp riêng, vì vậy tôi tải tệp đó lên lần đầu tiên sử dụng lớp học.Điều này mang lại cho tôi sự kiện sử dụng đầu tiên của lớp học.

spl_autoload_register(function($class) { 

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

    if (method_exists($class, 'construct')) { 
     $class::construct(); 
    } 
}); 
Các vấn đề liên quan