2008-11-17 31 views
32

Một số cách bạn đã triển khai các mô hình trong khung công tác Zend là gì?Các mô hình trong khung công tác Zend

Tôi đã thấy các cuộc gọi class User extends Zend_Db_Table_Abstract và sau đó đặt cơ bản như trong bộ điều khiển của bạn:

$foo = new User;

$foo->fetchAll()

nhưng những gì về sử dụng phức tạp hơn? Phần Quickstart của tài liệu cung cấp ví dụ như vậy nhưng tôi vẫn cảm thấy như tôi không nhận được ví dụ "sử dụng tốt nhất" cho các mô hình trong Zend Framework. Có triển khai thú vị nào không?


EDIT: Tôi nên làm rõ (để phản ứng lại lời nhận xét của CMS) ... Tôi biết về làm Selects phức tạp hơn. Tôi đã quan tâm đến các cách tiếp cận tổng thể cho khái niệm Mô hình và các ví dụ cụ thể về cách những người khác đã triển khai chúng (về cơ bản, nội dung hướng dẫn sử dụng và những thứ cơ bản về cách làm sáng tỏ)

Trả lời

22

Cá nhân tôi phân lớp cả hai Zend_Db_Table_AbstractZend_Db_Table_Row_Abstract. Sự khác biệt chính giữa mã của tôi và của bạn là xử lý rõ ràng lớp con của Zend_Db_Table_Abstract dưới dạng "bảng" và Zend_Db_Table_Row_Abstract là "hàng". Rất hiếm khi tôi nhìn thấy các cuộc gọi trực tiếp để chọn các đối tượng, SQL hoặc các phương thức cơ sở dữ liệu ZF được xây dựng trong các bộ điều khiển của tôi. Tôi cố gắng ẩn logic yêu cầu hồ sơ cụ thể cho các cuộc gọi sau số Zend_Db_Table_Abstract như vậy:

class Users extends Zend_Db_Table_Abstract { 

    protected $_name = 'users'; 

    protected $_rowClass = 'User'; // <== THIS IS REALLY HELPFUL 

    public function getById($id) { 
     // RETURNS ONE INSTANCE OF 'User' 
    } 

    public function getActiveUsers() { 
     // RETURNS MULTIPLE 'User' OBJECTS    
    } 

} 

class User extends Zend_Db_Table_Row_Abstract { 

    public function setPassword() { 
     // SET THE PASSWORD FOR A SINGLE ROW 
    } 

} 

/* CONTROLLER */ 
public function setPasswordAction() { 

    /* GET YOUR PARAMS */ 

    $users = new Users(); 

    $user = $users->getById($id); 

    $user->setPassword($password); 

    $user->save(); 
} 

Có nhiều cách để tiếp cận điều này. Đừng nghĩ đây là người duy nhất, nhưng tôi cố gắng làm theo ý định thiết kế của ZF. (Dưới đây là nhiều hơn số thoughts and links on the subject của tôi.) Cách tiếp cận này có được một lớp nhỏ nặng, nhưng tôi cảm thấy nó giữ các bộ điều khiển tập trung vào xử lý đầu vào và phối hợp với quan điểm; rời khỏi mô hình để thực hiện công việc cụ thể của ứng dụng.

+7

Nên "bảo vệ $ _rowClass = 'Người dùng';" đã được "bảo vệ $ _rowClass = 'Người dùng';"? – Svish

+0

$ users-> getById ($ id) có thể được thay thế bằng phương pháp tìm kiếm $ user-> find ($ id) -> current(); –

1

Bạn có thể thực hiện các truy vấn phức tạp hơn, kiểm tra phần Advanced usage trong trang hướng dẫn sử dụng Zend_Db_Table.

$select = $table->select(); 
$select->from($table, 
       array('COUNT(reported_by) as `count`', 'reported_by')) 
     ->where('bug_status = ?', 'NEW') 
     ->group('reported_by'); 
1

bạn có thể mở rộng lớp Zend_Db_Table_Abstract và thêm một số phương pháp hữu ích vào nó. ví dụ bạn có thể thêm một phương thức changePassword() vào lớp người dùng của bạn và thao tác dữ liệu của nó. hoặc bạn có thể thay đổi phương thức __toString() mặc định của lớp, vì vậy bạn sẽ có phương thức __toString() tùy chỉnh, giả sử trả về toàn bộ thông tin liên hệ của người dùng (tên, địa chỉ, số điện thoại) trong chuỗi được định dạng tốt . trong hàm tạo của bạn, bạn có thể điền dữ liệu của bạn vào các thuộc tính của đối tượng của bạn. sau đó sử dụng chúng thích:

