2009-03-12 38 views
20

Tôi đang đùa giỡn với Zend Framework và cố gắng sử dụng hướng dẫn "QuickStart" trên trang web mà tôi đang thực hiện để xem quy trình hoạt động như thế nào. Tha thứ cho tôi nếu câu trả lời này là hiển nhiên, hy vọng ai đó có kinh nghiệm có thể làm sáng tỏ điều này.Lập mô hình đối tượng có nhiều mối quan hệ bảng trong Zend Framework

Tôi có ba bảng cơ sở dữ liệu:

CREATE TABLE `users` (
    `id` int(11) NOT NULL auto_increment, 
    `email` varchar(255) NOT NULL, 
    `username` varchar(255) NOT NULL default '', 
    `first` varchar(128) NOT NULL default '', 
    `last` varchar(128) NOT NULL default '', 
    `gender` enum('M','F') default NULL, 
    `birthyear` year(4) default NULL, 
    `postal` varchar(16) default NULL, 
    `auth_method` enum('Default','OpenID','Facebook','Disabled') NOT NULL default 'Default', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `email` (`email`), 
    UNIQUE KEY `username` (`username`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

CREATE TABLE `user_password` (
    `user_id` int(11) NOT NULL, 
    `password` varchar(16) NOT NULL default '', 
    PRIMARY KEY (`user_id`), 
    UNIQUE KEY `user_id` (`user_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

CREATE TABLE `user_metadata` (
    `user_id` int(11) NOT NULL default '0', 
    `signup_date` datetime default NULL, 
    `signup_ip` varchar(15) default NULL, 
    `last_login_date` datetime default NULL, 
    `last_login_ip` varchar(15) default NULL, 
    PRIMARY KEY (`user_id`), 
    UNIQUE KEY `user_id` (`user_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

Tôi muốn tạo ra một mô hình người dùng mà sử dụng tất cả ba bảng trong các tình huống nhất định. Ví dụ: bảng siêu dữ liệu được truy cập nếu/khi dữ liệu meta là cần thiết. Bảng user_password chỉ được truy cập nếu đặt 'Default' auth_method. Tôi có thể sẽ thêm một bảng hồ sơ sau này mà tôi muốn có thể truy cập từ mô hình người dùng.

Cách tốt nhất để làm điều này với ZF là gì và tại sao?

+0

Rất không rõ ràng về lý do tại sao điều này bị bỏ phiếu: có vấn đề gì với câu hỏi này không? Tôi không thể tìm thấy một câu hỏi tương tự giải thích điều này trong chi tiết tôi đang tìm kiếm. Hãy cho tôi biết nếu tôi có thể rõ ràng hơn. –

+0

Dunno, dư thừa dữ liệu có lẽ? Bạn có thể thay thế tất cả câu lệnh SQL đó bằng mô tả ngắn gọn về các bảng. – vartec

+0

Dường như một người nào đó đã downvoted tất cả các câu hỏi mới – vartec

Trả lời

23
class Users extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'users'; 
    protected $_rowClass = 'User'; 
    protected $_dependentTables = array ('UserMetadata', 'UserPassword'); 

... 

class UserMetadata extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'user_metadata'; 
    protected $_referenceMap = array (
    'Users'=> array (
    'columns'=>'user_id', 
    'refTableClass'=>'Users', 
    'refColumns'=>'id' 
    ) 
    ); 

... 

class UserPassword extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'user_password'; 
    protected $_referenceMap = array (
    'Users'=> array (
    'columns'=>'user_id', 
    'refTableClass'=>'Users', 
    'refColumns'=>'id' 
    ) 
    ); 

tìm nạp dữ liệu:

$id = //get your user id from somewhere 

$users = new Users(); 
$user = $users->fetchRow('id=?', $id); 
if ($user->authMethod == 0) 
{ 
    $metadata = $user->findDependentRowset('UserMetadata')->current(); 
} 

hoặc

$user = $users->fetchRow($users->select() 
       ->where('gender=?, 'M') 
       ->order('email ASC'); 

... vv

dữ liệu Chèn:

$newRow = $users->fetchNew(); 
$newRow->email = [email protected]; 
$newRow->save(); 

hoặc

$users = new Users(); 
$data = array('email'  => '[email protected]', 
       'firstname' => 'Me'); 
$users->insert($data); 

Cập nhật:

$user->email = '[email protected]'; 
$user->save(); 

Xóa một hàng:

$user->delete(); 

Sử dụng giao dịch:

$db->beginTransaction(); 
$db->commit(); 
$db->rollback(); 

vv ... tất cả trong số ZF Manual!

+0

Điều này có ý nghĩa nhất với tôi - vậy làm thế nào để bạn xử lý một chèn vào bảng người dùng? Một cách hợp lý, cần có một hàng user_metadata được tạo ra. Tôi có thể xử lý điều đó ở cấp độ mô hình bằng cách nào đó không? –

+1

Các logic để tạo một hàng siêu dữ liệu khi tạo một hàng người dùng mà bạn phải tự viết. nhưng thật dễ dàng. nếu bạn muốn làm điều đó một cách sạch sẽ, hãy sử dụng các giao dịch ... – markus

+0

Đây chính xác là những gì tôi đã làm, và nó hoạt động khá tốt. Cảm ơn bạn. –

2

Về cơ bản thay vì sử dụng Zend_Db_Table, hãy sử dụng tổng quát hơn Zend_Db_Select hoặc Zend_Db_Statement để truy xuất dữ liệu.

BTW. Bạn có thể muốn truy cập dữ liệu mật khẩu không trực tiếp trong Mô hình người dùng, mà đúng hơn là trong lớp xác thực người dùng của bạn có nguồn gốc từ Zend_Auth_Adapter.

+0

Tôi không có kế hoạch truy cập dữ liệu mật khẩu qua mô hình người dùng, ngoại trừ để cập nhật nó. Không sử dụng Zend_Db_Select hoàn toàn phá vỡ ý tưởng mô hình hóa dữ liệu người dùng như một đối tượng duy nhất? –

+0

Không phải ORM, không cần lập bản đồ bảng lớp 1 đến 1. – vartec

+0

BTW. bản đồ 1 = 1 sẽ có thể nếu DB của bạn ở 3NF, vấn đề của bạn xuất phát từ thực tế, rằng bạn đã chuẩn hóa DB của mình, chia dữ liệu người dùng thành 3 bảng. – vartec

0

Tôi sẽ nói rằng cách tốt nhất để làm điều này với ZF là sử dụng Doctrine.

0

Chỉ cần một vài lưu ý thẳng off the bat:

Bảng tài khoản đầu tiên, có vẻ giống như một bảng Person, trừ các phương pháp xác thực, nhưng bạn có thể đặt rằng trong bảng User_Password, mà bạn có thể có thể đổi tên Người dùng. Bảng User_Metadata có vẻ như nó chỉ có thể được hợp nhất với bảng User_Password/User. Bây giờ, ngay cả khi không có những thay đổi đó, bạn có ba bảng riêng biệt, với ba khái niệm riêng biệt, nếu bạn mô hình hóa từng lớp riêng biệt như các lớp khác nhau, và sau đó có một lớp UserModel như một mặt tiền của các loại để truy cập vào mỗi, nó sẽ có thể làm cho nó dễ dàng hơn.

2

Tóm lại, tôi sẽ tạo mô hình cho mỗi bảng chứ không phải một mô hình truy cập cả ba. Sau đó tôi sẽ define relationships giữa các bảng.

Thành thật mà nói, có vẻ như không phải là một "mô hình" cho mỗi bảng nhưng đó là những gì tôi thấy được thực hiện nhiều lần trong các ví dụ khác nhau trực tuyến và đó là những gì tôi đã làm trong một số dự án đã tạo ra với khung công tác Zend. Nếu bất cứ ai có cách xử lý tốt hơn, tôi hy vọng nó sẽ đăng nó ở đây.

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