php Zend 框架中的模型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/294875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:16:37  来源:igfitidea点击:

Models in the Zend Framework

phpmodel-view-controllerzend-frameworkmodel

提问by rg88

What are some of the ways you have implemented models in the Zend Framework?

您在 Zend 框架中实现模型的方式有哪些?

I have seen the basic class User extends Zend_Db_Table_Abstractand then putting calls to that in your controllers:

我已经看到了基本的class User extends Zend_Db_Table_Abstract,然后在你的控制器中调用它:

$foo = new User;

$foo = new User;

$foo->fetchAll()

$foo->fetchAll()

but what about more sophisticated uses? The Quickstart section of the documentation offers such an example but I still feel like I'm not getting a "best use" example for models in Zend Framework. Any interesting implementations out there?

但是更复杂的用途呢?文档的快速入门部分提供了这样一个示例,但我仍然觉得我没有得到 Zend Framework 中模型的“最佳使用”示例。有什么有趣的实现吗?



EDIT:I should clarify (in response to CMS's comment)... I know about doing more complicated selects. I was interested in overall approaches to the Model concept and concrete examples of how others have implemented them (basically, the stuff the manual leaves out and the stuff that basic how-to's gloss over)

编辑:我应该澄清(回应 CMS 的评论)......我知道做更复杂的选择。我对模型概念的整体方法和其他人如何实现它们的具体示例感兴趣(基本上,手册遗漏的内容以及基本操作方法所掩盖的内容)

采纳答案by Barrett Conrad

I personally subclass both Zend_Db_Table_Abstractand Zend_Db_Table_Row_Abstract. The main difference between my code and yours is that explicitly treat the subclass of Zend_Db_Table_Abstractas a "table" and Zend_Db_Table_Row_Abstractas "row". Very rarely do I see direct calls to select objects, SQL, or the built in ZF database methods in my controllers. I try to hide the logic of requesting specific records to calls for behind Zend_Db_Table_Abstractlike so:

我个人对Zend_Db_Table_Abstract和 进行子类化Zend_Db_Table_Row_Abstract。我的代码和你的代码之间的主要区别在于,明确地将 的子类Zend_Db_Table_Abstract视为“表”和Zend_Db_Table_Row_Abstract“行”。我很少在控制器中看到直接调用选择对象、SQL 或内置 ZF 数据库方法。我试图隐藏请求特定记录到后面调用的逻辑,Zend_Db_Table_Abstract如下所示:

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();
}

There are numerous ways to approach this. Don't think this is the only one, but I try to follow the intent of the ZF's design. (Here are more of my thoughts and links on the subject.) This approach does get a little class heavy, but I feel it keeps the controllers focused on handling input and coordinating with the view; leaving the model to do the application specific work.

有很多方法可以解决这个问题。不要认为这是唯一的,但我尝试遵循 ZF 的设计意图。(这里有更多关于这个主题的想法和链接。)这种方法确实有点沉重,但我觉得它让控制器专注于处理输入和与视图协调;让模型去做特定于应用程序的工作。

回答by Bill Karwin

I worked for Zend and did quite a bit of work on the Zend_Db_Table component.

我为 Zend 工作,并在 Zend_Db_Table 组件上做了很多工作。

Zend Framework doesn't give a lot of guidance on the concept of a "Model" with respect to the Domain Model pattern. There's no base class for a Model because the Model encapsulates some part of business logic specific to your application. I wrote a blogabout this subject in more detail.

Zend Framework 没有就领域模型模式的“模型”概念提供很多指导。模型没有基类,因为模型封装了特定于您的应用程序的业务逻辑的某些部分。我写了一篇关于这个主题的博客更详细。

Persistence to a database should be an internal implementation detail of a Model. The Model typically usesone or more Table. It's a common but improper object-oriented design to consider a Model as an extension of a Table. In other words, we should say Model HAS-A Table -- not Model IS-A Table.

