用.net开发已经很多年了,最近接触到php,发现php也很好玩。不过发现它里面没有集合Collection类,只有数组,并且数组很强。这里我用数组来包装成一个集合Collection,代码如下: <div class="codetitle"><a style="CURSOR: pointer" data="69256" class="copybut" id="copybut69256" onclick="doCopy('code69256')"> 代码如下:<div class="codebody" id="code69256"> 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])); } }
现在我们来测试一下这个集合是否好用。 我们首先建立一个集合元素类Course: <div class="codetitle"><a style="CURSOR: pointer" data="60970" class="copybut" id="copybut60970" onclick="doCopy('code60970')"> 代码如下:<div class="codebody" id="code60970"> 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; } }
测试代码如下: $courses=new Collection(); $courses->addItem(new Course(1,"001","语文"),1); $courses->addItem(new Course(2,"002","数学"),2); $obj=$courses->getItem(1); print $obj; 我想这个集合类应该可以满足我们平日开发的需求了吧。 可是我们现在。net里面有个对象延迟加载,举个例子来说吧,假如现在有Student这个对象,它应该有很多Course,但是我们希望在访问Course之前Course是不会加载的。也就是说在实例化Student的时候Course个数为0,当我们需要Course的时候它才真正从数据库读取相应数据。就是需要我们把Collection做成惰性实例化。 修改后的Collection代码如下: <div class="codetitle"><a style="CURSOR: pointer" data="38943" class="copybut" id="copybut38943" onclick="doCopy('code38943')"> 代码如下:<div class="codebody" id="code38943"> 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如下: <div class="codetitle"><a style="CURSOR: pointer" data="78464" class="copybut" id="copybut78464" onclick="doCopy('code78464')"> 代码如下:<div class="codebody" id="code78464"> 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,1); $col->addItem(new Course(2,2); } }
调用代码如下: $student=new Student(1,"majiang"); print $student->getName(); print $student->course->getItem(1);
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|