我们都知道如何从mysql获取我们需要的行(记录),读取数据,然后存取一些改动。很明显也很直接,在这个过程背后也没有什么拐弯抹角的。然而对于我们使用面对对象的程序设计(OOP)来管理我们数据库中的数据时,这个过程就需要大大改进一下了。这篇文章将对如何设计一个面对对象的方式来管理数据库的记录做一个简单的描述。你的数据当中的所有内部逻辑关系将被封装到一个非常条理的记录对象,这个对象能够提供专门(专一)的确认代码系统,转化以及数据处理。随着Zend Engine2 和php5的发布,PHP开发者将会拥有更强大的面对对象的工具来辅助工作,这将使这个过程(面对对象地管理数据库)更有吸引力。

以下列出了一些使用对象来描叙你的数据库的有利方面:

http://www.gaodaima.com/46136.html在数据库中使用对象的好处_php

存取方法(accessor methods)将会使你对属性的读取和写入过程做到完全的控制

每一级的每个记录和属性(的操作)都有确认过程

从关系表中智能的获取对象

重复使用的逻辑方法意味着所有的数据交互都要通过相同的基础代码(codebase),这将使维护变得更加简单

代码简单,因为不同的记录的内部逻辑都已经包含在各自所处的类(class)当中,而不是繁琐的库(lib)文件

在手工编写代码和SQL查询语句时,出错的机会将更少

存取方法(Accessor methods)

存取方式是通过类给实例(instance)的变量赋值。一个例子,我有一个叫User的类,并且有一个实例$username,我会写这样的存取方法(函数),User->username()和User->setUsername()用来返回和给实例赋值。

class User {

var $username;

function username() {

return $this->username;

}

function setUsername($newUsername) {

$this->username = $newUsername;

}

}

?>

这里有很好的理由让我们编写这样的“特别的代码”。它将使开发者更灵活的改变类的繁琐的工作,因为这一过程将不需要其他的使用类的php代码。让我们来看看下面这个更加完善的可信赖的User类。

变量$username将不复存在,所有的东西都被整合的放在数组$_data当中

如果username是空的话,username()函数将提供一个缺省(默认)的值给它

setUsername()过程将在接受值之前确认username是否合乎标准格式(如字长等)

class User {

var $_data = array(); // associative array containing all the attributes for the User

function username() {

return !empty($this->_data['username']) ? $this->_data['username'] : '(no name!)';

}

function setUsername($newUsername) {

if ($this->validateUsername($newUsername)) {

$this->_data['username'] = $newUsername;

}

}

function validateUsername(&$someName) {

if (strlen($someName) > 12) {

throw new Exception('Your username is too long'); // PHP5 only

}

return true;

}

}

?>

显而易见,这对我们控制存取对象的数据有很大帮助。如果一个程序员已经直接地存取username的信息,以上代码的变化将会破坏他的代码。然而我们可以使用(类的)存取方法,就像上面代码中注释的那样,添加一个验证的功能而不需要改变任何其他的东西。注意username的验证(例子当中是不能超过12字节)代码是独立在setUsername()方法之外的。从验证到存储到数据库的过程轻而易举。而且,这是个非常好的单凭经验的方法,一个方法或一个类需要做的越少,它的重复使用的机会将会越大。这在你开始写一个子类时更加明显,假如你需要一个子类,并且又要跳过(忽略)父类方法(行为)中的一些特殊的细节,如果(针对这个细节的)方法很小而又精细,(修改它)只是一瞬间的过程,而如果这个方法非常臃肿,针对多种目的,你可能将在复制子类中大量代码中郁闷而终。

比方说,假如Admin是User类的一个子类。我们对adamin的用户可能会有不同的,相对苛刻一些的密码验证方法。最好是跨过父类的验证方法和整个setUsername()方法(在子类中重写)。

更多关于存取器(Accessor)

下面是一些其他的例子来说明如何使存取器用的更有效果。很多时候我们可能要计算结果,而不是简单的返回数组中的静态数据。存取方法还能做的一个有用的事情就是更新(updating)缓存中的值。当所有的变动(对数据的所有操作)都要通过setX()方法的时候,这正是我们根据X来重置缓存中的值的时刻。