对数据库的持久性应该是模型的内部实现细节。模型通常使用一个或多个表。将模型视为表的扩展是一种常见但不恰当的面向对象设计。换句话说,我们应该说 Model HAS-A Table——而不是 Model IS-A Table。

This is an example of IS-A:

这是一个 IS-A 的例子:

class MyModel extends Zend_Db_Table_Abstract
{
} 

This is an example of HAS-A:

这是 HAS-A 的示例:

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

In a real domain model, you would use$some_table in the methods of MyModel.

在真实的域模型中,您将在 MyModel 的方法中使用$some_table。

You can also read Martin Fowler's take on the Domain Modeldesign pattern, and his description of the Anemic Domain Modelantipattern, which is how many developers unfortunately approach OO programming.

您还可以阅读 Martin Fowler 对领域模型设计模式的看法,以及他对贫血领域模型反模式的描述,这是许多开发人员不幸地采用面向对象编程的方式。

回答by smack0007

Don't ever use Zend_Db_Table as your model. It just gets you into trouble. Either you write your own model classes which use Zend_Db_Table to talk to your database or you can read my blog post herefor a hack that allows you to somewhat combine the "Model" class and Zend_Db_Table.

永远不要使用 Zend_Db_Table 作为你的模型。它只会让你陷入困境。要么您编写自己的模型类,使用 Zend_Db_Table 与您的数据库对话,要么您可以在这里阅读我的博客文章了解允许您在某种程度上组合“模型”类和 Zend_Db_Table 的技巧。

The main thing to not is that when you use Zend_Db_Table directly in your controllers you end up doing the same things in multiple places. If you have to make a change to some of that logic, you have to make a change in multiple places. Not good. My first professional project was done like this because I was the one in the company who had to learn how to use ZF and it's a total mess now.

最重要的是,当您直接在控制器中使用 Zend_Db_Table 时,您最终会在多个地方做同样的事情。如果您必须对某些逻辑进行更改,则必须在多个地方进行更改。不好。我的第一个专业项目就是这样完成的,因为我是公司中那个必须学习如何使用 ZF 的人,现在这完全是一团糟。

I also tend to write helper functions into my classes for sophisticated fetches. Somthing like $table->doNameFetchAll() or $table->doOrderFetchAll().

我还倾向于将辅助函数写入我的类中以进行复杂的提取。类似 $table->doNameFetchAll() 或 $table->doOrderFetchAll() 之类的东西。

回答by ironkeith

I've been doing some research on Models for ZF and came across an interesting series of articles by Matthew Weier O'Phinney which are well worth checking out:

我一直在对 ZF 模型进行一些研究,并发现了 Matthew Weier O'Phinney 撰写的一系列有趣的文章,这些文章非常值得一看:

It's not "production code" and a lot is left to the imagination, but it's a good read and has helped me quite a bit.

它不是“生产代码”,很多东西都留给想象力,但它很好读,对我帮助很大。

回答by d-_-b

A model has nothing to do with the database. What if I am fetching data from an RSS feed or a SOAP service or reading files from the FS?

模型与数据库无关。如果我从 RSS 提要或 SOAP 服务获取数据或从 FS 读取文件怎么办?

I put all these kinds of things in models. In that case, my model class might not extend anything. I'm about to write a model that uses methods of other models.

我把所有这些东西都放在模型中。在这种情况下,我的模型类可能不会扩展任何东西。我即将编写一个使用其他模型方法的模型。

回答by chroder

Skip ZF for the models part, there are much better solutions. The "M" in ZF's "MVC" is pretty much absent. Reading their docs they don't really mention models at all -- which is a good thing, it means you can use just about anything you want without writing lots of adapter code.

对于模型部分跳过 ZF,有更好的解决方案。ZF 的“MVC”中的“M”几乎没有。阅读他们的文档,他们根本没有真正提到模型——这是一件好事,这意味着您可以使用任何您想要的东西,而无需编写大量适配器代码。

