2012-07-27 46 views
5

Tôi hiện đang sử dụng PHP PDO để truy cập cơ sở dữ liệu của mình. Đó là tất cả làm việc hoàn toàn tốt đẹp và dandy. Tuy nhiên, tôi sẽ thêm các bản sao đã đọc vào thiết lập máy chủ của mình, vì vậy tôi muốn điều chỉnh mã của mình cho phù hợp.Làm cách nào để tạo "công tắc chế độ" cho PHP PDO?

Kế hoạch hành động hiện tại của tôi là lưu trữ một loạt chi tiết thông tin xác thực cơ sở dữ liệu. Một "đọc và viết" được đặt cho cơ sở dữ liệu MySQL chính và bất kỳ số thông tin xác thực nào cho "bản sao đã đọc".

Điều tôi muốn làm là thêm phương thức vào lớp PDO được gọi là "chế độ" trong đó một chế độ được chuyển qua, chẳng hạn như "đọc" hoặc (mặc định) "ghi". Bằng cách chuyển qua (ví dụ: $ dbh-> mode ("read");), nó có thể tra cứu các chi tiết của một bản sao được đọc ngẫu nhiên (không fussed) và sử dụng các chi tiết đó cho kết nối. Sau đó, khi tôi đọc xong từ bản sao của mình, hãy thực hiện chế độ $ dbh-> ("mặc định") để đưa nó trở lại chế độ ghi, nhờ đó tôi có thể sử dụng INSERT, UPDATE, v.v.

Điều này có thể được thực hiện mà không cần đơn giản phá hủy đối tượng PDO và tạo một đối tượng mới? Các chi tiết kết nối có thể được thay đổi sau khi đối tượng đã tồn tại không?

Cho đến nay tôi có những điều sau đây (hầu như không có gì, nhưng đã tìm ra điểm bắt đầu).

Class SwitchablePDO extends PDO 
{ 
    public function mode($mode = "default") 
    { 
     // Use the credentials for my master read and write server by default 

     if($mode == "read") 
     { 
      // Use one the credentials for my read replicas (randomly choose) 
     } 

    } 
} 

Bất kỳ trợ giúp nào về điều này sẽ được đánh giá cao!

+0

Điều này có cần thiết không? Tôi nghĩ hầu hết mọi người sẽ sử dụng một vài người dùng DB để thực hiện việc này (chỉ có thể đọc và một người có quyền truy cập đầy đủ), sau đó sử dụng kết nối DB riêng cho từng người dùng. – Ozzy

+0

Điều đó sẽ không phân phối tải cho các bản sao đọc mặc dù. Các chi tiết kết nối có nghĩa đen khác nhau đối với mỗi bản sao được đọc. Và nếu tôi chỉ tạo một đối tượng PDO mới mỗi khi tôi muốn trao đổi để đọc hoặc viết, tôi vẫn cần một cách để làm điều này. Bằng cách này (hy vọng) sẽ cho phép tôi chỉ có một đối tượng kết nối/thể hiện của lớp của tôi tại một thời điểm thay vì phải sử dụng $ dbh_write-> query() và $ dbh_read-> query(). – Schodemeiss

Trả lời

2

Tôi thà thiết lập các đối tượng kết nối cơ sở dữ liệu hoàn toàn khác với đối phó với chế độ. Sử dụng một chế độ, bạn chắc chắn sẽ chạy vào một tình huống mà một đoạn mã không đặt chế độ và dựa vào đoạn mã trước đó, và sẽ thất bại khi được gọi trong một ngữ cảnh khác. Điều này được gọi là sequential coupling.

Với nhiều đối tượng được cung cấp bởi phương pháp nhà máy hoặc thùng chứa phụ thuộc, bạn đảm bảo mỗi đoạn mã chỉ định kết nối cơ sở dữ liệu nào cần, chẳng hạn như chính hoặc phụ. Là một phần thưởng, tránh sử dụng master/slave làm tên và thay vào đó sử dụng tên liên quan đến loại công việc cần thực hiện, như phân tích, cho phép bạn thay đổi máy chủ nào sẽ được sử dụng mà không cần phải chuyển mã tìm tất cả các đoạn mã liên quan.

1

Tạo các lớp riêng biệt cho chế độ đọc và ghi, sau đó chuyển sang các thuộc tính riêng tư/được bảo vệ trong lớp SwitchablePDO của bạn. Gọi số mode() thì chỉ cần đặt thuộc tính nào để sử dụng. Dưới đây là một số mã giả:

class WriteablePDO extends PDO 
{ 
    // methods 
} 

class ReadablePDO extends PDO 
{ 
    // methods 
} 

class SwitchablePDO 
{ 
    protected $_mode = 'read'; // default 
    protected $_read; 
    protected $_write; 

    public function __construct() 
    { 
     $this->_read = new ReadablePDO(); 
     $this->_write = new WriteablePDO(); 
    } 

    public function mode($key) 
    { 
     if ($key === 'read') 
     { 
      $this->_mode = '_read'; 
     } 
     elseif ($key === 'write') 
     { 
      $this->_mode = '_write'; 
     } 
    } 

    public function __call($method, $arguments) 
    { 
     return call_user_func_array(array($this->{$this->_mode}, $method), $arguments); 
    } 

}