2009-08-05 15 views
6

Tôi có một lớp cơ sở dữ liệu, trong đó một trường hợp được khai báo trong chính index.php nhưTôi có thể biến một biến toàn cầu có thể nhìn thấy mà không cần phải khai báo biến toàn cục trong mỗi hàm dựng của lớp PHP không?

$db = new Database(); 

Có cách nào cho biến $db để được công nhận trên toàn cầu trong tất cả các lớp khác mà không cần phải khai báo

global $db; 

trong hàm tạo của mỗi lớp?

+0

Bạn có thực sự cần nó cho tất cả các lớp khác không? –

+0

Không phải tất cả, nhưng một số lượng đáng kể. –

Trả lời

16

No. Bạn phải khai báo Global $ db trong hàm tạo của mỗi lớp.

hoặc bạn có thể sử dụng mảng Toàn cầu: $ _GLOBALS ['vars'];

Cách duy nhất để giải quyết vấn đề này là sử dụng lớp tĩnh để bọc nó, được gọi là Singleton Method (Xem Here để được giải thích). Nhưng đây là thực hành rất tệ.

class myClass 
    { 
    static $class = false; 
    static function get_connection() 
    { 
     if(self::$class == false) 
     { 
      self::$class = new myClass; 
     } 
     else 
     { 
      return self::$class; 
     } 
    } 
    // Then create regular class functions. 
    } 

Phương pháp singleton được tạo để đảm bảo chỉ có một phiên bản của bất kỳ lớp nào. Nhưng, bởi vì mọi người sử dụng nó như là một cách để tắt globalling, nó trở nên được gọi là lập trình lười biếng/xấu.

StackOverflow Kiến thức
How to Avoid Using PHP Global Objects
Share Variables Between Functions in PHP Without Using Globals
Making a Global Variable Accessible For Every Function inside a Class
Global or Singleton for Database Connection

+0

Tại sao lại là downvote? –

+0

Tôi e ngại rằng phương pháp Singleton không phải là câu trả lời đúng cho điều này. Nhưng tôi đã bao gồm nó bởi vì nó 'kỹ thuật' có thể được sử dụng. –

+0

Tôi không phải là người bỏ phiếu xuống, cảm ơn vì đã cho tôi biết - Tôi muốn tránh những thói quen xấu. –

1

bạn có thể sử dụng

$GLOBALS['db']->doStuff(); 

hoặc cách khác sử dụng một số loại phương pháp truy cập singleton

Database::getInstance()->doStuff(); 
+0

Có phải một trong những phương pháp xấu đó không? Cách tốt nhất để khai báo lớp cơ sở dữ liệu là toàn cục trong mỗi lớp? –

0

Bạn có thể sử dụng lớp học Registry để lưu trữ và truy xuất phiên bản Database của mình.

class Registry 
{ 
    protected static $_data = array(); 

    public static function set($key, $value) 
    { 
     self::$_data[$key] = $value; 
    } 

    public static function get($key, $default = null) 
    { 
     if (array_key_exists($key, self::$_data)) { 
      return self::$_data[$key]; 
     } 

     return $default; 
    } 
} 

Registry::set('db', new Database()); 
$db = Registry::get('db'); 
+0

Đó là cơ bản một lớp đơn cho dữ liệu .... –

+0

vì vậy là $ GLOBALS ... –

+0

Ngoại trừ '$ GLOBALS' và từ khóa' global' được tích hợp vào ngôn ngữ, và do đó nhanh và được mọi người biết đến. Lớp đăng ký của bạn không có và không thêm chức năng phụ. Một số loại 'Tùy chọn' lớp có thể hữu ích cho việc lưu trữ các tùy chọn ứng dụng, nhưng thậm chí có thể thay thế bằng một mảng kết hợp. –

1

Tại sao không tạo lớp có chứa global $db; trong hàm tạo, sau đó mở rộng tất cả các lớp khác?

2

Tôi làm điều đó một chút khác biệt. Tôi thường có một đối tượng ứng dụng toàn cầu (App). Trong đối tượng mà tôi làm một số khởi tạo cơ bản như tạo các đối tượng db của tôi, bộ nhớ đệm đối tượng, vv

Tôi cũng có một chức năng toàn cầu mà trả về đối tượng App .... do đó (định nghĩa đối tượng ứng dụng không hiển thị):

define('APPLICATION_ID', 'myApplication'); 

${APPLICATION_ID} = new App; 

function app() { 
    return $GLOBALS[APPLICATION_ID]; 
} 

Vì vậy, sau đó tôi có thể sử dụng giống như sau bất cứ nơi nào trong bất kỳ mã để tham khảo đối tượng trong đối tượng toàn cầu:

app()->db->read($statement); 
app()->cache->get($cacheKey); 
app()->debug->set($message); 
app()->user->getInfo(); 

đó không phải là hoàn hảo nhưng tôi thấy nó làm cho mọi việc dễ dàng hơn trong nhiều hoàn cảnh.