文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>CakePHP中文手册【翻译】-Model (一)

CakePHP中文手册【翻译】-Model (一)

时间:2007-09-14  来源:youngpand


Model
第1节
model是什么?
model是什么?是MVC中的M。
它能做什么?把逻辑从表现层中分离出来,独立应用程序的逻辑。
一般来说,model是一个数据库的访问入口,更特殊的是,它是某个特定数据库表会的访问入口。缺省的,每个model使用数据表,此表的表名是它自己的复数形式,例如,‘User‘model使用’users‘表。Model也可以包含数据验证规则,关联信息,以及指定到它使用的表的方法。下面是一个简单的User model在Cake中的样子:
User model实例,保存在app/models/user.php

//AppModel gives you all of Cake's Model functionality

class User extends AppModel
{
    // Its always good practice to include this variable.
    var $name = 'User';

    // This is used for validation, see Chapter 11.
    var $validate = array();

    // You can also define associations.
    // See section 6.3 for more information.

    var $hasMany = array('Image' =>
                   array('className' => 'Image')
                   );

    // You can also include your own functions:
    function makeInactive($uid)
    {
        //Put your own logic here...
    }
}

?>

第2节
Model 功能
从PHP的角度看,model扩展了AppModel类。AppModel类在cake/目录中定义,如果你想创建你自己的类,请把它放在app/app_model.php.它应该包含在2个或更多的model之间可共享的方法。它自己扩展了Model类,此类是一个标准的Cake库,定义在cake/libs/model.php中。
本节介绍大部分常用的Cake Model函数。记住使用
http://api.cakephp.org
获取全部参考,这是非常重要的。
用户定义函数
在Model中,某个特定表的函数的例子是一对用来隐藏/显示blog中的post的方法。
Model 函数实例
class Post extends AppModel
{
   var $name = 'Post';

   function hide ($id=null)
   {
      if ($id)
      {
          $this->id = $id;
          $this->saveField('hidden', '1');
      }
   }

   function unhide ($id=null)
   {
      if ($id)
      {
          $this->id = $id;
          $this->saveField('hidden', '0');
      }
   }
}
?>