Take a look at Doctrinefor models instead. It is quickly becoming the de-facto ORM for PHP.

请查看模型的Doctrine。它正在迅速成为 PHP 的事实上的 ORM。

回答by CMS

You can do more complicated queries, check the Advanced usagesection in the Zend_Db_Tablemanual page.

您可以进行更复杂的查询,请查看手册页中的高级用法部分Zend_Db_Table

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

回答by farzad

you can extend the Zend_Db_Table_Abstract class and add some useful methods to it. for example you can add a changePassword() method to your user class and manipulate it's data. or you can change the default __toString() method of your class, so you'll have a customized __toString() method that, let's say returns the whole contact information of the user (name, address, phone number) in a well formatted string. in your constructor you could populate your data into properties of your object. then use them like:

您可以扩展 Zend_Db_Table_Abstract 类并向其添加一些有用的方法。例如,您可以向用户类添加 changePassword() 方法并操作它的数据。或者您可以更改您的类的默认 __toString() 方法,因此您将拥有一个自定义的 __toString() 方法,假设以格式良好的字符串返回用户的完整联系信息(姓名、地址、电话号码) . 在您的构造函数中,您可以将数据填充到对象的属性中。然后像这样使用它们:

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

your model extends the Zend_Db_Table_Abstract just to ease the process of accessing its data, but the functionality you could have on that data is all up on your creativity and need. I recommend you the book "php|architect's guide to programming with zend framework" by Cal Evans. the book is very informative and easy to read. chapters 4 and 6 are going to be useful for this matter.

您的模型扩展 Zend_Db_Table_Abstract 只是为了简化访问其数据的过程,但是您可以对该数据拥有的功能完全取决于您的创造力和需求。我向您推荐 Cal Evans 所著的“php|architect's guide to programming with zend framework”一书。这本书内容丰富且易于阅读。第 4 章和第 6 章将对此有用。

回答by lo_fye

I use Propel 1.3 instead of Zend_Db_Table. It's tricky to setup, but awesome. It can examine your database and auto-generate all your models. It actually generates 2 levels and 2 types of model.

我使用 Propel 1.3 而不是 Zend_Db_Table。设置起来很棘手,但很棒。它可以检查您的数据库并自动生成您的所有模型。它实际上生成了 2 个级别和 2 种类型的模型。

Examples for 'user' table:

“用户”表的示例:

Level 1: BaseModel & BasePeer: these get overwritten every time you regenerate your ORM. i.e. BaseUser.php & BaseUserPeer.php

级别 1:BaseModel 和 BasePeer:每次重新生成 ORM 时,这些都会被覆盖。即 BaseUser.php 和 BaseUserPeer.php

Level 2: StubModel & StubPeer: these don't get overwritten. They're the ones you customize. i.e. User.php & UserPeer.php

级别 2:StubModel 和 StubPeer:这些不会被覆盖。它们是您自定义的。即 User.php 和 UserPeer.php

Type 1: Model - for basic CRUD operations, not queries i.e. User.php Type 2: Peer -- for queries. These are static objects. i.e. UserPeer.php

类型 1:模型 - 用于基本的 CRUD 操作,而不是查询,即 User.php 类型 2:对等 - 用于查询。这些是静态对象。即 UserPeer.php

So to create a user:

所以要创建一个用户:

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

To find all dereks:

查找所有德里克:

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

回答by sunwukung

http://zfsite.andreinikolov.com/2008/08/zend_db_table-time-overhead-about-25-percents/

http://zfsite.andreinikolov.com/2008/08/zend_db_table-time-overhead-about-25-percents/

Bit of a catch 22, Zend_Table is nice in principle, but generates some performance overheads (without caching)...

有点问题 22, Zend_Table 原则上很好,但会产生一些性能开销(没有缓存)......