我們都知道如何從Mysql獲取我們需要的行(記錄),讀取數(shù)據(jù),然后存取一些改動(dòng)。很明顯也很直接,在這個(gè)過程背后也沒有什么拐彎抹角的。然而對于我們使用面對對象的程序設(shè)計(jì)(OOP)來管理我們數(shù)據(jù) " /> 中文字幕免费视频精品一,在线观看黄免费,性色xxx视频

一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

PHP數(shù)據(jù)庫操作面向?qū)ο蟮膬?yōu)點(diǎn)


我們都知道如何從Mysql獲取我們需要的行(記錄),讀取數(shù)據(jù),然后存取一些改動(dòng)。很明顯也很直接,在這個(gè)過程背后也沒有什么拐彎抹角的。然而對于我們使用面對對象的程序設(shè)計(jì)(OOP)來管理我們數(shù)據(jù)庫中的數(shù)據(jù)時(shí),這個(gè)過程就需要大大改進(jìn)一下了。這篇文章將對如何設(shè)計(jì)一個(gè)面對對象的方式來管理數(shù)據(jù)庫的記錄做一個(gè)簡單的描述。你的數(shù)據(jù)當(dāng)中的所有內(nèi)部邏輯關(guān)系將被封裝到一個(gè)非常條理的記錄對象,這個(gè)對象能夠提供專門(專一)的確認(rèn)代碼系統(tǒng),轉(zhuǎn)化以及數(shù)據(jù)處理。隨著Zend Engine2 和php5的發(fā)布,php開發(fā)者將會(huì)擁有更強(qiáng)大的面對對象的工具來輔助工作,這將使這個(gè)過程(面對對象地管理數(shù)據(jù)庫)更有吸引力。


以下列出了一些使用對象來描敘你的數(shù)據(jù)庫的有利方面:


存取方法(Accessor methods)將會(huì)使你對屬性的讀取和寫入過程做到完全的控制
每一級(jí)的每個(gè)記錄和屬性(的操作)都有確認(rèn)過程
從關(guān)系表中智能的獲取對象
重復(fù)使用的邏輯方法意味著所有的數(shù)據(jù)交互都要通過相同的基礎(chǔ)代碼(codebase),這將使維護(hù)變得更加簡單
代碼簡單,因?yàn)椴煌挠涗浀膬?nèi)部邏輯都已經(jīng)包含在各自所處的類(class)當(dāng)中,而不是繁瑣的庫(lib)文件
在手工編寫代碼和SQL查詢語句時(shí),出錯(cuò)的機(jī)會(huì)將更少


存取方法(Accessor methods)

存取方式是通過類給實(shí)例(instance)的變量賦值。一個(gè)例子,我有一個(gè)叫User的類,并且有一個(gè)實(shí)例$username,我會(huì)寫這樣的存取方法(函數(shù)),User->username()和User->setUsername()用來返回和給實(shí)例賦值。



<?php
class User {
var $username;

function username() {
return $this->username;
}

function setUsername($newUsername) {
$this->username = $newUsername;
}
}
?>




這里有很好的理由讓我們編寫這樣的“特別的代碼”。它將使開發(fā)者更靈活的改變類的繁瑣的工作,因?yàn)檫@一過程將不需要其他的使用類的php代碼。讓我們來看看下面這個(gè)更加完善的可信賴的User類。


變量$username將不復(fù)存在,所有的東西都被整合的放在數(shù)組$_data當(dāng)中
如果username是空的話,username()函數(shù)將提供一個(gè)缺省(默認(rèn))的值給它
setUsername()過程將在接受值之前確認(rèn)username是否合乎標(biāo)準(zhǔn)格式(如字長等)

<?php
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;
}
}
?>



顯而易見,這對我們控制存取對象的數(shù)據(jù)有很大幫助。如果一個(gè)程序員已經(jīng)直接地存取username的信息,以上代碼的變化將會(huì)破壞他的代碼。然而我們可以使用(類的)存取方法,就像上面代碼中注釋的那樣,添加一個(gè)驗(yàn)證的功能而不需要改變?nèi)魏纹渌臇|西。注意username的驗(yàn)證(例子當(dāng)中是不能超過12字節(jié))代碼是獨(dú)立在setUsername()方法之外的。從驗(yàn)證到存儲(chǔ)到數(shù)據(jù)庫的過程輕而易舉。而且,這是個(gè)非常好的單憑經(jīng)驗(yàn)的方法,一個(gè)方法或一個(gè)類需要做的越少,它的重復(fù)使用的機(jī)會(huì)將會(huì)越大。這在你開始寫一個(gè)子類時(shí)更加明顯,假如你需要一個(gè)子類,并且又要跳過(忽略)父類方法(行為)中的一些特殊的細(xì)節(jié),如果(針對這個(gè)細(xì)節(jié)的)方法很小而又精細(xì),(修改它)只是一瞬間的過程,而如果這個(gè)方法非常臃腫,針對多種目的,你可能將在復(fù)制子類中大量代碼中郁悶而終。