获取数据
下面是一些用来获取数据的标准model方法。
findAll
string $conditions
array $fields
string $order
int $limit
int $page
int $recursive
返回符合$conditions(如果有的话)并且上限为$limit条的指定字段,并从页面$page(缺省为页面1)开始列出。$conditions看起来和他们在SQL语句里的一样,例如$conditions = "race = 'wookie' AND thermal_detonators > 3"。
当$recursive设置为一个大于1的整数时,findAll()操作会尽可能返回与findAll()找到的那些相关联的model。如果你的财产(Property)有多个拥有者,并且他们拥有多个合同(contract),那么一个Property model的findAll()方法将递归返回这些相关的model。
find
string $conditions
array $fields
string $order
int $recursive
返回匹配$conditions的第一个记录的指定字段(或所有字段,如果没有指明)。
当$recursive选项设置为一个1到3之间的整数值,findAll()操作尽可能返回与findAll()找到的那些相关联的model。递归查找最深可到第3层。如果你的财产(Property)有多个拥有者,并且他们拥有多个合同(contract),那么一个Property model的递归find()方法将返回最多三层深的关联model。
findAllBy
string $value
这些魔幻函数可以作为一个快捷方式来查询你的表,并获得一行给定了特定的字段,特定的值的记录。将你想查询的字段名字放上去,并使用骆驼峰的格式。实例(在Controller里)可以为
$this->Post->findByTitle('My First Blog Post');
$this->Author->findByLastName('Rogers');
$this->Property->findAllByState('AZ');
$this->Specimen->findAllByKingdom('Animalia');
返回值是一个数组,并且按find()或findAll()那样的格式进行格式化.
findNeighbours
string $conditions
array $field
string $value
返回一个相邻的Model数组(仅用指定的字段),并由$field和$value指定,由SQL条件$conditions进行过滤。
在这种情形下,它是非常价值的。你可以让用户通过'Previous'和'Next'的链接在你的model入口里获取有序的记录。它仅对数字和日期字段有效。
class ImagesController extends AppController
{
    function view($id)
    {
        // Say we want to show the image...

        $this->set('image', $this->Image->find("id = $id");

        // But we also want the previous and next images...

        $this->set('neighbours', $this->Image->findNeighbours(null, 'id', $id);

    }
}

它会给我们一个全集的$image['Image']数组,并在view中接着有 $neighbours['prev']['Image']['id'] 以及$neighbours['next']['Image']['id'] 。
field
string $name
string $conditions
string $order
返回一个字符串,即匹配$conditions 条件以及$order顺序的第一个记录的单个字段。
findCount
string $conditions
返回与给定条件匹配的记录数。
generateList
string $conditions
string $order
int $limit
string $keyPath
string $valuePath
本函数是可以快捷的得到一键/值列—特别是对手动创建一个model的HTML select标记。使用$conditions, $order, 以及$limit这些参数来作出一个findAll()请求。通过$keyPath和$valuePath,告诉model在哪里找到生成列表的键与值。例如,如果你打算生成一列基于Role Model的角色,并且键为它们的整数id,完整的调用可以如下:
$this->set(
    'Roles',
    $this->Role->generateList(null, 'role_name ASC', null, '{n}.Role.id', '{n}.Role.role_name')
);

//This would return something like:
array(
    '1' => 'Account Manager',
    '2' => 'Account Viewer',
    '3' => 'System Manager',
    '4' => 'Site Visitor'
);

read
string $fields
string $id
使用本函数得到当前已加载记录的字段以及它们的值,或者为$id的记录。
请注意,read()操作仅仅获得第一层相关model值,与model里$recursive值没有关系。为了获取其他层,使用find()或findAll().
query
string $query
execute
string $query
可以使用model的query()和execute()来执行自定义的SQL调用。两者之间的区别是query()用来执行自定义的SQL查询(返回结果),而execute()用来执行自定义的SQL命令(不需返回值)。
使用query()的自定义SQL调用
class Post extends AppModel
{
    var $name = 'Post';

    function posterFirstName()
    {
        $ret = $this->query("SELECT first_name FROM posters_table
                                 WHERE poster_id = 1");
        $firstName = $ret[0]['first_name'];
        return $firstName;
    }
}
?>

复杂的查找条件(使用Array)
大多数model的查找调用会以这样那样的方式传入一组条件。解决此最简单的方式就是在SQL里使用WHERE子句,但是如果需要更多的控制,你可以使用数组。数组的使用可以使读取更加清楚,同时也更加简单,而且使查询的创建变得相当简单。本语法也将查询的元素(字段,值,操作等)变成严谨但可控制的部分。这让Cake可以生成最有效的查询,并保证恰当的SQL语法,以及脱离每个查询的独立部分。
最基础的是,一个基于数组的查询可以这样:
使用Array的基本查询条件实例
$conditions = array("Post.title" => "This is a post");

//Example usage with a model:
$this->Post->find($conditions);

本结构自己就能非常好的解释它自己:它会查找任何title为"This is a post"的post。注意我们在前面可以把“title”作为字段名,但是在建立查询时,一直指定model名将会是一个优秀的实践,因为它改进了代码的清晰性,并帮助阻止未来的冲突,因为在未来你可能会选择改变你的schema。那么其他的匹配呢?同样简单。让我们查找一些title不是"This is a post"的post:
array("Post.title" => " This is a post")
就在表达式前增加一个'‘。Cake可以解析任何有效的SQL比较操作符,包括匹配表达式,如LIKE,BETWEEN,或REGEX,只要你在表达式或值等操作符之间留一个空格。这里还是有一个例外,那就是IN(…)样式的匹配。查找title为给定值的post可以是:
array("Post.title" => array("First post", "Second post", "Third post"))
在条件中,同样简单增加额外的条件和增加额外的键/值对到数组中:
array
(
    "Post.title"   => array("First post", "Second post", "Third post"),
    "Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks"))
)
缺省的,Cake将多个条件组成AND,意思就是,上面的片段仅仅匹配那些在2周前创建的post,而且title需要匹配其中一个给定的值。虽说如此,我们可以很容易的查找那些匹配任何条件的post:
array
("or" =>
    array
    (
        "Post.title" => array("First post", "Second post", "Third post"),
        "Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks"))
    )
)
Cake接受所有有效的SQL布尔操作,包括ND, OR, NOT, XOR等,并且它们可以为大写,也可以为小写,不管你喜欢哪种。这些条件也可无限嵌套。Posts和Authors之间的关系是hasMany/belongsTo,它会使POST上的查询有一个LEFT JOIN操作。你打算查找所有包含某个关键字或在2周前创建的Post,但是你想约定这些Post为Bob编写,可以是:
array
("Author.name" => "Bob", "or" => array
    (
        "Post.title" => "LIKE %magic%",
        "Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks")
    )
)
保存你的数据
为了将数据保存到你的model中,你需要为它提供你想要保存的数据。用来处理的save()方法应该按下面的形式:
Array
(
    [ModelName] => Array
        (
            [fieldname1] => 'value'
            [fieldname2] => 'value'
        )
)
为了让你的数据按这种方式发表在Controller上,最简单的方式就是使用HTML Helper来实现,因为它创建表单元素,这些元素都以Cake期望的方式命名的。当然,你也没有必要使用它:保证你的表单元素按类似data[Modelname][fieldname]的方式命名。最简单的方式是使用$html->input('Model/fieldname')。
表单Post的数据会自动格式化,并将$this->data 放入Controller里。因此保存web表单的数据是非常简单的。一个合适的controller编辑函数可能看起来如下:
function edit($id)
{

   //Note: The property model is automatically loaded for us at $this->Property.

   // Check to see if we have form data...
   if (empty($this->data))
   {
        $this->Property->id = $id;
        $this->data = $this->Property->read();//populate the form fields with the current row
   }
   else
   {
      // Here's where we try to save our data. Automagic validation checking
      if ($this->Property->save($this->data['Property']))
      {
         //Flash a message and redirect.
         $this->flash('Your information has been saved.',
                     '/properties/view/'.$this->data['Property']['id'], 2);
      }
      //if some fields are invalid or save fails the form will render
   }
}
注意,save操作是怎样在一个条件语句中放置的:当你试图将数据保存到model时,Cake自动试图根据你提供的规则验证数据。为了学到更多关于数据验证的知识,参看
第12章
。如果你不想让save()验证数据,使用save($data, false).
其他有用的存储函数:
del
string $id
boolean $cascade
删除指定$id的model,或者model的当前id。如果这个model和其他model相关联,并且'dependent'间已经在关联数组中设置,本方法也会删除那些关联的model,如果$cascade设为true的话。
如果成功返回true。
saveField
string $name
string $value
用来保存单个字段值。
getLastInsertId
返回最近创建记录的ID。


相关阅读 更多 +
排行榜 更多 +
胜利女神新的希望小米服手游下载

胜利女神新的希望小米服手游下载

角色扮演 下载
我要当老板伐木工厂游戏下载

我要当老板伐木工厂游戏下载

模拟经营 下载
涡轮螺旋桨最新版下载

涡轮螺旋桨最新版下载

模拟经营 下载