于是我们的这个类层次变得更加明了:

内部变量$_data的处理被替换成受保护的私有方法(private methods)_getData()和_setData()

这类方法被转移到被称作记录(Record)的抽象的超级类(super class),当然它是User类下的子类

这个记录类(Record class)掌握所有存取数组$_data的细节,在内容被修改之前调用验证的方法,以及将变更的通知发给记录(Records),就像发给中心对象存储(ObjectStore)实例。

class User extends Record {

// --- OMITTED CODE --- //

/**

* Do not show the actual password for the user, only some asterixes with the same strlen as the password value.

*/

function password() {

$passLength = strlen($this->_getData('password'));

return str_repeat('*', $passLength);

}

/**

* Setting the user password is not affected.

*/

function setPassword($newPassword) {

$this->_setData('password', $newPassword);

}

/**

* fullName is a derived attribute from firstName and lastName

* and does not need to be stored as a variable.

* It is therefore read-only, and has no 'setFullname()' accessor method.

*/

function fullName() {

return $this->firstName() . " " . $this->lastName();

}

/**

* Spending limit returns the currency value of the user's spending limit.

* This value is stored as an INT in the database, eliminating the need

* for more expensive DECIMAL or DOUBLE column types.

*/

function spendingLimit() {

return $this->_getData('spendingLimit') / 100;

}

/**

* The set accessor multiplies the currency value by 100, so it can be stored in the database again

* as an INT value.

*/

function setSpendingLimit($newSpendLimit) {

$this->_setData('spendingLimit', $newSpendLimit * 100);

}

/**

* The validateSpendingLimit is not called in this class, but is called automatically by the _setData() method

* in the Record superclass, which in turn is called by the setSpendingLimit() method.

*/

function validateSpendingLimit(&$someLimit) {

if (is_numeric($someLimit) AND $someLimit >= 0) {

return true;

} else {

throw new Exception("Spending limit must be a non-negative integer"); //PHP5 only

}

}

}

/**

* Record is the superclass for all database objects.

*/

abstract class Record {

var $_data = array();

var $_modifiedKeys = array(); // keeps track of which fields have changed since record was created/fetched

/**

* Returns an element from the $_data associative array.

*/

function _getData($attributeName) {

return $this->_data[$attributeName];

}

/**

* If the supplied value passes validation, this

* sets the value in the $_data associative array.

*/

function _setData($attributeName, $value) {

if ($this->validateAttribute($attributeName, $value)) {

if ($value != $this->_data[$attributeName]) {

$this->_data[$attributeName] = $value;

$this->_modifiedKeys[] = $attributeName;

$this->didChange();

} else {

// the new value is identical to the current one

// no change necessary

}

}

}

/**

* For an attribute named "foo", this looks for a method named "validateFoo()"

* and calls it if it exists. Otherwise this returns true (meaning validation passed).

*/

function validateAttribute($attributeName, &$value) {

$methodName = 'validate' . $attributeName;

if (method_exists($this, $methodName)) {

return $this->$methodName($value);

} else {

return true;

}

}

function didChange() {

// notify the objectStore that this record changed

}

}

?>

现在我们拥有了一个抽象的超级类(Record),我们可以将User类里面大量的代码转移出来,而让这个User的子类来关注User的特殊项目如存取和验证方法。你可能已经注意到在我们的这个纪录类(Record class)没有任何的SQL代码。这并不是疏忽或者遗漏!对象存储类(ObjectStore class)(隐藏在第二部分)将负责所有和数据库的交互,还有我们的超级类Record的实例化。这样使我们的Record类更加瘦小而又有效率,而这对于评价我们处理大量对象的效率的时候是个重要因素。

如果你有兴趣看看这篇文章基于的完整的代码(不会出现如文中出现的所有的语法错误),可以给我的邮箱发信sam@360works.com