public function __toString() { 
    $data = $this->_name . ', ' . $this->_adderss . ', call: ' . $this->_phone; 
    return $data; 
} 

mô hình của bạn mở rộng Zend_Db_Table_Abstract chỉ để giảm bớt quá trình truy cập vào dữ liệu của nó, nhưng các chức năng bạn có thể có trên dữ liệu đó là tất cả lên về sự sáng tạo và nhu cầu của bạn. Tôi khuyên bạn nên cuốn sách hướng dẫn "php | kiến ​​trúc sư để lập trình với khung công tác zend" của Cal Evans. cuốn sách rất thông tin và dễ đọc. chương 4 và 6 sẽ hữu ích cho vấn đề này.

3

Bỏ qua ZF cho phần mô hình, có nhiều giải pháp tốt hơn. Chữ "M" trong "MVC" của ZF khá vắng mặt. Đọc tài liệu của họ họ không thực sự đề cập đến các mô hình - đó là một điều tốt, nó có nghĩa là bạn có thể sử dụng bất cứ thứ gì bạn muốn mà không cần viết nhiều mã adapter.

Hãy xem Doctrine cho các mô hình thay thế. Nó nhanh chóng trở thành ORM thực tế cho PHP.

+0

Học thuyết sẽ tuyệt vời nhưng tôi không thể chắc chắn có quyền truy cập vào các phiên bản của PHP đủ hiện tại để đáp ứng các yêu cầu của giáo lý. – Stuart

+0

Doctrine nói rằng nó đòi hỏi PHP 5.2.3, trong khi ZF yêu cầu PHP 5.1.4 nhưng cũng mạnh mẽ khuyến cáo 5.2.3 vì lợi ích an ninh và hiệu suất của nó. –

61

Tôi đã làm việc cho Zend và thực hiện khá nhiều công việc trên thành phần Zend_Db_Table.

Zend Framework không cung cấp nhiều hướng dẫn về khái niệm "Mô hình" liên quan đến mẫu Mô hình miền. Không có lớp cơ sở cho Mô hình bởi vì Mô hình đóng gói một số phần của logic nghiệp vụ cụ thể cho ứng dụng của bạn. Tôi đã viết một số blog về chủ đề này chi tiết hơn.

Tính kiên trì đối với cơ sở dữ liệu phải là chi tiết triển khai bên trong của Mô hình. Mô hình thường là sử dụng một hoặc nhiều Bảng. Đó là một thiết kế hướng đối tượng phổ biến nhưng không phù hợp để xem xét một Mô hình như một phần mở rộng của một Bảng. Nói cách khác, chúng ta nên nói Model HAS-A Table - không phải là Model IS-A Table.

Đây là một ví dụ về IS-A:

class MyModel extends Zend_Db_Table_Abstract 
{ 
} 

Đây là một ví dụ về HAS-A:

class MyModel // extends nothing 
{ 
    protected $some_table; 
} 

Trong một mô hình miền thực, bạn sẽ sử dụng $ some_table trong các phương pháp của MyModel.

Bạn cũng có thể đọc Martin Fowler trên mẫu thiết kế Domain Model và mô tả của mình về mẫu đối tượng Anemic Domain Model, đó là số lượng nhà phát triển không may khi tiếp cận lập trình OO.

+1

"... đã làm khá nhiều công việc trên Zend_Db_Table ..." Tôi biết bạn đã làm, Bill. Tôi là một cái gì đó của một fan hâm mộ của công việc php của bạn, phải trung thực. – Stuart

+0

