本篇文章是对PHP中Collection 类进行了详细的分析介绍,需要的朋友参考下用.net开发已经很多年了,最近接触到php,发现php也很好玩。不过发现它里面没有集合Collection类,只有数组,并且数组很强。这里我用数组来包装成一个集合Collection,代码如下:复制代码代码如下:PHP 8.5.5 PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载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:复制代码代码如下: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代码如下:复制代码代码如下: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如下:
复制代码代码如下:
