CodingBison

PHP supports object-oriented programming. Object-oriented programming allows us to create objects based on a common template, known as a class. Simply put, a class is an aggregation of data and functions that interact with the data. The data is called properties/variables and the functions are called methods.

To define a class in PHP, we can use the keyword "class" followed by the name of the class. Next, the class can define both variables (properties) and functions (methods). These definitions are similar to definition of regular variables and functions, except that these are defined within the scope of the class.

Once a class has been defined, we can use the keyword "new" to create an object based on that class. Objects created from the class are instances of that class and automatically acquire both properties and methods of the class.

We demonstrate the concepts of class and object using a simple example.

This example (provided below) defines a PHP class "BasicUser". This "BasicUser" class holds both variables and methods. The variables ($userID, $userName, and $userAge) hold information about a user and the methods (set_userID(), set_userName(), set_userAge(), print_userinfo()) handle that information. After defining the "BasicUser" class, we use the keyword "new" to create "$me_as_user" object.

The example also uses "$this" variable -- when used inside the scope of a class, "$this" refers to the current object.

 <?php
 /* Definition of "BasicUser" class */
 class BasicUser {
     /* Following variables are properties of "BasicUser" class */
     var $userID, $userName, $userAge;

     /* Following functions are methods of "BasicUser" class */
     function set_userID($varID) {
         $this->userID = $varID;
     }

     function set_userName($varName) {
         $this->userName = $varName;
     }

     function set_userAge($varAge) {
         $this->userAge = $varAge;
     }

     function print_userinfo() {
         echo "Printing My Details:<br>";
         echo "Userid: $this->userID<br>";
         echo "Name: $this->userName<br>";
         echo "Age: $this->userAge<br>";
     }
 }

 /* Create $me_as_user object based on "BasicUser" class */
 $me_as_user = new BasicUser();
 $me_as_user->set_userID("ksimon");
 $me_as_user->set_userName("Karuna Simon");
 $me_as_user->set_userAge(32);
 $me_as_user->print_userinfo();
 ?>

To run the above program, let us first store this file (let us name it "object.php") at a location that is accessible to the web server (in Fedora/Red Hat Linux, the default location for web server is "/var/www/html/"). Also, we need to ensure that the web server itself is running. When we load this file, we would see the following output on the web server.

 Printing My Details: 
 Userid: ksimon
 Name: Karuna Simon
 Age: 32

PHP's object-oriented approach is flexible. For example, PHP allows us to add variables to an object even when the parent class does not define/support it! Thus, if we wanted to add a field "userCity" to the $me_as_user object, then all we would have to do is to refer it using "$me_as_user->userCity = 'Chicago'". With this, PHP automatically adds a new variable to the object.

However, PHP offers no similar flexibility to add an object method on the fly. Adding a method dynamically (e.g., "$me_as_user->set_userCity('Chicago')") would simply be an error.

Constructors and Destructors

PHP (starting with PHP5) provides provision for two special-purpose methods: constructor and destructor methods respectively. Each class can define their own constructor and destructor methods by defining __construct() and __destruct() methods respectively. PHP automatically calls __construct() when the object is created and would automatically call __destruct() method when the object goes out of scope.

However, PHP4 and prior versions do not provide provision for __construct() and __destruct() methods. Instead, for constructor method, we can define a function with the same name as that of the class name. Thus, if the above program were to define a function as "function BasicUser()", then that would act as a constructor method for PHP4 and prior versions. PHP4 and prior versions do not provide a way to define destructor method().

Like any other PHP function, we can pass parameters to __constructor() method as well. Since the class uses this method for initialization, we can use this method to pass parameters to initialize values of object properties instead of explicitly assigning them later. The following code demonstrate this behavior.

 <?php
 class BasicUser {
     var $userID, $userName, $userAge;

     /* The constructor method initializes class properties */
     function __construct($varID, $varName, $varAge) {
         echo "Calling Constructor() function for BasicUser class <br>";
         echo "We can put all initialization routines here <br>";
         $this->userID = $varID;
         $this->userName = $varName;
         $this->userAge = $varAge;
     }   

     function __destruct() {
         echo "<br>Calling Destructor() function for BasicUser class <br>";
         echo "We can put all cleanup routines here <br>";
     }   

     function print_userinfo() {
         echo "<br>Printing My Details: <br>";
         echo "Userid: $this->userID<br>";
         echo "Name: $this->userName<br>";
         echo "Name: $this->userAge<br>";
     }   
 }

 $me_as_user = new BasicUser("ksimon", "Karuna Simon", 32);
 $me_as_user->print_userinfo();
 ?>

