2012-02-10 22 views
5

Tôi đang cố gắng tạo một lớp đơn giản để sử dụng singleton để kết nối với cơ sở dữ liệu mysql và thực hiện truy vấn, mã hoạt động tốt và tôi chưa gặp bất kỳ vấn đề nào với nó, nhưng vì tôi mới sử dụng OOP cho dù đây là thực hành xấu hay không.kết nối cơ sở dữ liệu singleton php, thực thi mã này có tệ không?

Đây là lớp

class Database { 
private $databaseName = 'dbname'; 
private $host = 'localhost'; 
private $user = 'user'; 
private $password = 'pass'; 
private static $instance; //store the single instance of the database 

private function __construct(){ 
    //This will load only once regardless of how many times the class is called 
    $connection = mysql_connect($this->host, $this->user, $this->password) or die (mysql_error()); 
    $db = mysql_select_db($this->databaseName, $connection) or die(mysql_error()); 
    echo 'DB initiated<br>'; 
} 

//this function makes sure there's only 1 instance of the Database class 
public static function getInstance(){ 
    if(!self::$instance){ 
     self::$instance = new Database(); 
    } 
    return self::$instance;  
} 

public function connect() { 
    //db connection 
} 
public function query($query) { 
    //queries 
    $sql = mysql_query($query) or die(mysql_error()); 
    return $sql; 
} 

public function numrows($query) { 
    //count number of rows 
    $sql = $this->query($query); 
    return mysql_num_rows($sql); 
} 


} 

//Intantiate the class 
$database = Database::getInstance(); 

và khi tôi muốn sử dụng lớp tôi sẽ làm:

$query = "SELECT * FROM registrations"; 
echo $database->numrows($query); 
$sql = $database->query($query); 
+0

Mẫu Singleton thường được triển khai trong Lớp cơ sở dữ liệu, Trình ghi nhật ký, Bộ điều khiển mặt trước hoặc Đối tượng yêu cầu và phản hồi. – diEcho

+0

tôi không thấy bất kỳ sự cố nào trong số – jere

+0

Có vô số lớp học db này bạn có thể xem. Thậm chí nhìn vào các khuôn khổ như codeigniter để xem các lớp db của chúng hoạt động như thế nào. –

Trả lời

12

Đơn là tin xấu.

  • Chúng giới thiệu trạng thái toàn cầu thành một chương trình. Hầu hết các lập trình viên nên quen thuộc với lý do tại sao tình trạng toàn cầu là xấu.
  • Chúng giới thiệu sự ghép nối chặt chẽ giữa singleton và bất kỳ lớp nào sử dụng nó. Điều này có nghĩa là bạn không thể tái sử dụng các lớp được đề cập mà không cần sử dụng lại singleton.
  • Họ thực hiện kiểm tra đơn vị của các lớp phụ thuộc vào singleton có vấn đề bởi vì bạn không thể dễ dàng thay thế singleton bằng một mô hình.
  • Chúng khuyến khích một kiểu mã hóa trong đó các lớp cố gắng giải quyết các phụ thuộc của riêng chúng. Điều này là xấu bởi vì nó có thể làm giảm sự rõ ràng về những gì phụ thuộc lớp có.
  • PHP có kiến ​​trúc Chia sẻ không có gì, nghĩa là các trình đơn PHP không thực sự đơn thuần, có thể có nhiều phiên bản tồn tại cùng một lúc (mỗi lần một yêu cầu mở).
  • Điều gì sẽ xảy ra nếu bạn đột nhiên phát hiện vào một số ngày sau đó mà bạn thực sự cần nhiều hơn một tài nguyên đang được cung cấp bởi singleton? Đây là kịch bản phổ biến hơn bạn có thể nghĩ rằng

Thay vào đó, bạn nên xem xét vì giải quyết các vấn đề trên.

+0

Bạn có thể cung cấp một số bài viết hay về 'dependency-injection' và một số giải thích tại sao" Registry for database "là ý tưởng tồi? (Tôi biết tôi có thể google nó, nhưng một cái gì đó với chất lượng xác nhận và từ các nguồn đáng tin cậy) – Vyktor