php对象好用吗,在数据库中使用对象的好处_php相关推荐

  1. android 对象数据库中,解析嵌套的JSON对象,并存储在数据库中的Android

    我只是试图让存储在我的JSON文件中的值,并将其保存到SQLite数据库:解析嵌套的JSON对象,并存储在数据库中的Android 这是我的JSON文件: { "list": { ...

  2. 对象的继承关系在数据库中的实现方式和PowerDesigner设计

    在面向对象的编程中,使用对象的继承是一个非常普遍的做法,但是在关系数据库管理系统RDBMS中,使用的是外键表示实体(表)之间的关系,那么对于继承关系,该怎么在RDBMS中表示呢?一般来说有3种实现方式 ...

  3. mysql对象资源管理器_恢复数据库可以使用对象资源管理器进行,也可以通过 完成...

    恢复数据库可以使用对象资源管理器进行,也可以通过 完成 更多相关问题 球根花卉经移植可促进新根萌发长势更好. Word中没有字数统计功能. "精"在上古跟"粗" ...

  4. 在SQL数据库中搜索对象的不同方法

    This article explores various ways to search for database objects in SQL database such as tables, st ...

  5. 使用PHP从Access数据库中提取对象,第2部分

    In the first part of this series we learned how to extract packaged objects from a legacy Access dat ...

  6. SQL Server数据库中的T-SQL如果存在语句概述

    This article walks through different versions of the T-SQL IF EXISTS statement for the SQL database ...

  7. 谈谈数据库中的日期、时间、日期时间、时间戳

    最近翻看以前的笔记,发现对于数据库日期时间和时间戳还不是太明白.下面从网上搜了下,整理到下面** Date 包含年月日如:2008-03-21 ,Time时间:19::00:00 在数据库中存储插入数 ...

  8. 关于数据库中的schema的注释

    关于数据库中的schema schema:模式,在SQL Server中文版文档中翻译为架构. 在数据库学习过程中,有一个schema概念,如概念模式.物理模式.内部模式.外部模式.逻辑模式,以及DB ...

  9. Oracle 12c CDB数据库中数据字典架构

    Oracle 12c CDB数据库中数据字典架构 使用sys用户和普通用户实验结果不同: SELECT * FROM V$PDBS; create table LHRTEST as select * ...

最新文章

  1. CSS之未知高度多行文本垂直居中
  2. 安卓中radiobutton不进入监听事件_Laravel模型事件的实现原理详解
  3. UVALive - 7270 Osu! Master
  4. 【AIX 命令学习】lsattr 显示一个给定设备或一种设备的属性
  5. npz文件转为npy_numpy的文件存储 .npy .npz 文件
  6. 前端学习(3289):react hook state-hook
  7. 南开大学java考试试题_2014秋学期南开大学《Java语言程序设计》在线作业附答案...
  8. 人人开源项目文档_为什么图对于您的开源项目文档至关重要
  9. openwrt环境下,使用externel commissioning组网openthread
  10. Android原生框架--Xui使用
  11. python项目总结
  12. Continous Integration.Continous Development,Continous Delivery之间的关系
  13. Pyinstaller Pmw
  14. 跨境支付的噱头,你读懂了吗?
  15. html表格一行设置颜色,更改表格中一行的颜色,html
  16. Linux下安装miniconda
  17. Java调用c/c++(JNI)最详细步骤
  18. shell脚本编程超级群-问题集合--持续更新中
  19. window定时计划任务
  20. 微信小程序使用wxparse,显示图片的相对路径问题

热门文章

  1. 刚刚!6月榜单:JS跌惨,Python又霸榜,C++再无翻身可能!
  2. 猴子选大王 java,PAT-JAVA-5-28 猴子选大王 (20分)
  3. flume获取mysql日志到hdfs_Hadoop实战:Flume输入日志到HDFS报错解决
  4. Redis 分布式集群搭建2022版本+密码(linux环境)
  5. docker-compose 实战案例
  6. Java 中判断连接Oracle数据库连接成功
  7. 第三篇:Spring Boot整合Servlet
  8. 用友u8服务器优化,用友U8v10.1运行速度慢的问题及解决方法
  9. 列赋值为列表_Pandas入门-3-新增数据列操作
  10. C语言 空指针 NULL - C语言零基础入门教程