As we can see from the following output, __construct() method gets called at the beginning when the object is getting created and __destruct() method gets called when the object goes out of scope.

 Calling Constructor() function for BasicUser class 
 We can put all initialization routines here 

 Printing My Details: 
 Userid: ksimon
 Name: Karuna Simon
 Name: 32

 Calling Destructor() function for BasicUser class 
 We can put all cleanup routines here 

Private Keyword

PHP allows us to design classes by taking into consideration the nature of object data. In this regard, PHP classes can use "private" keyword to make their variables visible only inside the class. Accessing such private variables outside the class would be an error.

Let us illustrate this using an example. If we were to design a class to hold user details along with user's Social Security Number (SSN). Since SSN is confidential, we can use "private" to ensure that the variable is not visible outside the class.

The example (provided below) uses the "private" keyword to characterize $userId and $userSSN variables. The class uses the __construct() method to update the values of these two private variables. Since the class does not have any method to update these value and since these values are not visible outside the class, using the __construct() method is the only way to add these values. Trying to access a private variable outside the class (for example, doing "$me_as_user->userSSN = 787878878" in the following program) would lead to a run-time error.

 <?php
 class BasicUser {
     var $userName, $userAge;
     /* The following are private variables */
     private $userID, $userSSN;

     function __construct($varID, $varName, $varAge, $varSSN) {
         echo "Initializing the BasicUser object...";
         $this->userID = $varID;
         $this->userName = $varName;
         $this->userAge = $varAge;
         $this->userSSN = $varSSN;
     }   

     function set_userName($varName) {
         $this->userName = $varName;
     }   

     function set_userAge($varAge) {
         $this->userAge = $varAge;
     }   

     function print_userinfo() {
         echo "<br>Printing My Details: <br>";
         echo "Userid: $this->userID<br>";
         echo "Name: $this->userName<br>";
         echo "Age: $this->userAge<br>";
         echo "SSN: $this->userSSN<br>";
     }   
 }

 $me_as_user = new BasicUser("ksimon", "Karuna Simon", 32, 123456789);
 $me_as_user->print_userinfo();

 $me_as_user->set_userName("Karuna Simon Gilbert");
 $me_as_user->set_userAge(34);
 $me_as_user->print_userinfo();
 ?>

We provide the output of this program below.

 Initializing the BasicUser object... 
 Printing My Details: 
 Userid: ksimon
 Name: Karuna Simon
 Age: 32
 SSN: 123456789

 Printing My Details: 
 Userid: ksimon
 Name: Karuna Simon Gilbert
 Age: 34
 SSN: 123456789

A related design consideration is providing functions that set properties of an object. If a property (variable) does not need to be visible outside the class then we can make the variable private and provide a dedicated set method to explicitly update its value. If an application wishes to update the property, then it can use the set method. Thus, the above program can add set_userID() and set_userSSN() methods to update these private variables.

Copying PHP objects

When we copy an object, PHP returns a reference to the original object instead of making an actual copy (this was added as part of PHP5 and so versions prior to that made an actual copy). Using a reference instead of making an actual copy is efficient since it is much cheaper to return the reference than to make a copy of the entire object. However, there is one catch! If we modify the behavior of the object via the reference copy, then the original object also gets modified!

We provide a simple example to demonstrate this behavior. We create "$me_as_user" as an object based on the "BasicUser" class and then make a copy of it. When we modify the userName variable using the copy, $copy_me_as_user, then the original object also gets modified (as is confirmed by the subsequent output). For PHP4 and earlier, the way to use a reference instead of copy would be to pass it explicitly using the reference operator, "&": "$copyref_me_as_user = &$me_as_user;".

 <?php
 class BasicUser {
     function __construct($varID, $varName) {
         echo "Initializing the BasicUser object...";
         $this->userID = $varID;
         $this->userName = $varName;
     }   

     function print_userinfo() {
         echo "<br>Printing My Details: <br>";
         echo "Userid: $this->userID<br>";
         echo "Name: $this->userName<br>";
     }   
 }

 $me_as_user = new BasicUser("ksimon", "Karuna Simon");
 $me_as_user->print_userinfo();

 $copy_me_as_user = $me_as_user;
 $copy_me_as_user->userName = "Lisa Simpson"; 

 $copy_me_as_user->print_userinfo(); 
 $me_as_user->print_userinfo();
 ?>

The output (provided below) confirms that modifying the copy object ends up modifying the original object as well. If we do need to create two independent copies of the object (such that updating one object does not affect the other), then a safe approach would be to create another object (using the new() method) and then manually copy variables from the original object to the new one.

 Initializing the BasicUser object...
 Printing My Details:
 Userid: ksimon
 Name: Karuna Simon

 Printing My Details:
 Userid: ksimon
 Name: Lisa Simpson

 Printing My Details:
 Userid: ksimon
 Name: Lisa Simpson




comments powered by Disqus