比方說,假如Admin是User類的一個(gè)子類。我們對adamin的用戶可能會(huì)有不同的,相對苛刻一些的密碼驗(yàn)證方法。最好是跨過父類的驗(yàn)證方法和整個(gè)setUsername()方法(在子類中重寫)。

更多關(guān)于存取器(Accessor)
下面是一些其他的例子來說明如何使存取器用的更有效果。很多時(shí)候我們可能要計(jì)算結(jié)果,而不是簡單的返回?cái)?shù)組中的靜態(tài)數(shù)據(jù)。存取方法還能做的一個(gè)有用的事情就是更新(updating)緩存中的值。當(dāng)所有的變動(dòng)(對數(shù)據(jù)的所有操作)都要通過setX()方法的時(shí)候,這正是我們根據(jù)X來重置緩存中的值的時(shí)刻。

于是我們的這個(gè)類層次變得更加明了:

內(nèi)部變量$_data的處理被替換成受保護(hù)的私有方法(private methods)_getData()和_setData()
這類方法被轉(zhuǎn)移到被稱作記錄(Record)的抽象的超級(jí)類(super class),當(dāng)然它是User類下的子類
這個(gè)記錄類(Record class)掌握所有存取數(shù)組$_data的細(xì)節(jié),在內(nèi)容被修改之前調(diào)用驗(yàn)證的方法,以及將變更的通知發(fā)給記錄(Records),就像發(fā)給中心對象存儲(chǔ)(ObjectStore)實(shí)例。

<?php
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
}
}
?>



現(xiàn)在我們擁有了一個(gè)抽象的超級(jí)類(Record),我們可以將User類里面大量的代碼轉(zhuǎn)移出來,而讓這個(gè)User的子類來關(guān)注User的特殊項(xiàng)目如存取和驗(yàn)證方法。你可能已經(jīng)注意到在我們的這個(gè)紀(jì)錄類(Record class)沒有任何的SQL代碼。這并不是疏忽或者遺漏!對象存儲(chǔ)類(ObjectStore class)(隱藏在第二部分)將負(fù)責(zé)所有和數(shù)據(jù)庫的交互,還有我們的超級(jí)類Record的實(shí)例化。這樣使我們的Record類更加瘦小而又有效率,而這對于評(píng)價(jià)我們處理大量對象的效率的時(shí)候是個(gè)重要因素。

php技術(shù)PHP數(shù)據(jù)庫操作面向?qū)ο蟮膬?yōu)點(diǎn),轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 香蕉大久久 | 国产成人精品久久亚洲高清不卡 | 四虎8848精品永久在线观看 | 91精选在线观看 | 成人丝袜激情一区二区 | 香蕉521av成人网 | 蕾丝视频福利网站 | 亚洲综合在线网 | 欧美精品高清在线xxxx | 99精品视频在线成人精彩视频 | 欧美在线性视频 | 亚洲综合色一区二区三区另类 | 伊人婷婷在线 | 日韩久久久精品首页 | 美女张开腿让男人桶爽的免费动漫 | 国产在线观看人成激情视频 | 丝袜精品 欧美 亚洲 自拍 | 五月婷婷丁香综合 | 亚洲成精品动漫久久精久 | 最新福利小视频在线播放 | 精品国产成人a区在线观看 精品国产成人a在线观看 | 天天色天天拍 | 国产99区 | 免费一区二区三区视频导航 | 久久香蕉精品 | 午夜hhh视频在线观看hhhh | 91麻豆精品福利在线观看 | 久久久青草青青国产亚洲免观 | 美女毛片免费看 | 亚洲天堂久 | 色五月婷婷成人网 | 成人福利在线观看免费视频 | 国内免费视频成人精品 | 91国自产精品中文字幕亚洲 | 91久久精品国产亚洲 | 日本一区二区三区视频在线 | 亚洲一二三四 | 奇米影视狠狠干 | 91精品在线免费视频 | 亚洲一区二区三区精品影院 | 日本国产最新一区二区三区 |