《PHP设计模式介绍》第十四章 动态记录模式(3)_PHP教程
推荐:《PHP设计模式介绍》第十三章 适配器模式接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题。程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相关库的发展和进化。我孩子的无数玩具中有一个简要地描
到目前为止,这些实验已证明了以下事实:属性可以被设置,save()能正常工作,$ID属性已被置为1。让我们进一步的深入到数据表去验证其它的属性值也被正确的保存。
class ActiveRecordTestCase extends UnitTestCase { // ... function testNew() { $link = new Bookmark; $link->url = ‘http://simpletest.org/’; $link->name = ‘SimpleTest’; $link->description = ‘SimpleTest project homepage’; $link->tag = ‘testing’; $link->save(); $this->assertEqual(1, $link->getId()); // fetch the table as an array of hashes $rs = $this->conn->getAll(‘select * from bookmark’); $this->assertEqual(1, count($rs), ‘returned 1 row’); foreach(array(‘url’, ‘name’, ‘description’, ‘tag’) as $key) { $this->assertEqual($link->$key, $rs[0][$key]); } } } |
以上突出显示代码的功能是获取整个书签表数据。GetAll()方法执行查询并返回结果集,该结果集是以数组形式存放的记录的哈稀表。AssertEqual()方法验证只有一条记录存在于结果集中。通过foreach循环比较从数据表中取得记录的字段与$link对象的属性值是否一致。
上述代码已能正常工作,但通过手工的方法设定属性值去增加书签表数据的方法还是略显繁琐。因此,为上述的案例增加一个方便(通用)的方法,来实现增加的新建书签对象。
The ActiveRecordTestCase::add()方法带有(处理)四个参数,可建立与插入一个新的ActiveRecord书签对象。如果你在后续实验中要用到新创建的书签对象,add()方法还可以在创建成功后返回它。
class ActiveRecordTestCase extends UnitTestCase { // ... function add($url, $name, $description, $tag) { $link = new Bookmark; $link->url = $url; $link->name = $name; $link->description = $description; $link->tag = $tag; $link->save(); return $link; } } |
你完全可以在本实验案例中写一个测试方法来证明其可用性。
class ActiveRecordTestCase extends UnitTestCase { // ... function testAdd() { $this->add(‘http://php.net’, ‘PHP’, ‘PHP Language Homepage’, ‘php’); $this->add(‘http://phparch.com’, ‘php|architect’, ‘php|arch site’, ‘php’); $rs = $this->conn->execute(‘select * from bookmark’); $this->assertEqual(2,$rs->recordCount()); $this->assertEqual(2,$this->conn->Insert_ID()); } } |
既然书签可以创建并存储于数据库中,让我们给Active Record书签对象增加一个方法,可以简单的从数据库中获取数据并在实例的属性中保存所获取的值。一种通用的建立动态记录对象的技术是通过传递一个标示符,如书签号(或是别的什么标准)到它的构造函数中,并且从数据库中取出与这个ID相关联的行数据。
class ActiveRecordTestCase extends UnitTestCase { // ... function testCreateById() { $link = $this->add( ‘http://blog.casey-sweat.us/’, ‘My Blog’, ‘Where I write about stuff’, ‘php’); $this->assertEqual(1, $link->getId()); $link2 = new Bookmark(1); $this->assertIsA($link2, ‘Bookmark’); $this->assertEqual($link, $link2); } } |
这个实验传递了一个ID到构造函数,这是前面的实验所没有出现过的。是否传递ID是可选的,如果没有传递ID,则前述试验中建立新的空书签实例的功能将依然正常工作。
这儿是一些实现上述功能要求的代码。
class Bookmark { // ... const SELECT_BY_ID = ‘select * from bookmark where id = ?’; public function __construct($id=false) { $this->conn DB::conn(); if ($id) { $rs = $this->conn->execute( self::SELECT_BY_ID ,array((int)$id)); if ($rs) { $row = $rs->fetchRow(); foreach($row as $field => $value) { $this->$field = $value; } } else { trigger_error(‘DB Error: ‘.$this->conn->errorMsg()); } } } // ... } |
构造函数允许一个名为$id的参数,它的默认为假。如果传来的参数不为假,则BOOKmark则用此ID为关键字查询数据库中BOOKmark表的相关行,如果该行存在,则用获取的数据来设定对象属性的值。
数据错误测试
Mock::generate(‘ADOConnection’); class ActiveRecordTestCase extends UnitTestCase { //... function testDbFailure() { $conn = new MockADOConnection($this); $conn->expectOnce(‘execute’, array(‘*’,’*’)); $conn->setReturnValue(‘execute’,false); $conn->expectOnce(‘errorMsg’); $conn->setReturnValue(‘errorMsg’, ‘The database has exploded!!!!’); } } |
这段代码调用了Mock::generate() 来生成一个MockADOConnection 类,并生成一个模拟连接的实例,同时设定一些基本的返回值来指明错误,和定义在这些环境中可能会出现的意外。
分享:《PHP设计模式介绍》第十二章 装饰器模式若你从事过面向对象的php开发,即使很短的时间或者仅仅通过本书了解了一些,你会知道,你可以 通过继承改变或者增加一个类的功能,这是所有面向对象语言的一个基本特性。如果已经存在的一个php
- 相关链接:
- 教程说明:
PHP教程-《PHP设计模式介绍》第十四章 动态记录模式(3)。