2011-10-17 50 views
6

Tôi đang làm việc trên một dự án mà tôi muốn có thể khai báo một biến thành viên tĩnh bên trong một lớp cơ sở trừu tượng. Tôi đã có một lớp Model, một lớp bài trung gian, và cuối cùng là một bài viết lớp trang web cụ thể, giống như sau:Biến tĩnh PHP trong lớp trừu tượng

abstract class Model { 
    protected static $_table = null; 
    protected static $_database = null; 

    ... 
} 

abstract class PostModel extends Model { 
    public function __construct() { 
     if (!isset(self::$_table)) { 
      self::$_table = 'some_table'; 
     } 

     parent::__construct(); 
    } 

    ... 
} 

class SitePostModel extends PostModel { 
    public function __construct() { 
     if (!isset(self::$_database)) { 
      self::$_database = 'some_database'; 
     } 

     parent::__construct(); 
    } 

    ... 
} 

Tôi muốn làm cho nó rõ ràng từ lớp Mẫu rằng $ _table và các thành viên $ _database là bắt buộc. Tuy nhiên, $ _table thực sự là tĩnh từ quan điểm của lớp PostModel, và $ _database thực sự là tĩnh từ quan điểm của lớp SitePostModel.

Đây có phải là cách hợp pháp để hoàn thành mục tiêu của tôi không? Việc khai báo các biến tĩnh trong Bản thân mô hình có ngụ ý rằng chúng chỉ tồn tại một lần cho lớp cơ sở trừu tượng, hay chỉ một lần cho lớp khởi tạo thực tế?

+4

* (tham chiếu) * [chương về từ khóa 'static'] (http://php.net/manual/en/language.oop5.static.php) và [chương về Binding tĩnh muộn] (http : //php.net/manual/en/language.oop5.late-static-bindings.php). – Gordon

+2

Đối với việc này là hợp pháp hay ngụ ý bất cứ điều gì, tôi muốn nói điều này là đối tượng tranh luận. IMO, bạn không nên sử dụng Thừa kế ở đây cả. Ngoài ra, Mô hình thường không ngụ ý cơ sở dữ liệu. – Gordon

+0

Tôi đánh giá cao đầu vào @Gordon. Tôi nghĩ 'Mô hình không ngụ ý cơ sở dữ liệu' là đủ để thuyết phục tôi không đối xử với các thành viên theo cách này. Trong tương lai gần, lớp Model này sẽ chỉ mô hình hóa các bảng cơ sở dữ liệu, nhưng nó có thể không phải lúc nào cũng như vậy. – michaelxor

Trả lời

1

Đây có phải là cách hợp pháp để hoàn thành mục tiêu của tôi không?

No. Nó không hoạt động, vì vậy nó không kiểm tra cơ bản cho tính hợp pháp.

Không khai báo các biến tĩnh trong chính Mô hình ngụ ý rằng chúng chỉ tồn tại một lần cho lớp cơ sở trừu tượng, hoặc chỉ một lần cho lớp khởi tạo thực tế?

Biến tĩnh là toàn cục, chúng tồn tại một lần. Trong trường hợp của bạn cho mỗi tên lớp. Nếu bạn có ba tên lớp, bạn sẽ có ba biến (toàn cầu). Các từ khóa được bảo vệ chỉ kiểm soát khả năng hiển thị/phạm vi của ba biến tĩnh:

<?php 

class A { 
    protected static $v = 'red'; 
    public static function get() { return self::$v . ' - ' . static::$v;} 
} 

class B extends A { 
    protected static $v = 'blue'; 
} 

class C extends B { 
    protected static $v = 'green'; 
} 

echo C::get(); # red - green 
+0

Xin lỗi vì phản ứng muộn (cực kỳ), nhưng tôi chỉ muốn làm rõ. Bạn đã nói rằng giải pháp của tôi sẽ không hoạt động. Trong thực tế, tôi đã thực hiện lời khuyên của @ Gordon từ phía trên, và tôi đã chuyển các biến $ _table và $ _database ra khỏi lớp Model chung; tuy nhiên, nếu tôi đã để lại mã như được hiển thị ở trên, tôi vẫn có thể sử dụng static :: $ _ database và static :: $ _ table trong các hàm save()/load() cho Model và lấy 'some_table' và 'some_database,' như ví dụ của bạn cho thấy. SitePostModel :: save() thực sự sẽ hoạt động chính xác và sẽ là duy nhất từ ​​SomeOtherSitePostModel :: save(), no? – michaelxor

+0

"Đây có phải là cách hợp pháp để hoàn thành mục tiêu của tôi không? Không. Nó không hoạt động, do đó, nó không kiểm tra cơ bản cho tính hợp pháp." -> Rực rỡ;) – Mirko

0

Gần đây tôi đã chạy vào cùng một vấn đề và đến cùng một giải pháp - đưa các thiết lập vào biến tĩnh và truy cập chúng bằng cách sử dụng từ khóa tĩnh. Nó cũng hoạt động trong trường hợp bạn có cài đặt mặc định (chẳng hạn như số hàng trên mỗi trang) mà bạn có thể muốn ghi đè trong các lớp con. Điều này có vẻ giống như cách trực quan và hiệu quả nhất.

Alternatives Tôi đã xem xét:

  • Sử dụng một hàm getter trừu tượng tĩnh. Nó đòi hỏi nhiều dòng mã hơn và nhiều chức năng hơn.
  • Giữ cài đặt trong biến thành viên không tĩnh và để cho hàm tạo lớp con lo lắng về nó. Tôi từ chối tùy chọn này bởi vì các lớp con của tôi không cần một hàm tạo khác.
Các vấn đề liên quan