首頁 php教程 php手册 PHP数据库操作面向对象的优点

PHP数据库操作面向对象的优点

Jun 21, 2016 am 09:07 AM
function the this

对象|数据|数据库

我们都知道如何从Mysql获取我们需要的行(记录),读取数据,然后存取一些改动。很明显也很直接,在这个过程背后也没有什么拐弯抹角的。然而对于我们使用面对对象的程序设计(OOP)来管理我们数据库中的数据时,这个过程就需要大大改进一下了。这篇文章将对如何设计一个面对对象的方式来管理数据库的记录做一个简单的描述。你的数据当中的所有内部逻辑关系将被封装到一个非常条理的记录对象,这个对象能够提供专门(专一)的确认代码系统,转化以及数据处理。随着Zend Engine2 和PHP5的发布,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类更加瘦小而又有效率,而这对于评价我们处理大量对象的效率的时候是个重要因素。



本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1662
14
CakePHP 教程
1418
52
Laravel 教程
1311
25
PHP教程
1261
29
C# 教程
1234
24
2 個月不見,人形機器人 Walker S 會摺衣服了 2 個月不見,人形機器人 Walker S 會摺衣服了 Apr 03, 2024 am 08:01 AM

機器之能報道編輯:吳昕國內版的人形機器人+大模型組隊,首次完成疊衣服這類複雜柔性材料的操作任務。隨著融合了OpenAI多模態大模型的Figure01揭開神秘面紗,國內同行的相關進展一直備受關注。就在昨天,國內"人形機器人第一股"優必選發布了人形機器人WalkerS深入融合百度文心大模型後的首個Demo,展示了一些有趣的新功能。現在,得到百度文心大模型能力加持的WalkerS是這個樣子的。和Figure01一樣,WalkerS沒有走動,而是站在桌子後面完成一系列任務。它可以聽從人類的命令,折疊衣物

function是什麼意思 function是什麼意思 Aug 04, 2023 am 10:33 AM

function是函數的意思,是一段具有特定功能的可重複使用的程式碼區塊,是程式的基本組成單元之一,可以接受輸入參數,執行特定的操作,並傳回結果,其目的是封裝一段可重複使用的程式碼,提高程式碼的可重複使用性和可維護性。

'enumerate()'函數在Python中的用途是什麼? 'enumerate()'函數在Python中的用途是什麼? Sep 01, 2023 am 11:29 AM

在本文中,我們將了解enumerate()函數以及Python中「enumerate()」函數的用途。什麼是enumerate()函數? Python的enumerate()函數接受資料集合作為參數並傳回一個枚舉物件。枚舉物件以鍵值對的形式傳回。 key是每個item對應的索引,value是items。語法enumerate(iterable,start)參數iterable-傳入的資料集合可以作為枚舉物件傳回,稱為iterablestart-顧名思義,枚舉物件的起始索引由start定義。如果我們忽

MySQL.proc表的作用與功能詳解 MySQL.proc表的作用與功能詳解 Mar 16, 2024 am 09:03 AM

MySQL.proc表的功能與功能詳解MySQL是一種流行的關係型資料庫管理系統,開發者在使用MySQL時常常會涉及到預存程序(StoredProcedure)的建立與管理。而MySQL.proc表則是一個非常重要的系統表,它儲存了資料庫中所有的預存程序的相關信息,包括預存程序的名稱、定義、參數等。在本文中,我們將詳細解釋MySQL.proc表的作用與功能

聊聊Vue2為什麼能透過this存取各種選項中屬性 聊聊Vue2為什麼能透過this存取各種選項中屬性 Dec 08, 2022 pm 08:22 PM

這篇文章帶大家解讀vue原始碼,來介紹一下Vue2中為什麼可以使用 this 存取各種選項中的屬性,希望對大家有幫助!

一篇搞懂this指向,追趕70%的前端人 一篇搞懂this指向,追趕70%的前端人 Sep 06, 2022 pm 05:03 PM

同事因為this指向的問題卡住的bug,vue2的this指向問題,使用了箭頭函數,導致拿不到對應的props。當我跟他介紹的時候他竟然不知道,隨後也刻意的看了一下前端交流群,至今最起碼還有70%以上的前端程式設計師搞不明白,今天給大家分享一下this指向,如果啥都沒學會,請給我一個大嘴巴子。

Vue.use函數的用法與作用 Vue.use函數的用法與作用 Jul 24, 2023 pm 06:09 PM

Vue.use函數的用法和作用Vue是一款流行的前端框架,它提供了許多有用的功能和功能。其中之一就是Vue.use函數,它可以讓我們在Vue應用中使用插件。本文將介紹Vue.use函數的用法和作用,並且提供一些程式碼範例。 Vue.use函數的基本用法非常簡單,只需在Vue實例化之前呼叫它,並傳入要使用的插件作為參數。以下是一個簡單的範例://引入並使用插件

在PHP中的clearstatcache()函數 在PHP中的clearstatcache()函數 Sep 07, 2023 am 09:33 AM

clearstatcache()函數用於清除檔案狀態快取。 PHP快取以下函數傳回的資訊−stat()lstat()file_exists()is_writable()is_readable()is_executable()is_file()is_dir()filegroup()fileowner()filesize()filetype()fileperms()這樣做是為了提供更好的性能。語法voidclearstatecache()參數NA傳回值clearstatcache(

See all articles