+0

Đăng ký giống như Singletons trong hầu hết các khía cạnh (nhà nước toàn cầu, khuyến khích các lớp học giải quyết phụ thuộc, vv). Đối với DI, có rất nhiều bài viết hiện có nếu bạn google, như bạn đã nói. :) Tôi tin rằng tài liệu hướng dẫn cho khung công tác Symfony bao gồm một cuộc thảo luận khá tốt về DI trong ngữ cảnh PHP. – GordonM

+0

Điều gì về lớp autoloader, với (mở rộng câu trả lời của tôi) 'get ($ connName)' sẽ khởi tạo kết nối tự động với 'configs/$ connName.ini'? Tôi hiểu rằng bạn nên cung cấp "Model" với kết nối từ "Controller" và mô hình không nên làm bất cứ điều gì như 'DBs :: get ('export')' nhưng có gì sai khi có kết nối mặc định được chỉ định? – Vyktor

0

mô hình này sẽ ổn thôi vì singleton sẽ chỉ áp dụng cho phiên người dùng hiện tại. Quyết định thực sự đi xuống đến mức ưu tiên của bạn. Nếu bạn muốn hiệu suất nhanh hơn cho người dùng thì bạn muốn cho phép nhiều kết nối cơ sở dữ liệu hơn cho mỗi người dùng, nhưng nếu bạn muốn giới hạn mức độ khó mà cơ sở dữ liệu của bạn bị tấn công thì singleton mang đến cho bạn một con đường tốt.

+1

Đơn là tin xấu. Họ nên tránh. – GordonM

+0

@GordonM, rất đúng. Lời khuyên của bạn là giải pháp lâu dài thận trọng hơn. – davidethell

2

Tôi nghĩ một singleton có thể được chấp nhận đối với người quản lý kết nối, nhưng không phải cho một kết nối.

Bạn không bao giờ biết khi nào bạn cần có thêm kết nối cho một phần cụ thể trong quá trình phát triển của mình. Giả sử bạn cần thêm đồng bộ hóa với cơ sở dữ liệu từ xa.

Trình quản lý kết nối (có thể quản lý nhiều kết nối) có thể là một singleton. Một kết nối; Không.

Trình quản lý kết nối cũng có thể tải "Trình điều khiển" để bạn có thể tạo kết nối MySQL và ngày bạn cần MSSQL, sqLite hoặc bất kỳ thứ gì khác, bạn có thể thêm các trình điều khiển cần thiết .

2

Tôi sẽ nói điều đó phụ thuộc vào cách bạn sử dụng lớp học. Nếu bạn gọi Database::getInstance() mọi lúc bạn muốn sử dụng một cơ sở dữ liệu, thì điều đó là xấu từ quan điểm của OO, bởi vì nó làm tổn thương đến khả năng kiểm thử. Nếu bạn làm điều đó chỉ một lần và sau đó tiêm thể hiện cho các đối tượng cần phải làm việc với cơ sở dữ liệu, nó không phải là quá xấu để sử dụng singleton (nhưng vẫn không cần thiết).

tôi đề nghị bạn nhìn vào tiêm khái niệm phụ thuộc: http://misko.hevery.com/2008/11/11/clean-code-talks-dependency-injection/ hoặc http://fabien.potencier.org/article/11/what-is-dependency-injection

0

Đối số tích cực duy nhất mà tôi đã từng nghe cho các mẫu thiết kế Singleton trong PHP là từ một nhà phát triển người thực hiện một kết nối cơ sở dữ liệu Singleton kết hợp với một đối tượng Memcached. Tôi đã không thực sự có cơ hội để xem mã và hiệu suất nhưng anh ấy đã có thể đưa ra một lập luận chặt chẽ.

Cá nhân tôi không tin rằng mẫu thiết kế Singleton rất phù hợp với PHP, phần lớn là không trạng thái (như được chỉ ra trước mỗi yêu cầu sẽ có một singleton).

Các vấn đề liên quan