FWIW, tôi đã không bắt đầu dự án, tôi chỉ tiếp quản khi những người ban đầu chuyển sang. Paul M. Jones (http: // paul-m-jones.com /) xứng đáng với tín dụng là kiến ​​trúc sư của các thành phần Zend_Db. –

+4

Để diễn giải: Mô hình chất béo & bộ điều khiển gầy là tốt. Mô hình gầy và bộ điều khiển chất béo là xấu. –

7

Đừng bao giờ sử dụng Zend_Db_Table làm mô hình của bạn. Nó chỉ khiến bạn gặp rắc rối. Bạn có thể viết các lớp mô hình của riêng bạn sử dụng Zend_Db_Table để nói chuyện với cơ sở dữ liệu của bạn hoặc bạn có thể đọc bài đăng trên blog của tôi here để hack cho phép bạn kết hợp phần nào với lớp "Mô hình" và Zend_Db_Table.

Điều chính không phải là khi bạn sử dụng Zend_Db_Table trực tiếp trong bộ điều khiển của bạn, bạn sẽ làm những điều tương tự ở nhiều nơi. Nếu bạn phải thay đổi một số logic đó, bạn phải thực hiện thay đổi ở nhiều nơi. Không tốt. Dự án chuyên nghiệp đầu tiên của tôi đã được thực hiện như thế này bởi vì tôi là một trong những công ty đã phải học cách sử dụng ZF và bây giờ nó là một mớ hỗn độn.

Tôi cũng có xu hướng viết các hàm trợ giúp vào các lớp của tôi để tìm nạp phức tạp. Mọi thứ như $ table-> doNameFetchAll() hoặc $ table-> doOrderFetchAll().

+0

Liên kết của bạn bị hỏng, bạn có bản sao tài nguyên đã nói khác không? –

+0

@ x-istence Dường như blog đã chuyển từ .com sang miền .net. Đây là liên kết: http://zacharysnow.net/2008/06/20/zend_db_table-as-a-model/ –

+1

Xin lỗi, chỉ nhìn thấy chuỗi nhận xét này lần đầu tiên. Tôi đã viết bài báo đó từ lâu rồi. Nếu bạn viết một ứng dụng mới về sau, tôi sẽ thực hiện nhiều cách tiếp cận được trình bày trong Zend Framework nhanh hơn: http://framework.zend.com/manual/en/learning.quickstart.create-model.html – smack0007

1

Thực thể cơ sở dữ liệu không phải là loại thành phần mô hình duy nhất. Như vậy, nó không thực sự có ý nghĩa để nói về các mô hình (số nhiều) - Ứng dụng của bạn có một mô hình, có chứa nhiều thành phần. Một số thành phần này có thể là các cổng bảng (Và do đó mở rộng từ Zend_Db), trong khi những thành phần khác thì không.

Tôi khuyên bạn nên giữ quyển sách Domain Driven Design bởi Eric Evans, một công cụ tuyệt vời để giải thích cách xây dựng mô hình đối tượng.

7

Tôi đã làm một số nghiên cứu về mô hình cho ZF và đã xem qua một loạt thú vị của bài viết bởi Matthew Weier O'Phinney mà cũng đáng để thử qua:

Nó không phải là "mã sản xuất" và nhiều thứ được để lại cho trí tưởng tượng, nhưng đó là một đọc tốt và đã giúp tôi q uite một chút.

1

Tôi sử dụng Propel 1.3 thay vì Zend_Db_Table. Rất khó để thiết lập, nhưng tuyệt vời. Nó có thể kiểm tra cơ sở dữ liệu của bạn và tự động tạo tất cả các mô hình của bạn. Nó thực sự tạo ra 2 cấp độ và 2 loại mô hình.

Ví dụ về bảng 'user':

Level 1: BaseModel & BasePeer: những bị ghi đè mỗi khi bạn tạo ORM của bạn. tức là BaseUser.php & BaseUserPeer.php

Cấp 2: StubModel & StubPeer: những điều này không bị ghi đè. Họ là những người bạn tùy chỉnh. tức là User.php & UserPeer.php

Loại 1: Mô hình - cho các hoạt động CRUD cơ bản, không phải truy vấn tức là User.php Loại 2: Truy vấn ngang hàng. Đây là những đối tượng tĩnh. tức là UserPeer.php

Vì vậy, để tạo một người dùng:

$derek = new User(); 
$derek->setFirstName('Derek'); 
$derek->save(); 

Để tìm tất cả dereks:

$c = new Criteria(); 
$c->add(UserPeer::FIRST_NAME, 'Derek'); 
$dereks = UserPeer::doSelect($c); 
5

Mô hình có không có gì để làm với cơ sở dữ liệu. Điều gì sẽ xảy ra nếu tôi tìm nạp dữ liệu từ nguồn cấp dữ liệu RSS hoặc dịch vụ SOAP hoặc đọc tệp từ FS?

Tôi đặt tất cả những thứ này vào mô hình. Trong trường hợp đó, lớp mô hình của tôi có thể không mở rộng bất cứ điều gì. Tôi sắp viết một mô hình sử dụng các phương pháp của các mô hình khác.

+2

Hoàn toàn đồng ý! Mặc dù đây là câu hỏi ngày, nhiều người vẫn đến và nhìn ở đây, vì vậy tôi sẽ giải pháp hậu. Tôi đã viết bài báo làm thế nào tôi đã thực hiện mô hình và ORM trong khuôn khổ zend. Hy vọng nó sẽ giúp nhiều người. nó đang diễn ra: http://havl.net/devnotes/2010/10/zendframework-model-orm/ – DavidHavl

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