Analysis of Collection class design in PHP

Source: Internet
Author: User
This article provides a detailed analysis of Collection classes in PHP. For more information, see. net. it has been developed for many years. Recently, I have been using php and found that php is also very fun. However, it is found that there is no Collection class in it, only an array, and the array is very strong. Here, I use arrays to package a Collection. the code is as follows:
The code is as follows:
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]);
}
}

Now let's test whether this set is useful.
First, we create a set element class Course:
The code is as follows:
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;
}
}

The test code is as follows:
$ Courses = new Collection ();
$ Courses-> addItem (new Course (1, "001", ""), 1 );
$ Courses-> addItem (new Course (2, "002", "mathematics"), 2 );
$ Obj = $ courses-> getItem (1 );
Print $ obj;
I think this collection class can meet our daily development needs.
But now. Net has an object that is delayed to load. for example, if there is a Student object, it should have a lot of Course, but we hope the Course will not load before accessing the Course. That is to say, when the Student is instantiated, the number of Course is 0. when we need Course, it actually reads the corresponding data from the database. That is, we need to make the Collection into a inert instantiation.
The modified Collection code is as follows:
The code is as follows:
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 shocould take a collection as
* 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 );
}
}
}

The required Student is as follows:
The code is as follows:
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 ('loadcourse', $ 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", ""), 1 );
$ Col-> addItem (new Course (2, "002", "mathematics"), 2 );
}
}

The call code is as follows:
$ Student = new Student (1, "majiang ");
Print $ student-> getName ();
Print $ student-> course-> getItem (1 );

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.