淺析PHP中Collection 類的設(shè)計(jì)
更新時(shí)間:2013年06月21日 09:13:04 作者:
本篇文章是對(duì)PHP中Collection 類進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
用.net開(kāi)發(fā)已經(jīng)很多年了,最近接觸到php,發(fā)現(xiàn)php也很好玩。不過(guò)發(fā)現(xiàn)它里面沒(méi)有集合Collection類,只有數(shù)組,并且數(shù)組很強(qiáng)。這里我用數(shù)組來(lái)包裝成一個(gè)集合Collection,代碼如下:
class Collection{
private $_members=array();
public function addItem($obj,$key=null)
{
if($key)
{
if(isset($this->_members[$key]))
{
throw new exception("Key \"$key\" already in use!");
}
else
{
$this->_members[$key]=$obj;
}
}
else
{
$this->_members[]=$obj;
}
}
public function removeItem($key)
{
if(isset($this->_members[$key]))
{
unset($this->_members[$key]);
}
else
{
throw new exception("Invalid Key \"$key\"!");
}
}
public function getItem($key)
{
if(isset($this->_members[$key]))
{
return $this->_members[$key];
}
else
{
throw new exception("Invalid Key \"$key\"!");
}
}
public function Keys()
{
return array_keys($this->_members);
}
public function legth()
{
return sizeof($this->_members);
}
public function exists($key)
{
return (isset($this->_members[$key]));
}
}
現(xiàn)在我們來(lái)測(cè)試一下這個(gè)集合是否好用。
我們首先建立一個(gè)集合元素類Course:
class Course
{
private $_id;
private $_courseCode;
private $_name;
public function __construct($id,$courseCode,$name)
{
$this->_id=$id;
$this->_courseCode=$courseCode;
$this->_name=$name;
}
public function getName()
{
return $this->_name;
}
public function getID()
{
return $this->_id;
}
public function getCourseCode()
{
return $this->_courseCode;
}
public function __toString()
{
return $this->_name;
}
}
測(cè)試代碼如下:
$courses=new Collection();
$courses->addItem(new Course(1, "001", "語(yǔ)文"),1);
$courses->addItem(new Course(2, "002", "數(shù)學(xué)"),2);
$obj=$courses->getItem(1);
print $obj;
我想這個(gè)集合類應(yīng)該可以滿足我們平日開(kāi)發(fā)的需求了吧。
可是我們現(xiàn)在。net里面有個(gè)對(duì)象延遲加載,舉個(gè)例子來(lái)說(shuō)吧,假如現(xiàn)在有Student這個(gè)對(duì)象,它應(yīng)該有很多Course,但是我們希望在訪問(wèn)Course之前Course是不會(huì)加載的。也就是說(shuō)在實(shí)例化Student的時(shí)候Course個(gè)數(shù)為0,當(dāng)我們需要Course的時(shí)候它才真正從數(shù)據(jù)庫(kù)讀取相應(yīng)數(shù)據(jù)。就是需要我們把Collection做成惰性實(shí)例化。
修改后的Collection代碼如下:
class Collection {
private $_members = array(); //collection members
private $_onload; //holder for callback function
private $_isLoaded = false; //flag that indicates whether the callback
//has been invoked
public function addItem($obj, $key = null) {
$this->_checkCallback(); //_checkCallback is defined a little later
if($key) {
if(isset($this->_members[$key])) {
throw new KeyInUseException("Key \"$key\" already in use!");
} else {
$this->_members[$key] = $obj;
}
} else {
$this->_members[] = $obj;
}
}
public function removeItem($key) {
$this->_checkCallback();
if(isset($this->_members[$key])) {
unset($this->_members[$key]);
} else {
throw new KeyInvalidException("Invalid key \"$key\"!");
}
}
public function getItem($key) {
$this->_checkCallback();
if(isset($this->_members[$key])) {
return $this->_members[$key];
} else {
throw new KeyInvalidException("Invalid key \"$key\"!");
}
}
public function keys() {
$this->_checkCallback();
return array_keys($this->_members);
}
public function length() {
$this->_checkCallback();
return sizeof($this->_members);
}
public function exists($key) {
$this->_checkCallback();
return (isset($this->_members[$key]));
}
/**
* Use this method to define a function to be
* invoked prior to accessing the collection.
* The function should take a collection as a
* its sole parameter.
*/
public function setLoadCallback($functionName, $objOrClass = null) {
if($objOrClass) {
$callback = array($objOrClass, $functionName);
} else {
$callback = $functionName;
}
//make sure the function/method is valid
if(!is_callable($callback, false, $callableName)) {
throw new Exception("$callableName is not callable " .
"as a parameter to onload");
return false;
}
$this->_onload = $callback;
}
/**
* Check to see if a callback has been defined and if so,
* whether or not it has already been called. If not,
* invoke the callback function.
*/
private function _checkCallback() {
if(isset($this->_onload) && !$this->_isLoaded) {
$this->_isLoaded = true;
call_user_func($this->_onload, $this);
}
}
}
所需的Student如下:
class CourseCollection extends Collection {
public function addItem(Course $obj,$key=null) {
parent::addItem($obj,$key);
}
}
class Student{
private $_id;
private $_name;
public $course;
public function __construct($id,$name)
{
$this->_id=$id;
$this->_name=$name;
$this->course=new CourseCollection();
$this->course->setLoadCallback('loadCourses',$this);
}
public function getName()
{
return $this->_name;
}
public function getID()
{
return $this->_id;
}
public function __toString()
{
return $this->_name;
}
public function loadCourses(Collection $col)
{
$col->addItem(new Course(1, "001", "語(yǔ)文"),1);
$col->addItem(new Course(2, "002", "數(shù)學(xué)"),2);
}
}
調(diào)用代碼如下:
$student=new Student(1, "majiang");
print $student->getName();
print $student->course->getItem(1);
復(fù)制代碼 代碼如下:
class Collection{
private $_members=array();
public function addItem($obj,$key=null)
{
if($key)
{
if(isset($this->_members[$key]))
{
throw new exception("Key \"$key\" already in use!");
}
else
{
$this->_members[$key]=$obj;
}
}
else
{
$this->_members[]=$obj;
}
}
public function removeItem($key)
{
if(isset($this->_members[$key]))
{
unset($this->_members[$key]);
}
else
{
throw new exception("Invalid Key \"$key\"!");
}
}
public function getItem($key)
{
if(isset($this->_members[$key]))
{
return $this->_members[$key];
}
else
{
throw new exception("Invalid Key \"$key\"!");
}
}
public function Keys()
{
return array_keys($this->_members);
}
public function legth()
{
return sizeof($this->_members);
}
public function exists($key)
{
return (isset($this->_members[$key]));
}
}
現(xiàn)在我們來(lái)測(cè)試一下這個(gè)集合是否好用。
我們首先建立一個(gè)集合元素類Course:
復(fù)制代碼 代碼如下:
class Course
{
private $_id;
private $_courseCode;
private $_name;
public function __construct($id,$courseCode,$name)
{
$this->_id=$id;
$this->_courseCode=$courseCode;
$this->_name=$name;
}
public function getName()
{
return $this->_name;
}
public function getID()
{
return $this->_id;
}
public function getCourseCode()
{
return $this->_courseCode;
}
public function __toString()
{
return $this->_name;
}
}
測(cè)試代碼如下:
$courses=new Collection();
$courses->addItem(new Course(1, "001", "語(yǔ)文"),1);
$courses->addItem(new Course(2, "002", "數(shù)學(xué)"),2);
$obj=$courses->getItem(1);
print $obj;
我想這個(gè)集合類應(yīng)該可以滿足我們平日開(kāi)發(fā)的需求了吧。
可是我們現(xiàn)在。net里面有個(gè)對(duì)象延遲加載,舉個(gè)例子來(lái)說(shuō)吧,假如現(xiàn)在有Student這個(gè)對(duì)象,它應(yīng)該有很多Course,但是我們希望在訪問(wèn)Course之前Course是不會(huì)加載的。也就是說(shuō)在實(shí)例化Student的時(shí)候Course個(gè)數(shù)為0,當(dāng)我們需要Course的時(shí)候它才真正從數(shù)據(jù)庫(kù)讀取相應(yīng)數(shù)據(jù)。就是需要我們把Collection做成惰性實(shí)例化。
修改后的Collection代碼如下:
復(fù)制代碼 代碼如下:
class Collection {
private $_members = array(); //collection members
private $_onload; //holder for callback function
private $_isLoaded = false; //flag that indicates whether the callback
//has been invoked
public function addItem($obj, $key = null) {
$this->_checkCallback(); //_checkCallback is defined a little later
if($key) {
if(isset($this->_members[$key])) {
throw new KeyInUseException("Key \"$key\" already in use!");
} else {
$this->_members[$key] = $obj;
}
} else {
$this->_members[] = $obj;
}
}
public function removeItem($key) {
$this->_checkCallback();
if(isset($this->_members[$key])) {
unset($this->_members[$key]);
} else {
throw new KeyInvalidException("Invalid key \"$key\"!");
}
}
public function getItem($key) {
$this->_checkCallback();
if(isset($this->_members[$key])) {
return $this->_members[$key];
} else {
throw new KeyInvalidException("Invalid key \"$key\"!");
}
}
public function keys() {
$this->_checkCallback();
return array_keys($this->_members);
}
public function length() {
$this->_checkCallback();
return sizeof($this->_members);
}
public function exists($key) {
$this->_checkCallback();
return (isset($this->_members[$key]));
}
/**
* Use this method to define a function to be
* invoked prior to accessing the collection.
* The function should take a collection as a
* its sole parameter.
*/
public function setLoadCallback($functionName, $objOrClass = null) {
if($objOrClass) {
$callback = array($objOrClass, $functionName);
} else {
$callback = $functionName;
}
//make sure the function/method is valid
if(!is_callable($callback, false, $callableName)) {
throw new Exception("$callableName is not callable " .
"as a parameter to onload");
return false;
}
$this->_onload = $callback;
}
/**
* Check to see if a callback has been defined and if so,
* whether or not it has already been called. If not,
* invoke the callback function.
*/
private function _checkCallback() {
if(isset($this->_onload) && !$this->_isLoaded) {
$this->_isLoaded = true;
call_user_func($this->_onload, $this);
}
}
}
所需的Student如下:
復(fù)制代碼 代碼如下:
class CourseCollection extends Collection {
public function addItem(Course $obj,$key=null) {
parent::addItem($obj,$key);
}
}
class Student{
private $_id;
private $_name;
public $course;
public function __construct($id,$name)
{
$this->_id=$id;
$this->_name=$name;
$this->course=new CourseCollection();
$this->course->setLoadCallback('loadCourses',$this);
}
public function getName()
{
return $this->_name;
}
public function getID()
{
return $this->_id;
}
public function __toString()
{
return $this->_name;
}
public function loadCourses(Collection $col)
{
$col->addItem(new Course(1, "001", "語(yǔ)文"),1);
$col->addItem(new Course(2, "002", "數(shù)學(xué)"),2);
}
}
調(diào)用代碼如下:
$student=new Student(1, "majiang");
print $student->getName();
print $student->course->getItem(1);
相關(guān)文章
PHP實(shí)現(xiàn)刪除非站內(nèi)外部鏈接實(shí)例代碼
一般在做網(wǎng)站系統(tǒng)的時(shí)候,出于優(yōu)化等因素的考慮需要再添加文章的時(shí)候刪除掉不是本站的鏈接,對(duì)于這一要求可以通過(guò)讓PHP處理下文章內(nèi)容,來(lái)達(dá)到文章外部鏈接的自動(dòng)刪除的效果。需要的朋友可以參考下2014-06-06
PHP實(shí)現(xiàn)基于文本的簡(jiǎn)易搜索引擎功能
這篇文章給大家介紹了PHP實(shí)現(xiàn)基于文本的簡(jiǎn)易搜索引擎功能,讓這個(gè)功能可以在小型網(wǎng)站或者特定數(shù)據(jù)集內(nèi)提供快速的關(guān)鍵字搜索能力,非常適合沒(méi)有使用復(fù)雜數(shù)據(jù)庫(kù)搜索引擎(如Elasticsearch)的場(chǎng)景,需要的朋友可以參考下2024-02-02
php 獲取mysql數(shù)據(jù)庫(kù)信息代碼
有時(shí)候我們需要知道m(xù)ysql數(shù)據(jù)庫(kù)中的一些情況,好在php提供了一些內(nèi)置方法與函數(shù),大家了解下了。2009-03-03
用PHP實(shí)現(xiàn)的隨機(jī)廣告顯示代碼
用PHP實(shí)現(xiàn)的隨機(jī)廣告顯示代碼...2007-06-06
php $_SERVER windows系統(tǒng)與linux系統(tǒng)下的區(qū)別說(shuō)明
本篇文章主要是對(duì)php $_SERVER windows系統(tǒng)與linux系統(tǒng)下的區(qū)別進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-02-02
golang 調(diào)用 php7詳解及實(shí)例
這篇文章主要介紹了golang 調(diào)用 php7詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-01-01

