SlideShare une entreprise Scribd logo
1  sur  41
Télécharger pour lire hors ligne
Definition of a Class


A class is user defined data type that contains attributes or data members; and methods which
work on the data members. (You will learn more about data members and methods in following
tutorials. This tutorial focuses only on learning how to create a Class in PHP5)

To create a class, you need to use the keyword class followed by the name of the class. The
name of the class should be meaningful to exist within the system (See note on naming a class
towards the end of the article). The body of the class is placed between two curly brackets within
which you declare class data members/variables and class methods.

Example of a Class:

class Customer {
        private $first_name, $last_name;

         public function setData($first_name, $last_name) {
                 $this->first_name = $first_name;
                 $this->last_name = $last_name;
         }

         public function printData() {
                 echo $this->first_name . " : " . $this->last_name;
         }
}



In the above program, Customer is the name of the class and $first_name/$last_name are
attributes or data members. setData() and printData() are methods of a class. We will discuss
more about attributes and members in the upcoming articles on PHP5 OOPS Tutorials series.



Definition of an Object
An object is a living instance of a class. This means that an object is created from the definition
of the class and is loaded in memory. A good analogy to understand this is to compare objects
with humans - and understand that all of us (you and I) are objects. If God wants to send a
human to earth, what is easy for Him to do? Create and define properties and attributes of each
human separately or create a one time template and generate objects out if it. Therefore, this
onetime template is a Class and you, I & everyone in this world is an object - that is a living
instance of class Human.

Creating Objects in PHP5 Class

To create an object of a PHP5 class we use the keyword new. Below is the syntax style of how
to create objects in PHP5:
$obj_name = new ClassName();

In the above syntax style, $obj_name is a variable in PHP. ‘new’ is the keyword which is
responsible for creating a new instance of ClassName.



class Customer {
        private $first_name, $last_name;

         public function getData($first_name, $last_name) {
                 $this->first_name = $first_name;
                 $this->last_name = $last_name;
         }

         public function printData() {
                 echo $this->first_name . " : " . $this->last_name;
         }
}

$c1 = new Customer();
$c2 = new Customer();

In the above example $c1 and $c2 are two objects of the Customer Class. Both these objects are
allocated different blocks in the memory. Look at the diagram below:




Therefore, an object is a living instance of a class. Each object / living instance has its own
memory space that can hold independent data values.

Definition of an class attribute
An attribute is also know as data members and is used to hold data of a class. The data that it
holds are specific to the nature of the class in which it has been defined. For example, a
Customer class would hold data related to a customer, an Order class would hold data related a
an order.
Attributes can either be public, private or protected - the default being public.
These are called Access Specifiers.



Example Code:

class Customer {
        private $first_name, $last_name;
        private $outstanding_amount = 0; //example of default value

         public function getData($first_name, $last_name) {
                 $this->first_name = $first_name;
                 $this->last_name = $last_name;
         }

         public function printData() {
                 echo $this->first_name . " : " . $this->last_name;
         }
}

$c1 = new Customer();



Objects as Attributes

In addition to declaring attributes as intrinsic data types (int, string, etc), you can also declare
data members as objects of another class. This is called aggregation in Object Oriented Analysis
and Design (OOAD). Lets look at an example below:

class Customer {
        private $first_name, $last_name;
        private $outstanding_amount = 0; //example of default value

         public function getData($first_name, $last_name) {
                 $this->first_name = $first_name;
                 $this->last_name = $last_name;
         }

         public function printData() {
                 echo $this->first_name . " : " . $this->last_name;
         }
}

class Order {
        private $order_id;
        private $customer;

         public setCust(Customer $c) {
                 $this->customer = $c;
         }
}
$c1 = new Customer();
$o1 = new Order();

$o1->setCust($c1); //storing $c1 object in $o1 order object

In the above example setCust() method accepts a Customer type of parameter which is stored
internally in the $customer data member.

The advantage of the above method is that it allows you to change the customer object
independently of the order object. Imagine having to add 3 - 4 new data members to the
Customer object. You only have to modify the Customer object without having the need to
modify the Order Object.



Definition of Access Specifiers
Access specifiers specify the level of access that the outside world (i.e. other class objects,
external functions and global level code) have on the class methods and class data members.
Access specifiers can either be public, private or protected.

Why do we need Access specifiers
Access specifiers are used as a key component of Encapsulation and Data Hiding. By using
either of the access specifiers mentioned above i.e. public, private or protected you can hide or
show the internals of your class to the outside world.

Explanation of each access specifier

1. Private
2. Protected
3. Public

1. Private
A private access specifier is used to hide the data member or member function to the outside
world. This means that only the class that defines such data member and member functions have
access them. Look at the example below:

Example:

class Customer {
        private $name;

         public function setName($name) {
                 $this->name = $name;
         }

         public function getName() {
                 return $this->name;
         }
}
$c = new Customer();
$c->setName("Sunil Bhatia");
echo $c->name; //error, $name cannot be accessed from outside the class
               //$name can only be accessed from within the class

echo $c->getName(); //this works, as the methods of the class have access
                    //to the private data members or methods

In the above example, echo $c->name will give you an error as $name in class
Customer has been declared private and hence only be accessed by its member
functions internally. Therefore, the following line echo $c->getName() will
display the name.


2. Public
A public access specifier provides the least protection to the internal data
members and member functions. A public access specifier allows the outside
world to access/modify the data members directly unlike the private access
specifier. Look at the example below:




Example:

class Customer {
        public $name;

         public function setName($name) {
                 $this->name = $name;
         }

         public function getName() {
                 return $this->name;
         }
}

$c = new Customer();
$c->setName("Sunil Bhatia");
echo $c->name;         // this will work as it is public.
$c->name = "New Name" ; // this does not give an error.




In the above example, echo $c->name will work as it has been declared as public
and hence can be accessed by class member functions and the rest of the script.



3. Protected
A protected access specifier is mainly used with inheritance. A data member or member function
declared as protected will be accessed by its class and its base class but not from the outside
world (i.e. rest of the script). We can also say that a protected data member is public for the class
that declares it and it’s child class; but is private for the rest of the program (outside world).
Look at the example below:



class Customer {
        protected $name;

          public function setName($name) {
                  $this->name = $name;
          }

          public function getName() {
                  return $this->name;
          }
}

class DiscountCustomer extends Customer {

          private $discount;

          public function setData($name, $discount) {
                  $this->name = $name; //this is storing $name to the Customer
                                      //class $name variable. This works
                                      // as it is a protected variable

                    $this->discount = $discount;
          }
}

$dc = new DiscountCustomer();
$dc->setData("Sunil Bhatia",10);
echo $dc->name; // this does not work as $name is protected and hence
               // only available in Customer and DiscountCustomer class

In the above example, echo $dc->name will not work work $name has been defined as a
protected variable and hence it is only available in Customer and DiscountCustomer class.



Important Note of Access Specifier in PHP5
In PHP5, access specifiers are public by default. This means that if you don’t specify
an access specifier for a data member or method then the default ‘public’ is
applicable




Definition of an class method
A class method/functions is the behavior/functionality of a class i.e. they provide the necessary
code for the class in which it is defined. Examples could be a saveCustomer() method in the class
Customer or a printDocument() in the Document class.
Methods act (perform operations) on the data members of the class and can be declared as
private or public. A class method is exactly similar to PHP functions, it’s just that class functions
are declared inside classes and accessed using the -> (arrow operator / dereferencing operator).



Methods can also be declared as either public, protected or private.

Example Code:

class Customer {
        private $name;
        public functionsetName($name) {
                $this->name = $name;
        }
}

$c1 = new Customer();
$c1->setName("Sunil Bhatia");

In the above example setName() is the class method of the Customer class. The setName() class
method is responsible for accepting the name of the customer and storing it in the internal data
member i.e. $name.

class Customer {
        private $name;
        public function setName($name) {
                if(trim($name) != "") {
                        $this->name = $name;
                        return true;
                }
                else {
                        return false;
                }
        }
}

$c1 = new Customer();
$c1->setName("Sunil Bhatia");




In the above example the setName() method accepts a customer’s name and validates to check if
$name is blank. If $name is blank the setName() function returns false; otherwise it stores the
$name in the $this->name of the class and returns true.
Definition of a Constructor
A constructor is a special function of a class that is automatically executed whenever an object
of a class gets instantiated.

It’s special because it is automatically executed or called when an object of a class
is created.

Why do we need a Constructor?
It is needed as it provides an opportunity for doing necessary setup operations like
initializing class variables, opening database connections or socket connections,
etc. In simple terms, it is needed to setup the object before it can be used.



In PHP5 a constructor is defined by implementing the __construct() method. This
naming style has been introduced in PHP5. In PHP4, the name of the constructor
was the same name as that of the class.

PHP5 to be backward complaint also supports the PHP4 rule. When an object is
created, PHP5 searches for __construct() first. If __construct() is not defined it then
searches for a method with the same that of the class. However, if you define both;
PHP5 will first search for __construct() method and execute it if available, otherwise
it will execute the same class name function.



class Customer {
        public function __construct() {
                //code
        }
}




Example



class Customer {
        private $first_name;
        private $last_name;
        private $outstanding_amount;

         public function __construct() {
                 $first_name = "";
                 $last_name = "";
                 $outstanding_amount = 0;
         }
public function setData($first_name, $last_name, $outstanding_amount)
{
                  $this->first_name = $first_name;
                  $this->last_name = $last_name;
                  $this->outstanding_amount = $outstanding_amount;
         }

         public function printData() {
                 echo "Name : " . $first_name . " " . $this->last_name . "n";
                 echo "Outstanding Amount : " . $this->outstanding_amount .
"n";
         }

}

$c1 = new Customer();
$c1->setData("Sunil","Bhatia",0);


In the above example on line number 26, we create a new object of the
Customer class. the ‘new’ operator is responsible for creating the Customer
class. At this point PHP5 searches the Customer class to see if a constructor
has been defined. Therefore, it calls the constructor method i.e.
__construct() defined starting from line no 7. The __construct() method sets
the $first_name and $last_name to blank and sets the $outstanding_amount to
zero.




Parameterized Constructor or Argument Constructor

A parameterized or argument constructor is a constructor which accepts values in the form of
arguments in the constructor. Unlike other programming languages where overloaded argument
constructors is possible, in PHP5 you cannot overload constructors.

Example:

class Customer {
        private $first_name;
        private $last_name;
        private $outstanding_amount;

        public function __construct($first_name, $last_name,
$outstanding_amount) {
                $this->setData($first_name, $last_name, $outstanding_amount);
        }

         public function setData($first_name, $last_name, $outstanding_amount)
{
                  $this->first_name = $first_name;
                  $this->last_name = $last_name;
                  $this->outstanding_amount = $outstanding_amount;
         }

         public function printData() {
echo "Name : " . $first_name . " " . $this->last_name . "n";
                  echo "Outstanding Amount : " . $this->outstanding_amount .
"n";
         }

}

$c1 = new Customer("Sunil","Bhatia",0);


In the above example on line number 24, we create a new object $c1 and pass
values “Sunil”, “Bhatia” and zero to the constructor defined on line number
starting 7. The constructor now takes 3 arguments and stores them in the
internal private variable $first_name, $last_name and $outstanding_amount
respectively.


Definition of a Destructor
A destructor is a special function of a class that is automatically executed
whenever an object of a class is destroyed.


An object of a class is destroyed Means

    1. it goes out of scope,
    2. when you specifically set it to null,
    3. when you unset it or when the program execution is over.



A PHP5 destructor is defined by implementing the __destruct() method. In PHP4 however, the
concept of a destructor did not exist.

Important Note:
A destructor cannot take any arguments.

class Customer {
        public function __destructor() {
                //code
        }
}

Example:

class Customer {

         private $first_name;
         private $last_name;
         private $outstanding_amount;

         public function __construct() {
                 $first_name = "";
                 $last_name = "";
$outstanding_amount = 0;
         }

         public function setData($first_name, $last_name, $outstanding_amount)
{
                  $this->first_name = $first_name;
                  $this->last_name = $last_name;
                  $this->outstanding_amount = $outstanding_amount;
         }

         public function printData() {
                 echo "Name : " . $first_name . " " . $last_name . "n";
                 echo "Outstanding Amount : " . $outstanding_amount . "n";
         }

}

class Order {
        private $order_id;
        private $customer;

         public function __construct($order_id, $customer) {
                 $this->order_id = $order_id;
                 $this->customer = $customer;
         }

         public function __destruct() {
                 unset($this->order_id);
                 unset($this->customer);
         }
}

$order_id = "L0001";
$c1 = new Customer();
$c1->setData("Sunil","Bhatia",0);

$o = new Order($order_id, $c1);




In the above example on line number 45, we create a new object of the Order
class. The argument constructor of the Order class takes two parameters i.e.
$order_id and $customer object. After the program completes its execution, the
object goes out of scope because the program stops execution after line 45 and
hence the destructor is automatically called.




Accessor Methods:
Accessor methods are also know as getter methods. The reason why we need an accessor method
is to be able to read the value of a property/attribute in a class object. In real OOAD practice
most of the data members that you define would either be private or protected (more on this will
be covered in the tutorial on Access specifiers), therefore to access data of such data members
that have been defined as either private or protected will require an implementation of accessor
or getter methods.

Note: To make a property or data member as non-read only; you should not provide a getter or
accessor method.

Mutator Methods:

Mutator methods are opposite to accessor methods. Mutator methods provides a mechanism to
store data in data members that have either been declared as private or protected. The reason why
you should provide a mutator method is to provide necessary validation on the data that is to be
stored in the data member of the class.

Note: To make a property or data member as read only; you should not provide a setter or
mutator method.

Lets look at an example of accessor and mutator methods below:

class Customer {
        private $name;

         //mutator method
         public function setName($name) {
                 if(trim($name) != "") {
                         $this->name = $name;
                         return true;
                 }
                 else {
                         return false;
                 }
         }

         //accessor method
         public getName() {
                 return $this->name;
         }
}

$c1 = new Customer();
$c1->setName("Sunil Bhatia");
echo $c1->getName();

Output:
Sunil Bhatia

In the above example the setName() method accepts a customer’s name and validates to check if
$name is blank. If $name is blank the setName() function returns false; otherwise it stores the
$name in the $this->name of the class and returns true. The getName() returns the name stored in
the $name data member of the $c1 object.
PHP5 introduces a new operator by the name of instanceOf. instanceOf is used to check if two
objects passed as operands belong to the same class. This check can also happen when an object
is compared with a class name.

In PHP4 a similar functionality existed with a method is_a(), which has been replaced by the
instanceOf operator in PHP5.

class Person {
        ...
}

$p1 = new Person();
$p2 = new Person();

if($p1 instanceof $p2)
     echo "True";
else
     echo "False";

In the above example, we are comparing to check if $p1 and $p2 belong to the same class i.e.
Person. In this case $p1 and $p2 both belong to the same class Person and hence the output is
True. Please note that line number 8 can also be written as if($p2 instanceof $p1) and will yield
the same output.

You can also use instanceOf operator to compare an object with the name of the class, look at the
example below:

class Person {
        ...
}

$p1 = new Person();

if($p1 instanceof Person)
     echo "True";
else
     echo "False";

In the above example, on line number 7 $p1 object is being compared to check if its a Person
type of object. In this case $p1 is a Person type of object and hence the output is True.

Behaviour of instanceOf operator in inheritance

class Customer extends Person {
        ...
}

$p1 = new Person();
$c1 = new Customer();
if($c1 instanceof $p1)
     echo "True";
else
     echo "False";

In the above example, on line number 8 $c1 child class object is being compared with $p1 which
is a parent class object. This is possible because Customer class is a child of the Person Class,
just that the Customer class is a specialized form of the Person class and therefore this becomes
possible. However the reverse is not possible, we cannot compare if($p1 instanceof $c1) and will
result in an error.



Constants

To declare a constant in a class, PHP5 provides developers with a new keyword i.e. const; look
at the example below:

class Customer {
        const TYPES = "Anything";
}

echo "Types are : " . Customer::TYPES;

In the above example, const is a keyword and TYPES is the name of the constant. Outside the
class definition we echo the value of the constant by using the scope resolution operator (::) like
this Customer::TYPES. Observe that we don’t need to create an object of the class to make use
of the constant.

The next logical question is if we can create an object of the Customer class and using the scope
resolution operator access the constant. The answer is no; reason - because a constant belongs to
the class definition scope and not to an object.
Example of accessing Constants within a function

class Customer {
        const TYPES = "Anything";

         public function showConstant() {
                 echo "Echo from showConstant() : " . Customer::TYPES;
         }

}

$c = new Customer();
$c->showConstant();

Output:
Echo from showConstant() : Anything
Some observations on Constants

    1. Variables defined as constants cannot be changed.
    2. Only a string or numeric value can be assigned to a constant.
    3. Arrays, Objects & Expressions cannot be assigned to a constant.
    4. A class constant can only be accessed via the scope resolution operator (::) executed on
       the class name.
    5. A class constant cannot have <a>access specifiers</a> assigned to it (private, public &
       protected)



Definition of Inheritance:

Inheritance is the mechanism of deriving a new class from an existing class. It allows a sub-
class / child class to share/inherit the attributes and behaviors of a base-class or parent class.
These inherited attributes and behaviors are usually modified by means of extension.

PHP5 Inheritance

To inherit in PHP5, you should use the keyword ‘extends’ in the class definition. In PHP5 only
single inheritance is allowed. Look at the example below:

class Person {
        private $name;
        private $address;

          public function getName() {
                  return $this->name;
          }
}

class Customer extends Person {
        private $customer_id;
        private $record_date;

          public getCustomerId() {
                  return $this->customer_id;
          }

          public getCustomerName() {
                  return $this->getName();// getName() is in Person
          }
}

In the above example, class Customer extends from the Person class. This means that Customer
class is the child class and the Person base class. The child class Customer extends the method
getName() and calls it in the getCustomerName() method of the Customer class.
Inheritance and Access Specifiers
You can refer to the Access specifiers tutorial to understand what it means. Let’s understand the
use of Access Specifiers with context to Inheritance.

Access specifiers specify the level of access that the outside world (other objects and functions)
have on the data members / member functions of the class. Please note that all data members and
member functions are public by default.

Lets look at how three access specifiers viz. private, public and protected behave in Inheritance:

1. private

A private access specifier is used to hide data and member functions. A method or data member
declared as private can only be accessed by the class itself and neither the outside program nor
the derived class can have access to it. Lets look at an example below:

class Customer {
        private $name;
        public $age;

            public function __construct($name, $age) {
                    $this->name = $name;
                    $this->age = $age;
            }
}

$c = new Customer("Sunil","28");
echo "Name : " . $c->name; //causes an error

In the above example, the statement;

echo “Name : ” . $c->name;

causes an error as we are trying to access $name that has been declared as a private member
variable. We can however access the $age data member without any limitation as its public.

Note: When you define a method as private that method can only be called from within that class
and not from outside that is the global level script.

2. public

A public access specifier allows the data members and methods to be access from anywhere in
the script. Lets look at an example below:

class Customer {
        private $name;
        public $age;

            public function __construct($name, $age) {
$this->name = $name;
                   $this->age = $age;
         }
}

$c = new Customer("Sunil","28");
echo "Age : " . $c->age; //prints 28

In the above example, the statement;

echo “Age : ” . $c->;age;

prints 28 on the screen as $age is a public variable and hence can be accessed from anywhere in
the script. Please note that if you declare any data member or method without a access specifier it
is considered as ‘public’.

3. protected

A protected access specifier allows the derived class to access the data member or member
functions of the base class, whereas disallows global access to other objects and functions.

class Person {
        protected $name;
}

class Customer extends Person {
        function setName($name) {
                //this works as $name is protected in Person
                $this->name = $name;
        }
}

$c1 = new Customer();
$c1->setName("Sunil");
$c1->name = "Sunil"; //this causes error as $name is protected and not public

In the above example, the statement;

$this->name = $name;

in the setName() function is referring to the $name data member of the Person class. This access
is only possible because the $name variable has been declared as protected. Had this been
private; the above statement would have raised an error. Further, in the statement towards the
end;

$c1->name = “Sunil”;

raises an error as $name in the Person class has been declared as protected and not public.
PHP5 Inheritance - Method Overriding
Lets learn how to override methods in PHP5, but before we understand how to override methods
in PHP5; lets define method overriding.

Definition of Method Overriding:
Method overriding is when the function of base class is re-defined with the same name, function
signature and access specifier (either public or protected) of the derived class.

The reason to override method is to provide additional functionality over and above what has
been defined in the base class. Imagine that you have a class by the name of Bird from which
you derive two child classes viz. Eagle and Swift. The Bird class has methods defined to eat, fly,
etc, but each of the specialized classes viz Eagle and Swift will have its own style of flying and
hence would need to override the flying functionality.

Lets look at an example with Bird:

class Bird {
        public function fly() {
                echo "Fly method of Bird Class called";
        }
}

class Eagle extends Bird {
        public function fly() {
                echo "Fly method of the Eagle Class called";
        }
}

class Swift extends Bird {
        public function fly() {
                echo "Fly method of the Swift Class called";
        }
}

$e = new Eagle();
$s = new Swift();

$e->fly();
echo "n";
$s->fly();

Output:
Fly method of the Eagle Class called
Fly method of the Swift Class called

In the above example, we create two objects of class Eagle and Swift. Each of these classes have
overridden the method fly() and have provided their own implementation of the fly() method that
has been extended from the Bird class. The manner in which they have been extended the Bird
class fly() method is not called as both these classes have provided a new functionality for the
fly() method.
Another example of function overriding in Inheritance

class Person {
        function calculateAge($dob) {
                echo "calculateAge called of Person Classn";
        }

}

class Customer extends Person {
        function calculateAge($dob) {
                echo "calculateAge called of Customer Classn";
        }
}

$c1 = new Customer();
$p1 = new Person();

$c1->calculateAge("something");
$p1->calculateAge("something More");

Output:
calculateAge called of Customer Class
calculateAge called of Person Class

PHP5 Inheritance - Invoking parent methods
When you override a method of the base class, it’s functionality is completely hidden unless it
has been explicitly invoked from the child class. To invoke a parent class method you should use
the keyword parent followed by the scope resolution operator followed by the name of the
method as mentioned below:

         parent::function_name();

Look at the example below:

class Person {
        public function showData() {
                echo "This is Person's showData()n";
        }
}

class Customer extends Person{
        public function showData() {
                parent::showData();
                echo "This is Customer's showData()n";
        }
}

$c = new Customer();
$c->showData();
Output:
This is Person’s showData()
This is Customer’s showData()

In the above example, look at the way in which the showData() function in the Customer child
class is invoking the the Person parent class’s showData() function. When the program executes
the showData() method if the Customer class is called which inturn calls the showData() function
of the parent class. After the parent class’s showData() function complets its execution the
remaining code in showData() function of the Customer class is executed.

PHP5 Inheritance - Invoking parent Constructor and Destructor
We can get the parent PHP5 constructor and PHP5 Destructor to be invoked in the same way as
invoking the parent method, refer to the example below:

class Person{
        public function __construct() {
                echo "This is Person's __construct()n";
        }

         public function __destruct() {
                 echo "This is Person's __destruct()n";
         }
}

class Customer extends Person{
        public function __construct() {
                parent::__construct();
                echo "This is Customer's __construct()n";
        }

         public function __destruct() {
                 parent::__destruct();
                 echo "This is Customer's __destruct()n";
         }
}

$c = new Customer();

Output:
This is Person’s __construct()
This is Customer’s __construct()
This is Person’s __destruct()
This is Customer’s __destruct()




What is an exception?
An exception is a logical/system error that occurs during the normal execution of a script. The
exception could either be raised by the system or the program itself it the exception cannot be
handled and the caller script/function needs to be informed about the same.

The use of a try…catch block

PHP5 introduces the try…catch block to trap exceptions. Look at the example below.


try {
   check();
}
catch(Exception $e) {
   echo "Message : " . $e->getMessage();
   echo "Code : " . $e->getCode();
}

function check() {
   if(some error condition) {
      throw new Exception("Error String",Error Code);
   }
}

In the above example, the method check() is called between the try {} block. The try{} block is
the area where you will place your code that could raise an exception. Below the try{} block is
the catch() {} block. The catch block expects the Exception type of object as a parameter. Within
the catch() {} block you will place your logic to either fix the issue or log the error.

In the function check(), we raise an Exception using the ‘throw’ keyword. The statement
following ‘throw’ is the syntax of creating a new object of Exception type. The exception class
accepts two parameters. The left parameter is a string that is the error message and the right
parameter is the integer error code that you wish to assign to that error.



Anatomy of PHP5 Exception class

class Exception {
        protected     $message;
        protected     $code;
        protected     $file;
        protected     $line;

         private $string;
         private $trace;

         public function __construct($message = null, $code = 0);
         public function __toString();

         final public function getCode();
final   public function getMessage();
          final   public function getFile();
          final   public function getLine();
          final   public function getTrace();
          final   public function getTraceAsString();
          final   private __clone();
}

In the above example, except for __construct and __toString(), no other method can be
overridden as all other methods are ‘final’.

Extending the Exception class

You can also extend the exception class as follows:


class CustomerException extends Exception {

    public function __construct($message = null, $code = 0) {

     $t_message = "Exception raised in CustomerException ";
     $t_message .= "with message : " . $message;

     parent::__construct($t_message, $code);

     }

}


function testException() {

          throw new CustomerException("CustomerException has been raised",101);

}

try {
        testException();
}
catch(CustomerException $e) {
        echo "Error Message : " $e->getMessage();
        echo "Error Code : " $e->getCode();
}

Output:

Error Message : CustomerException has been raised
Error Code : 101



What is an Abstract Class?
An abstract class is a class with or without data members that provides some functionality and
leaves the remaining functionality for its child class to implement. The child class must provide
the functionality not provided by the abstract class or else the child class also becomes abstract.

Objects of an abstract and interface class cannot be created i.e. only objects of concrete class can
be created

To define a class as Abstract, the keyword abstract is to be used e.g. abstract class ClassName
{}

Example of Abstract Class


abstract class Furniture {
        private $height, width, length;

          public function setData($h, $w, $l) {
                  $this->height = $h;
                  $this->width = $w;
                  $this->length = $l;
          }

          //this function is declared as abstract and hence the function
          //body will have to be provided in the child class
          public abstract function getPrice();

}


class BookShelf extends Furniture {

    private $price;

    public setData($h, $w, $l, $p) {
       parent::setData($h, $w, $l);
       $this->price = $p;
    }


    //this is the function body of the parent abstract method
    public function getPrice() {
       return $this->price;
    }
}

In the above example, the method getPrice() in class Furniture has been declared as Abstract.
This means that its the responsibility of the child class to provide the functionality of getPrice().
The BookShelf class is a child of the Furniture class and hence provides the function body for
getPrice().


       Private methods cannot be abstract
If a method is defined as abstract then it cannot be declared as private (it can only be public or
protected). This is because a private method cannot be inherited.

abstract class BaseClass {

    private abstract function myFun();

}

class DerivedClass extends BaseClass {
   public function myFun() {
           //logic here
   }
}

$d = new DerivedClass(); //will cause error

What is an Interface?

An interface is a contract between unrelated objects to perform a common function. An interface
enables you to specify that an object is capable of performing a certain function, but it does not
necessarily tell you how the object does so, this means that it leaves for classes implementing an
interface to define its behaviour.

To extend from an Interface, keyword implements is used.

We can have a class extend from more than one Interface.


interface Storable {
        function getContentsAsText();
}

class Document implements Storable {
        public function getContentsAsText() {
                return "This is Text of the Documentn";
        }
}

class Indexer {
        public function readAndIndex(Storable $s) {
                $textData = $s->getContentsAsText();
                //do necessary logic to index
                echo $textData;
        }
}

$p = new Document();

$i = new Indexer();
$i->readAndIndex($p);
In the above example, Document and the Indexer class are two independant classes. The Indexer
class is designed to index the contents of any text. Using the Storable interface above, we declare
a method getContentsAsText() in the Document class. Because the Indexer class is only
concerned with the TEXT, hence we can call getContentsAsText() method on the object of
Document. This way any class if it implements the method getContentsAsText() can get indexed

Difference between Abstract Class and Interface

Abstract Classes

   1. An abstract class can provide some functionality and leave the rest for derived class
   2. The derived class may or may not override the concrete functions defined in base class
   3. The child class extended from an abstract class should logically be related

Interface

   1. An interface cannot contain any functionality. It only contains definitions of the methods
   2. The derived class must provide code for all the methods defined in the interface
   3. Completely different and non-related classes can be logically be grouped together using
      an interface

Meaning of Polymorphism

Polymorphism is derived from two Greek words. Poly (meaning many) and morph (meaning
forms). Polymorphism means many forms. In C you have two methods with the same name that
have different function signatures and hence by passing the correct function signature you can
invoke the correct method.

This is how polymorphism is achieved in languages like C where in a function sum(int, int)
differs from sum(float, float). Therefore the method sum() has many forms depending on the
parameters being passed to it.

The meaning with Object Oriented languages changes. With Object Oriented language
polymorphism happens:

When the decision to invoke a function call is made by inspecting the object at runtime it is
called Polymorphism

Why method polymorphism cannot be achieved

The reason why polymorphism for methods is not possible in PHP is because you can have a
method that accepts two parameters and call it by passing three parameters. This is because PHP
is not strict and contains methods like func_num_args() and func_get_arg() to find the number of
arguments passed and get a particular parameter.
Because PHP is not type strict and allows variable arguments, this is why method polymorphism
is not possible.

PHP 5 Polymorphism

Since PHP 5 introduces the concept of Type Hinting, polymorphism is possible with class
methods. The basis of polymorphism is Inheritance and overridden methods.

Lets look at an example:


class BaseClass {
   public function myMethod() {
      echo "BaseClass method called";
   }
}

class DerivedClass extends BaseClass {
   public function myMethod() {
      echo "DerivedClass method called";
   }
}

function processClass(BaseClass $c) {
   $c->myMethod();
}

$c = new DerivedClass();
processClass($c);

In the above example, object $c of class DerievedClass is executed and passed to the
processClass() method. The parameter accepted in processClass() is that of BassClass. Within
the processClass() the method myMethod() is being called. Since the method is being called on
the class variable of BaseClass, it would not be wrong to assume that myMethod() of class
BaseClass will be called. But, as per the definition “When the decision to invoke a function call
is made by inspecting the object at runtime it is called Polymorphism”, myMethod() will be
called on object DerievedClass. The reason why this happens is because the object of
DerievedClass is being passed and hence the method myMethod() of DerievedClass will be
called.



Why method polymorphism cannot be achieved

The reason why polymorphism for methods is not possible in PHP is because you can have a
method that accepts two parameters and call it by passing three parameters. This is because PHP
is not strict and contains methods like func_num_args() and func_get_arg() to find the number of
arguments passed and get a particular parameter.
Because PHP is not type strict and allows variable arguments, this is why method polymorphism
is not possible.



PHP 5 Polymorphism

Since PHP 5 introduces the concept of Type Hinting, polymorphism is possible with class
methods. The basis of polymorphism is Inheritance and overridden methods.

Lets look at an example:


class BaseClass {
   public function myMethod() {
      echo "BaseClass method called";
   }
}

class DerivedClass extends BaseClass {
   public function myMethod() {
      echo "DerivedClass method called";
   }
}

function processClass(BaseClass $c) {
   $c->myMethod();
}

$c = new DerivedClass();
processClass($c);

In the above example, object $c of class DerievedClass is executed and passed to the
processClass() method. The parameter accepted in processClass() is that of BassClass. Within
the processClass() the method myMethod() is being called. Since the method is being called on
the class variable of BaseClass, it would not be wrong to assume that myMethod() of class
BaseClass will be called. But, as per the definition “When the decision to invoke a function call
is made by inspecting the object at runtime it is called Polymorphism”, myMethod() will be
called on object DerievedClass. The reason why this happens is because the object of
DerievedClass is being passed and hence the method myMethod() of DerievedClass will be
called.




PHP magic methods
PHP5 provides a magic method by the name of __toString() (double underscore followed by
toString()) which is useful for debugging purposes.

The __toString() method is automatically called when an object in PHP5 is converted into a
string for the purpose of display or concatenation

Following is the example of the __toString() method:

<?php

class Customer {
private $firstName, $lastName, $email;

public function __construct($firstName, $lastName, $email) {
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->email = $email;
}

public function __toString() {
return “Debug message from Customer Class : First Name = ” . $this->firstName . “, Last Name
= ” . $this->lastName . “, Email = ” . $this->email;
}
}

$c = new Customer(”Sunil”,”Bhatia”,”email@domain.com”);

echo “Customer Object is >>” . $c;

?>

Output:

Customer Object is >> Debug message from Customer Class : First Name = Sunil, Last Name =
Bhatia, Email = email@domain.com

See how in this example $c Customer Object got converted into a string type when used with the
dot (.) concatenation operator. In the background the magic method __toString() is automatically
called when such a conversion happens.

Security Tip:
Be careful not to include sensitive data as part of the output as you could compromise security by
leaking secure information. Many applications are written to write object states in a log file,
therefore you should ensure that sensitive information like Credit Card information, etc is not
made available through the magic method __toString()
By default PHP is a Loosely typed language and therefore it is not necessary to declare variables
before using them. This also holds true for using class members. Look at an example below.

<?php

class Customer {
public $name;
}

$c = new Customer();
$c->name = “Sunil”; // $name is set because its public

$c->email = “email@domain.com”; //assigning email@domain.com to the $email variable.

?>

Ideally in a strict language this would have been an error. But, with PHP this works perfectly
well as you can assign values to an undefined variable.

Because of the above limitation, PHP engine provides two magic methods __get() and __set().
__get() is used when value from an undefined variable is to be read and __set() is used when a
value is to be assigned to a undefined variable of a class.

__set() allows you to provide functionality to validate data being stored. See example below:

<?php

class Customer {
public $name;
private $data = array();

public function __set($dt, $vl) {
$this->data[$dt] = $vl;
}

public function __get($dt) {
return $this->data[$dt];
}
}

$c = new Customer();
$c->name = “Sunil”; // $name is set because its public

$c->email = “email@domain.com”; //assigning email@domain.com to the $email variable.
echo $c->email;

?>

In the above example when email@domain.com is assigned to the undefined variable $email, the
magic method __set() is called. To this __set() method the name of the variable is passed into
$dt variable of __set() method and the value i.e. email@domain.com is passed to $vl variable of
the __set() method.

The next step is to store these values into the $data array so that you could retrieve it later.

The __get() method works in the similar fashion. When you echo $c->email, __get() method is
called and the name email is passed in the $dt of the __get() method.

Tip:
It is possible to stop this behavior of PHP to assign values to undefined issues. The solution is
that you raise an exception from within __set() method. Look at the code below:

<?

class Customer {

private $name;

public function __set($dt, $vl) {
throw new Exception(”Cannot assign values to undefined variables”,1);
}

}

$c = new Customer();
$c->email = “email@domain.com”; //this will cause an exception to be raised

?>

magic methods __isset() and __unset()



These methods are automatically called internally when isset() and unset() is called on
undeclared data members. The magic method __isset() method receives an argument - the value
of which is the name of the variable that the program wants to test if the variable is set or not.

The magic method __unset() method receives an argument - the value of which is the name of
the variable that the program wants to unset.
Look at the example below:

class Customer {
        private $data = array();

         public function __set($dt, $vl) {
                 $this->data[$dt] = $vl;
         }

         public function __get($dt) {
                 return $this->data[$dt];
         }

         public function __isset($dt) {
                 return isset($this->data[$dt]);
         }

         public function __unset($dt) {
                 return unset($this->data[dt]);
         }
}

$c = new Customer();
$c->name = “Sunil Bhatia”;

echo isset($c->name).”n”;
echo unset($c->name);




In the example above the script creates a new Customer Object. The program assigns a string
value to an undeclared variable i.e. $c->name. The undeclared variable is handled by the magic
method __set().

The program ties to check if the undeclared variable i.e., $c->name has been set or not using the
PHP method isset(). Since $c->name is an undeclared variable the PHP5 magic method __isset()
is invoked that takes the name of the undeclared variable i.e. ‘name’ and checks if the internal
array $data[’name’] is set or not.

Similarly, when the program calls unset() on the undeclared variable i.e. $c->name, the PHP5
magic method __unset() is invoked that takes the name of the undeclared variable i.e. ‘name’ and
unsets the internal array $data[’name’].

The magic method __call() is to undeclared methods what __get() and __set() are to undeclared
data member.

These methods are automatically called internally when the program tires to execute a method
that has not been defined within the class at the time of development.
The magic method __call() takes two arguments. The first argument is the name of the
undeclared method invoked by the program and the second is an array that contains a list of
parameters passed to the undeclared array.


Look at the example below:

class Customer {

         public function __call($name, $args) {
                 var_dump($name);
                 echo "n";
                 var_dump($args);
                 echo "n";
         }
}

$c = new Customer();
$c->setName("Sunil","Bhatia");

Output:
string(7) “setName”

array(2) {
[0]=>
string(5) “Sunil”
[1]=>
string(6) “Bhatia”
}

In the example above, an object of the Customer class is created and an undeclared method viz.
$c->setName is called. The magic method __call() is internally executed which accepts two
parameters. The first parameter ‘$name’ contains the name of the method i.e. ’setName’ and the
second parameter ‘$args’ contains the arguments passed to the ’setName’ method i.e ‘Sunil’ &
‘Bhatia’.

Using this method, you can provide code to handle calls to undeclared method. To disallow
programs to call an undeclared method, you should raise an exception from within __call()
magic method.

Look at the example below:

class Customer {

        public function __call($name, $args) {
                throw new Exception("Undeclared method execution not
allowed",10);
        }
}
$c = new Customer();
$c->setName("Sunil","Bhatia");

Output:
Fatal error: Uncaught exception ‘Exception’ with message ‘Undeclared method execution not
allowed’ in D:sunilbwebsiteprogsmagic_call.php:6
Stack trace:
#0 [internal function]: Customer->__call(’setName’, Array)
#1 D:sunilbwebsiteprogsmagic_call.php(11): Customer->setName(’Sunil’, ‘Bhatia’)
#2 {main}
thrown in D:sunilbwebsiteprogsmagic_call.php on line 6

In the above program, when the script calls an undeclared variable $c->setName(), the magic
method __call() is executed. On executing the magic method __call(), an exception is raised
and the execution of the program stops there (unless we use the try..catch statements)

Many people debate that the magic method __autoload() causes a performance overhead. Well,
that is not the case. There is no performance penalty to pay. In fact, there may be performance
improvements if not all classes are used all the time. This is explained below.

Using the magic method __autoload has the beneficial side effect of requiring strict naming
conventions for files that hold class definitions.

Look at the example below:

include “customer.php”;
include “orders.php”;

$c = new Customer();

In the example displayed above, an instance of class Customer is created. Therefore, we only
need the customers.php file. The file orders.php is not needed. This means that we should only
have included the customer.php file. But, what if during execution on the basis of a condition, an
instance of class Orders would have to be created. Therefore you need to include both the files
i.e. customer.php and orders.php

But this causes performance issues. Each time the above script is executed, orders.php is
included. To avoid this performance hit, we would have to do additional programming to ensure
that the file orders.php is loaded only when needed.

This is the reason why magic method __autoload() should be used. Look at the example below:
function __autoload($class) {
   require $class . '.php'; //is substituted as require Customer.php (with
capital 'C')
}

$c = new Customer();


In the above program, we don’t explicitly include customer.php and orders.php file.
When an instance of the customer class is to be created, the PHP engine checks to
see if the file Customer.php is loaded. It does not raise an warning on finding that
Customer.php has not been loaded, it in turn calls the magic method __autoload().
The __autoload() magic method accepts a parameter which is the name of the class
that needs to be loaded



Therefore, on the line when an instance of the customer class is created i.e. object $c, magic
method __autoload() is called with the parameter $class containing value ‘Customer’. Within
the __autoload() method we call the ‘require’ method. The require method tries to load
$class.’php’ file i.e. Customer.php. Therefore, as stated earlier, the __autoload() method has its
beneficial side effect of requiring strict file naming convention.

The __autoload() method is called only once for each new class that needs to be loaded.
Subsequent instantiation of the Customer class object will not call the __autoload() method
again. Therefore, this offers performance improvements in your scripts because, unless the class
is needed - files are not loaded. Therefore, the PHP engine does not have to parse and compile an
unnecessary file.

Working with the magic method __sleep()

__sleep() magic method is called when the object of a class is about to be serialized. This magic
method __sleep() does not accept any parameter and returns an array. The array should contain a
list of class members that should be serialized. This means that if you don’t wish to serialize a
particular class member, you should not include it in the array. Look at the example below:

class Customer {
        private $name;
        private $credit_card_number;

         public function setName($name) {
                 $this->name = $name;
         }

         public function getName() {
                 return $this->name;
         }

         public function setCC($cc) {
                 $this->credit_card_number = $cc;
}

         public function getCC() {
                 return $this->credit_card_number;
         }

        public function __sleep() {
                return array("name"); //because of this, only name is
serialized
        }

}

$c = new Customer();
$c->setName("Sunil");
$c->setCC("1234567890123456");

$data = serialize($c)."n";
echo $data."n";

Output:
O:8:”Customer”:1:{s:14:” Customer name”;s:5:”Sunil”;}

In the above example, you can see that the serialized string data only contains the name of the
Customer Object. This is because the __sleep() magic method returned an array containing only
the ‘name’ data member.

Working with the magic method __wakeup()

__wakeup() magic method is the opposite of the __sleep() method. It is called when the object
of a class is about to be unserialized. This magic method __wakeup() does not accept any
parameter nor returns anything. The __wakeup() method is responsible for setup operations after
an object has been unserialized. Look at the example below:

class Customer {
        private $name;
        private $credit_card_number;

         public function setName($name) {
                 $this->name = $name;
         }

         public function getName() {
                 return $this->name;
         }

         public function setCC($cc) {
                 $this->credit_card_number = $cc;
         }

         public function getCC() {
                 return $this->credit_card_number;
         }
public function __sleep() {
                 return array("name");
         }

         public function __wakeup() {
                 if($this->name == "Sunil") {
                         //you would ideally fetch CC data from Database
                         $this->credit_card_number = "1234567890123456";
                 }
         }
}

$c = new Customer();
$c->setName("Sunil");
$c->setCC("1234567890123456");

$data = serialize($c)."n";
var_dump(unserialize($data));

Output:
object(Customer)#2 (2) {
[”name:private”]=>
string(5) “Sunil”
[”credit_card_number:private”]=>
string(16) “1234567890123456″
}

In the above example, you can see that after the $c object has been serialized and the output
stored in $data variable, we use the $data variable and pass it to the unserialize(). Before the
object is unserizlied and object created, the __wakeup() method is called. In the __wakeup()
method you should ideally make a database call to fetch data of the missing member variable.

To clone an object means to create a duplicate of an object. With regular variables $a = $b
means that a new variable $a gets created that contains the value of $b. This means that 2
variables get created.

With objects $obj2 = $obj1 does not mean that a new object i.e. $obj2 gets created. When we
execute $obj2 = $obj1, the reference of $obj1 is assigned to $obj2. This means that $obj1 and
$obj2 point to the same memory space. Look at the diagram below.
Lets look at an example where only references are assigned to another object:

class Customer {
        private $name;

          public function setName($name) {
                  $this->name = $name;
          }

          public function getName() {
                  return $this->name;
          }
}

$c1 = new Customer();
$c1->setName("Sunil");

$c2 = $c1; //only reference or memory assigned to $c2

$c2->setName("Vishal");

echo $c1->getName()."n";
echo $c2->getName()."n";

Output:
Vishal
Vishal

In the above example, $c2 has the reference of $c1; therefore, when you set a new name in the
$c2 object - $c1 object changes as well. Therefore, when an object is assigned as a reference;
changes made to one object are also reflected in the other.

Therefore, to create a new $obj2 object we must clone an object to create a new one. To clone an
PHP5 Object a special keyword i.e. clone is used. Example below:

          $obj2 = clone $obj1;

After the above line is executed $obj2 with a new memory space is created with the data
members having the same value as that of $obj1. This is also referred to as shallow copy.
The above technique works with a class having data members that are of intrinsic type i.e. int,
boolean, string, float, etc.. However, this technique will not work with a class that has a data
member which is an object of another class. In such a scenario, the cloned object continues to
share the reference of the data member object of the class that was cloned.

So, how do we resolve this issue? Doing a regular shallow copy won’t help us. To allow
aggregated objects (i.e. data members that are objects of another class) to also get cloned
properly we need to use the concept of ‘deep copy‘ as opposed to ‘shallow copy‘. To implement
a ‘deep copy‘ you should implement the magic method __clone().

You could also provide the implementation of __clone() magic method even when you don’t
have an aggregated object. You would want to do this for providing necessary clean up
operations, conversions or validations.

Lets explore a very simple example of cloning intrinsic data types:

class Customer {
        private $name;

          public function setName($name) {
                  $this->name = $name;
          }

          public function getName() {
                  return $this->name;
          }

          public function __clone() {
                  $c = new Customer();
                  $c->setName($this->name);
                  return $c;
          }

}

$c1 = new Customer();
$c1->setName("Sunil");

$c2 = clone $c1; //new object $c2 created

$c2->setName("Vishal");

echo $c1->getName()."n";
echo $c2->getName()."n";

Output:
Sunil
Vishal

In the above example, observe the line where the statement $c2 = clone $c1 is executed. This is
internally represented as $c2 = $c1.__clone(). However, you cannot explicitly call the __clone()
method on an object as the __clone() is automatically called. Now that $c1 and $c2 are two
individual objects, changes made to one object is not reflected in the other.

Cloning aggregate objects (i.e. data members that are objects of another class)

To clone a class having aggregated objects, you should perform ‘deep copy‘. Please refer to the
example below:

class Order {
        private $order_id;
        private $customer;

         public function setOrderId($order_id) {
                 $this->order_id = $order_id;
         }

         public function getOrderId() {
                 return $this->order_id;
         }

         public function setCustomer(Customer $customer) {
                 $this->customer = clone $customer;
         }

         public function getCustomer() {
                 return $this->customer;
         }

         public function __clone() {

                  $o = new Order();
                  $o->setOrderId($this->order_id);


                  //force a copy of the same object to itself, otherwise
                  //it takes the same instance. Seems like a bug to me
                  $this->customer = clone $this->customer;
                  $o->setCustomer($this->customer);
                  return $o;
         }

}

class Customer {
        private $name;

         public function setName($name) {
                 $this->name = $name;
         }

         public function getName() {
                 return $this->name;
         }

         public function __clone() {
$c = new Customer();
                  $c->setName($this->name);
                  return $c;
         }

}

$c = new Customer();
$c->setName("Sunil");

$o1 = new Order();
$o1->setOrderId("OD0001");
$o1->setCustomer($c);

$o2 = clone $o1;

$o2->getCustomer()->setName("Vishal");

var_dump($c);
var_dump($o1);
var_dump($o2);

Output:
object(Customer)#1 (1) {
[”name:private”]=>
string(5) “Sunil”
}
object(Order)#2 (2) {
[”order_id:private”]=>
string(6) “OD0001″
[”customer:private”]=>
object(Customer)#3 (1) {
[”name:private”]=>
string(5) “Sunil”
}
}
object(Order)#4 (2) {
[”order_id:private”]=>
string(6) “OD0001″
[”customer:private”]=>
object(Customer)#6 (1) {
[”name:private”]=>
string(6) “Vishal”
}
}

In the above example both $o1 and $o2 have their own set of customer objects, therefore
changes made to one object is not reflected in another. This example implements the concepts of
‘deep copy‘.
A special note on $this->customer = clone $this->customer; For some reason it is necessary to do
this for proper working of aggregated cloning.

Contenu connexe

Tendances

Library Management System - V1.0
Library Management System - V1.0Library Management System - V1.0
Library Management System - V1.0JamesMuturi
 
Architecture logicielle #3 : object oriented design
Architecture logicielle #3 : object oriented designArchitecture logicielle #3 : object oriented design
Architecture logicielle #3 : object oriented designJean Michel
 
1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object Calisthenics1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object CalisthenicsLucas Arruda
 
Object Oriented Programming Basics with PHP
Object Oriented Programming Basics with PHPObject Oriented Programming Basics with PHP
Object Oriented Programming Basics with PHPDaniel Kline
 
Drupal II: The SQL
Drupal II: The SQLDrupal II: The SQL
Drupal II: The SQLddiers
 
Chapter15 structure
Chapter15 structureChapter15 structure
Chapter15 structureDeepak Singh
 
Professional-grade software design
Professional-grade software designProfessional-grade software design
Professional-grade software designBrian Fenton
 
An Introduction to Object-Oriented Programming (DrupalCamp London 2015)
An Introduction to Object-Oriented Programming (DrupalCamp London 2015)An Introduction to Object-Oriented Programming (DrupalCamp London 2015)
An Introduction to Object-Oriented Programming (DrupalCamp London 2015)Bart Feenstra
 
oop lecture 3
oop lecture 3oop lecture 3
oop lecture 3Atif Khan
 
Coding for Scale and Sanity
Coding for Scale and SanityCoding for Scale and Sanity
Coding for Scale and SanityJimKellerES
 
Drupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comDrupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comJD Leonard
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency InjectionRifat Nabi
 

Tendances (20)

Library Management System - V1.0
Library Management System - V1.0Library Management System - V1.0
Library Management System - V1.0
 
Architecture logicielle #3 : object oriented design
Architecture logicielle #3 : object oriented designArchitecture logicielle #3 : object oriented design
Architecture logicielle #3 : object oriented design
 
1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object Calisthenics1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object Calisthenics
 
Ch8(oop)
Ch8(oop)Ch8(oop)
Ch8(oop)
 
inheritance
inheritanceinheritance
inheritance
 
Object Oriented Programming Basics with PHP
Object Oriented Programming Basics with PHPObject Oriented Programming Basics with PHP
Object Oriented Programming Basics with PHP
 
Drupal II: The SQL
Drupal II: The SQLDrupal II: The SQL
Drupal II: The SQL
 
Python programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphismPython programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphism
 
Chapter15 structure
Chapter15 structureChapter15 structure
Chapter15 structure
 
Delegate
DelegateDelegate
Delegate
 
Professional-grade software design
Professional-grade software designProfessional-grade software design
Professional-grade software design
 
An Introduction to Object-Oriented Programming (DrupalCamp London 2015)
An Introduction to Object-Oriented Programming (DrupalCamp London 2015)An Introduction to Object-Oriented Programming (DrupalCamp London 2015)
An Introduction to Object-Oriented Programming (DrupalCamp London 2015)
 
oop lecture 3
oop lecture 3oop lecture 3
oop lecture 3
 
Java2
Java2Java2
Java2
 
06 inheritance
06 inheritance06 inheritance
06 inheritance
 
Coding for Scale and Sanity
Coding for Scale and SanityCoding for Scale and Sanity
Coding for Scale and Sanity
 
Lecture18
Lecture18Lecture18
Lecture18
 
Drupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comDrupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.com
 
Demystifying oop
Demystifying oopDemystifying oop
Demystifying oop
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 

En vedette

En vedette (6)

Cartilha para exposição memórias & melodias
Cartilha para exposição memórias & melodiasCartilha para exposição memórias & melodias
Cartilha para exposição memórias & melodias
 
Grade6 ela
Grade6 elaGrade6 ela
Grade6 ela
 
BIZLife magazin, februar 2014.
BIZLife magazin, februar 2014.BIZLife magazin, februar 2014.
BIZLife magazin, februar 2014.
 
What's the weather like 3
What's the weather like 3What's the weather like 3
What's the weather like 3
 
Alfresco day madrid partner - csc
Alfresco day madrid   partner - cscAlfresco day madrid   partner - csc
Alfresco day madrid partner - csc
 
Unit 7 Fifth Grade cs 2012 2013
Unit 7 Fifth Grade cs 2012 2013Unit 7 Fifth Grade cs 2012 2013
Unit 7 Fifth Grade cs 2012 2013
 

Similaire à psnreddy php-oops

Lecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxLecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxDavidLazar17
 
Class 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented ProgrammingClass 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented ProgrammingAhmed Swilam
 
Demystifying Object-Oriented Programming - PHP UK Conference 2017
Demystifying Object-Oriented Programming - PHP UK Conference 2017Demystifying Object-Oriented Programming - PHP UK Conference 2017
Demystifying Object-Oriented Programming - PHP UK Conference 2017Alena Holligan
 
Object Oriented Programming in PHP
Object Oriented Programming  in PHPObject Oriented Programming  in PHP
Object Oriented Programming in PHPwahidullah mudaser
 
Object oriented programming in php
Object oriented programming in phpObject oriented programming in php
Object oriented programming in phpAashiq Kuchey
 
Wordpress (class,property,visibility,const,destr,inheritence,mysql etc)
Wordpress (class,property,visibility,const,destr,inheritence,mysql etc)Wordpress (class,property,visibility,const,destr,inheritence,mysql etc)
Wordpress (class,property,visibility,const,destr,inheritence,mysql etc)Rathod Shukar
 
Demystifying Object-Oriented Programming - PHP[tek] 2017
Demystifying Object-Oriented Programming - PHP[tek] 2017Demystifying Object-Oriented Programming - PHP[tek] 2017
Demystifying Object-Oriented Programming - PHP[tek] 2017Alena Holligan
 
Object Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering College
Object Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering CollegeObject Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering College
Object Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering CollegeDhivyaa C.R
 
Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in phpCPD INDIA
 
Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016Chris Tankersley
 
Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Alena Holligan
 
OOPS IN PHP.pptx
OOPS IN PHP.pptxOOPS IN PHP.pptx
OOPS IN PHP.pptxrani marri
 
Demystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPDemystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPAlena Holligan
 
Demystifying Object-Oriented Programming #phpbnl18
Demystifying Object-Oriented Programming #phpbnl18Demystifying Object-Oriented Programming #phpbnl18
Demystifying Object-Oriented Programming #phpbnl18Alena Holligan
 
Introduction to OOP with PHP
Introduction to OOP with PHPIntroduction to OOP with PHP
Introduction to OOP with PHPMichael Peacock
 

Similaire à psnreddy php-oops (20)

Lecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxLecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptx
 
Class 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented ProgrammingClass 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented Programming
 
Only oop
Only oopOnly oop
Only oop
 
Demystifying Object-Oriented Programming - PHP UK Conference 2017
Demystifying Object-Oriented Programming - PHP UK Conference 2017Demystifying Object-Oriented Programming - PHP UK Conference 2017
Demystifying Object-Oriented Programming - PHP UK Conference 2017
 
Object Oriented Programming in PHP
Object Oriented Programming  in PHPObject Oriented Programming  in PHP
Object Oriented Programming in PHP
 
Object oriented programming in php
Object oriented programming in phpObject oriented programming in php
Object oriented programming in php
 
Wordpress (class,property,visibility,const,destr,inheritence,mysql etc)
Wordpress (class,property,visibility,const,destr,inheritence,mysql etc)Wordpress (class,property,visibility,const,destr,inheritence,mysql etc)
Wordpress (class,property,visibility,const,destr,inheritence,mysql etc)
 
Demystifying Object-Oriented Programming - PHP[tek] 2017
Demystifying Object-Oriented Programming - PHP[tek] 2017Demystifying Object-Oriented Programming - PHP[tek] 2017
Demystifying Object-Oriented Programming - PHP[tek] 2017
 
UNIT III (8).pptx
UNIT III (8).pptxUNIT III (8).pptx
UNIT III (8).pptx
 
UNIT III (8).pptx
UNIT III (8).pptxUNIT III (8).pptx
UNIT III (8).pptx
 
Object Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering College
Object Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering CollegeObject Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering College
Object Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering College
 
Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in php
 
Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016
 
Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016
 
OOPS IN PHP.pptx
OOPS IN PHP.pptxOOPS IN PHP.pptx
OOPS IN PHP.pptx
 
Demystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPDemystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHP
 
Demystifying Object-Oriented Programming #phpbnl18
Demystifying Object-Oriented Programming #phpbnl18Demystifying Object-Oriented Programming #phpbnl18
Demystifying Object-Oriented Programming #phpbnl18
 
Introduction to OOP with PHP
Introduction to OOP with PHPIntroduction to OOP with PHP
Introduction to OOP with PHP
 
Class and object
Class and objectClass and object
Class and object
 
OOP in PHP.pptx
OOP in PHP.pptxOOP in PHP.pptx
OOP in PHP.pptx
 

Dernier

Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 

Dernier (20)

Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 

psnreddy php-oops

  • 1. Definition of a Class A class is user defined data type that contains attributes or data members; and methods which work on the data members. (You will learn more about data members and methods in following tutorials. This tutorial focuses only on learning how to create a Class in PHP5) To create a class, you need to use the keyword class followed by the name of the class. The name of the class should be meaningful to exist within the system (See note on naming a class towards the end of the article). The body of the class is placed between two curly brackets within which you declare class data members/variables and class methods. Example of a Class: class Customer { private $first_name, $last_name; public function setData($first_name, $last_name) { $this->first_name = $first_name; $this->last_name = $last_name; } public function printData() { echo $this->first_name . " : " . $this->last_name; } } In the above program, Customer is the name of the class and $first_name/$last_name are attributes or data members. setData() and printData() are methods of a class. We will discuss more about attributes and members in the upcoming articles on PHP5 OOPS Tutorials series. Definition of an Object An object is a living instance of a class. This means that an object is created from the definition of the class and is loaded in memory. A good analogy to understand this is to compare objects with humans - and understand that all of us (you and I) are objects. If God wants to send a human to earth, what is easy for Him to do? Create and define properties and attributes of each human separately or create a one time template and generate objects out if it. Therefore, this onetime template is a Class and you, I & everyone in this world is an object - that is a living instance of class Human. Creating Objects in PHP5 Class To create an object of a PHP5 class we use the keyword new. Below is the syntax style of how to create objects in PHP5:
  • 2. $obj_name = new ClassName(); In the above syntax style, $obj_name is a variable in PHP. ‘new’ is the keyword which is responsible for creating a new instance of ClassName. class Customer { private $first_name, $last_name; public function getData($first_name, $last_name) { $this->first_name = $first_name; $this->last_name = $last_name; } public function printData() { echo $this->first_name . " : " . $this->last_name; } } $c1 = new Customer(); $c2 = new Customer(); In the above example $c1 and $c2 are two objects of the Customer Class. Both these objects are allocated different blocks in the memory. Look at the diagram below: Therefore, an object is a living instance of a class. Each object / living instance has its own memory space that can hold independent data values. Definition of an class attribute An attribute is also know as data members and is used to hold data of a class. The data that it holds are specific to the nature of the class in which it has been defined. For example, a Customer class would hold data related to a customer, an Order class would hold data related a an order.
  • 3. Attributes can either be public, private or protected - the default being public. These are called Access Specifiers. Example Code: class Customer { private $first_name, $last_name; private $outstanding_amount = 0; //example of default value public function getData($first_name, $last_name) { $this->first_name = $first_name; $this->last_name = $last_name; } public function printData() { echo $this->first_name . " : " . $this->last_name; } } $c1 = new Customer(); Objects as Attributes In addition to declaring attributes as intrinsic data types (int, string, etc), you can also declare data members as objects of another class. This is called aggregation in Object Oriented Analysis and Design (OOAD). Lets look at an example below: class Customer { private $first_name, $last_name; private $outstanding_amount = 0; //example of default value public function getData($first_name, $last_name) { $this->first_name = $first_name; $this->last_name = $last_name; } public function printData() { echo $this->first_name . " : " . $this->last_name; } } class Order { private $order_id; private $customer; public setCust(Customer $c) { $this->customer = $c; } }
  • 4. $c1 = new Customer(); $o1 = new Order(); $o1->setCust($c1); //storing $c1 object in $o1 order object In the above example setCust() method accepts a Customer type of parameter which is stored internally in the $customer data member. The advantage of the above method is that it allows you to change the customer object independently of the order object. Imagine having to add 3 - 4 new data members to the Customer object. You only have to modify the Customer object without having the need to modify the Order Object. Definition of Access Specifiers Access specifiers specify the level of access that the outside world (i.e. other class objects, external functions and global level code) have on the class methods and class data members. Access specifiers can either be public, private or protected. Why do we need Access specifiers Access specifiers are used as a key component of Encapsulation and Data Hiding. By using either of the access specifiers mentioned above i.e. public, private or protected you can hide or show the internals of your class to the outside world. Explanation of each access specifier 1. Private 2. Protected 3. Public 1. Private A private access specifier is used to hide the data member or member function to the outside world. This means that only the class that defines such data member and member functions have access them. Look at the example below: Example: class Customer { private $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } }
  • 5. $c = new Customer(); $c->setName("Sunil Bhatia"); echo $c->name; //error, $name cannot be accessed from outside the class //$name can only be accessed from within the class echo $c->getName(); //this works, as the methods of the class have access //to the private data members or methods In the above example, echo $c->name will give you an error as $name in class Customer has been declared private and hence only be accessed by its member functions internally. Therefore, the following line echo $c->getName() will display the name. 2. Public A public access specifier provides the least protection to the internal data members and member functions. A public access specifier allows the outside world to access/modify the data members directly unlike the private access specifier. Look at the example below: Example: class Customer { public $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } $c = new Customer(); $c->setName("Sunil Bhatia"); echo $c->name; // this will work as it is public. $c->name = "New Name" ; // this does not give an error. In the above example, echo $c->name will work as it has been declared as public and hence can be accessed by class member functions and the rest of the script. 3. Protected A protected access specifier is mainly used with inheritance. A data member or member function declared as protected will be accessed by its class and its base class but not from the outside world (i.e. rest of the script). We can also say that a protected data member is public for the class
  • 6. that declares it and it’s child class; but is private for the rest of the program (outside world). Look at the example below: class Customer { protected $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } class DiscountCustomer extends Customer { private $discount; public function setData($name, $discount) { $this->name = $name; //this is storing $name to the Customer //class $name variable. This works // as it is a protected variable $this->discount = $discount; } } $dc = new DiscountCustomer(); $dc->setData("Sunil Bhatia",10); echo $dc->name; // this does not work as $name is protected and hence // only available in Customer and DiscountCustomer class In the above example, echo $dc->name will not work work $name has been defined as a protected variable and hence it is only available in Customer and DiscountCustomer class. Important Note of Access Specifier in PHP5 In PHP5, access specifiers are public by default. This means that if you don’t specify an access specifier for a data member or method then the default ‘public’ is applicable Definition of an class method A class method/functions is the behavior/functionality of a class i.e. they provide the necessary code for the class in which it is defined. Examples could be a saveCustomer() method in the class Customer or a printDocument() in the Document class.
  • 7. Methods act (perform operations) on the data members of the class and can be declared as private or public. A class method is exactly similar to PHP functions, it’s just that class functions are declared inside classes and accessed using the -> (arrow operator / dereferencing operator). Methods can also be declared as either public, protected or private. Example Code: class Customer { private $name; public functionsetName($name) { $this->name = $name; } } $c1 = new Customer(); $c1->setName("Sunil Bhatia"); In the above example setName() is the class method of the Customer class. The setName() class method is responsible for accepting the name of the customer and storing it in the internal data member i.e. $name. class Customer { private $name; public function setName($name) { if(trim($name) != "") { $this->name = $name; return true; } else { return false; } } } $c1 = new Customer(); $c1->setName("Sunil Bhatia"); In the above example the setName() method accepts a customer’s name and validates to check if $name is blank. If $name is blank the setName() function returns false; otherwise it stores the $name in the $this->name of the class and returns true.
  • 8. Definition of a Constructor A constructor is a special function of a class that is automatically executed whenever an object of a class gets instantiated. It’s special because it is automatically executed or called when an object of a class is created. Why do we need a Constructor? It is needed as it provides an opportunity for doing necessary setup operations like initializing class variables, opening database connections or socket connections, etc. In simple terms, it is needed to setup the object before it can be used. In PHP5 a constructor is defined by implementing the __construct() method. This naming style has been introduced in PHP5. In PHP4, the name of the constructor was the same name as that of the class. PHP5 to be backward complaint also supports the PHP4 rule. When an object is created, PHP5 searches for __construct() first. If __construct() is not defined it then searches for a method with the same that of the class. However, if you define both; PHP5 will first search for __construct() method and execute it if available, otherwise it will execute the same class name function. class Customer { public function __construct() { //code } } Example class Customer { private $first_name; private $last_name; private $outstanding_amount; public function __construct() { $first_name = ""; $last_name = ""; $outstanding_amount = 0; }
  • 9. public function setData($first_name, $last_name, $outstanding_amount) { $this->first_name = $first_name; $this->last_name = $last_name; $this->outstanding_amount = $outstanding_amount; } public function printData() { echo "Name : " . $first_name . " " . $this->last_name . "n"; echo "Outstanding Amount : " . $this->outstanding_amount . "n"; } } $c1 = new Customer(); $c1->setData("Sunil","Bhatia",0); In the above example on line number 26, we create a new object of the Customer class. the ‘new’ operator is responsible for creating the Customer class. At this point PHP5 searches the Customer class to see if a constructor has been defined. Therefore, it calls the constructor method i.e. __construct() defined starting from line no 7. The __construct() method sets the $first_name and $last_name to blank and sets the $outstanding_amount to zero. Parameterized Constructor or Argument Constructor A parameterized or argument constructor is a constructor which accepts values in the form of arguments in the constructor. Unlike other programming languages where overloaded argument constructors is possible, in PHP5 you cannot overload constructors. Example: class Customer { private $first_name; private $last_name; private $outstanding_amount; public function __construct($first_name, $last_name, $outstanding_amount) { $this->setData($first_name, $last_name, $outstanding_amount); } public function setData($first_name, $last_name, $outstanding_amount) { $this->first_name = $first_name; $this->last_name = $last_name; $this->outstanding_amount = $outstanding_amount; } public function printData() {
  • 10. echo "Name : " . $first_name . " " . $this->last_name . "n"; echo "Outstanding Amount : " . $this->outstanding_amount . "n"; } } $c1 = new Customer("Sunil","Bhatia",0); In the above example on line number 24, we create a new object $c1 and pass values “Sunil”, “Bhatia” and zero to the constructor defined on line number starting 7. The constructor now takes 3 arguments and stores them in the internal private variable $first_name, $last_name and $outstanding_amount respectively. Definition of a Destructor A destructor is a special function of a class that is automatically executed whenever an object of a class is destroyed. An object of a class is destroyed Means 1. it goes out of scope, 2. when you specifically set it to null, 3. when you unset it or when the program execution is over. A PHP5 destructor is defined by implementing the __destruct() method. In PHP4 however, the concept of a destructor did not exist. Important Note: A destructor cannot take any arguments. class Customer { public function __destructor() { //code } } Example: class Customer { private $first_name; private $last_name; private $outstanding_amount; public function __construct() { $first_name = ""; $last_name = "";
  • 11. $outstanding_amount = 0; } public function setData($first_name, $last_name, $outstanding_amount) { $this->first_name = $first_name; $this->last_name = $last_name; $this->outstanding_amount = $outstanding_amount; } public function printData() { echo "Name : " . $first_name . " " . $last_name . "n"; echo "Outstanding Amount : " . $outstanding_amount . "n"; } } class Order { private $order_id; private $customer; public function __construct($order_id, $customer) { $this->order_id = $order_id; $this->customer = $customer; } public function __destruct() { unset($this->order_id); unset($this->customer); } } $order_id = "L0001"; $c1 = new Customer(); $c1->setData("Sunil","Bhatia",0); $o = new Order($order_id, $c1); In the above example on line number 45, we create a new object of the Order class. The argument constructor of the Order class takes two parameters i.e. $order_id and $customer object. After the program completes its execution, the object goes out of scope because the program stops execution after line 45 and hence the destructor is automatically called. Accessor Methods: Accessor methods are also know as getter methods. The reason why we need an accessor method is to be able to read the value of a property/attribute in a class object. In real OOAD practice most of the data members that you define would either be private or protected (more on this will be covered in the tutorial on Access specifiers), therefore to access data of such data members
  • 12. that have been defined as either private or protected will require an implementation of accessor or getter methods. Note: To make a property or data member as non-read only; you should not provide a getter or accessor method. Mutator Methods: Mutator methods are opposite to accessor methods. Mutator methods provides a mechanism to store data in data members that have either been declared as private or protected. The reason why you should provide a mutator method is to provide necessary validation on the data that is to be stored in the data member of the class. Note: To make a property or data member as read only; you should not provide a setter or mutator method. Lets look at an example of accessor and mutator methods below: class Customer { private $name; //mutator method public function setName($name) { if(trim($name) != "") { $this->name = $name; return true; } else { return false; } } //accessor method public getName() { return $this->name; } } $c1 = new Customer(); $c1->setName("Sunil Bhatia"); echo $c1->getName(); Output: Sunil Bhatia In the above example the setName() method accepts a customer’s name and validates to check if $name is blank. If $name is blank the setName() function returns false; otherwise it stores the $name in the $this->name of the class and returns true. The getName() returns the name stored in the $name data member of the $c1 object.
  • 13. PHP5 introduces a new operator by the name of instanceOf. instanceOf is used to check if two objects passed as operands belong to the same class. This check can also happen when an object is compared with a class name. In PHP4 a similar functionality existed with a method is_a(), which has been replaced by the instanceOf operator in PHP5. class Person { ... } $p1 = new Person(); $p2 = new Person(); if($p1 instanceof $p2) echo "True"; else echo "False"; In the above example, we are comparing to check if $p1 and $p2 belong to the same class i.e. Person. In this case $p1 and $p2 both belong to the same class Person and hence the output is True. Please note that line number 8 can also be written as if($p2 instanceof $p1) and will yield the same output. You can also use instanceOf operator to compare an object with the name of the class, look at the example below: class Person { ... } $p1 = new Person(); if($p1 instanceof Person) echo "True"; else echo "False"; In the above example, on line number 7 $p1 object is being compared to check if its a Person type of object. In this case $p1 is a Person type of object and hence the output is True. Behaviour of instanceOf operator in inheritance class Customer extends Person { ... } $p1 = new Person(); $c1 = new Customer();
  • 14. if($c1 instanceof $p1) echo "True"; else echo "False"; In the above example, on line number 8 $c1 child class object is being compared with $p1 which is a parent class object. This is possible because Customer class is a child of the Person Class, just that the Customer class is a specialized form of the Person class and therefore this becomes possible. However the reverse is not possible, we cannot compare if($p1 instanceof $c1) and will result in an error. Constants To declare a constant in a class, PHP5 provides developers with a new keyword i.e. const; look at the example below: class Customer { const TYPES = "Anything"; } echo "Types are : " . Customer::TYPES; In the above example, const is a keyword and TYPES is the name of the constant. Outside the class definition we echo the value of the constant by using the scope resolution operator (::) like this Customer::TYPES. Observe that we don’t need to create an object of the class to make use of the constant. The next logical question is if we can create an object of the Customer class and using the scope resolution operator access the constant. The answer is no; reason - because a constant belongs to the class definition scope and not to an object. Example of accessing Constants within a function class Customer { const TYPES = "Anything"; public function showConstant() { echo "Echo from showConstant() : " . Customer::TYPES; } } $c = new Customer(); $c->showConstant(); Output: Echo from showConstant() : Anything
  • 15. Some observations on Constants 1. Variables defined as constants cannot be changed. 2. Only a string or numeric value can be assigned to a constant. 3. Arrays, Objects & Expressions cannot be assigned to a constant. 4. A class constant can only be accessed via the scope resolution operator (::) executed on the class name. 5. A class constant cannot have <a>access specifiers</a> assigned to it (private, public & protected) Definition of Inheritance: Inheritance is the mechanism of deriving a new class from an existing class. It allows a sub- class / child class to share/inherit the attributes and behaviors of a base-class or parent class. These inherited attributes and behaviors are usually modified by means of extension. PHP5 Inheritance To inherit in PHP5, you should use the keyword ‘extends’ in the class definition. In PHP5 only single inheritance is allowed. Look at the example below: class Person { private $name; private $address; public function getName() { return $this->name; } } class Customer extends Person { private $customer_id; private $record_date; public getCustomerId() { return $this->customer_id; } public getCustomerName() { return $this->getName();// getName() is in Person } } In the above example, class Customer extends from the Person class. This means that Customer class is the child class and the Person base class. The child class Customer extends the method getName() and calls it in the getCustomerName() method of the Customer class.
  • 16. Inheritance and Access Specifiers You can refer to the Access specifiers tutorial to understand what it means. Let’s understand the use of Access Specifiers with context to Inheritance. Access specifiers specify the level of access that the outside world (other objects and functions) have on the data members / member functions of the class. Please note that all data members and member functions are public by default. Lets look at how three access specifiers viz. private, public and protected behave in Inheritance: 1. private A private access specifier is used to hide data and member functions. A method or data member declared as private can only be accessed by the class itself and neither the outside program nor the derived class can have access to it. Lets look at an example below: class Customer { private $name; public $age; public function __construct($name, $age) { $this->name = $name; $this->age = $age; } } $c = new Customer("Sunil","28"); echo "Name : " . $c->name; //causes an error In the above example, the statement; echo “Name : ” . $c->name; causes an error as we are trying to access $name that has been declared as a private member variable. We can however access the $age data member without any limitation as its public. Note: When you define a method as private that method can only be called from within that class and not from outside that is the global level script. 2. public A public access specifier allows the data members and methods to be access from anywhere in the script. Lets look at an example below: class Customer { private $name; public $age; public function __construct($name, $age) {
  • 17. $this->name = $name; $this->age = $age; } } $c = new Customer("Sunil","28"); echo "Age : " . $c->age; //prints 28 In the above example, the statement; echo “Age : ” . $c->;age; prints 28 on the screen as $age is a public variable and hence can be accessed from anywhere in the script. Please note that if you declare any data member or method without a access specifier it is considered as ‘public’. 3. protected A protected access specifier allows the derived class to access the data member or member functions of the base class, whereas disallows global access to other objects and functions. class Person { protected $name; } class Customer extends Person { function setName($name) { //this works as $name is protected in Person $this->name = $name; } } $c1 = new Customer(); $c1->setName("Sunil"); $c1->name = "Sunil"; //this causes error as $name is protected and not public In the above example, the statement; $this->name = $name; in the setName() function is referring to the $name data member of the Person class. This access is only possible because the $name variable has been declared as protected. Had this been private; the above statement would have raised an error. Further, in the statement towards the end; $c1->name = “Sunil”; raises an error as $name in the Person class has been declared as protected and not public.
  • 18. PHP5 Inheritance - Method Overriding Lets learn how to override methods in PHP5, but before we understand how to override methods in PHP5; lets define method overriding. Definition of Method Overriding: Method overriding is when the function of base class is re-defined with the same name, function signature and access specifier (either public or protected) of the derived class. The reason to override method is to provide additional functionality over and above what has been defined in the base class. Imagine that you have a class by the name of Bird from which you derive two child classes viz. Eagle and Swift. The Bird class has methods defined to eat, fly, etc, but each of the specialized classes viz Eagle and Swift will have its own style of flying and hence would need to override the flying functionality. Lets look at an example with Bird: class Bird { public function fly() { echo "Fly method of Bird Class called"; } } class Eagle extends Bird { public function fly() { echo "Fly method of the Eagle Class called"; } } class Swift extends Bird { public function fly() { echo "Fly method of the Swift Class called"; } } $e = new Eagle(); $s = new Swift(); $e->fly(); echo "n"; $s->fly(); Output: Fly method of the Eagle Class called Fly method of the Swift Class called In the above example, we create two objects of class Eagle and Swift. Each of these classes have overridden the method fly() and have provided their own implementation of the fly() method that has been extended from the Bird class. The manner in which they have been extended the Bird class fly() method is not called as both these classes have provided a new functionality for the fly() method.
  • 19. Another example of function overriding in Inheritance class Person { function calculateAge($dob) { echo "calculateAge called of Person Classn"; } } class Customer extends Person { function calculateAge($dob) { echo "calculateAge called of Customer Classn"; } } $c1 = new Customer(); $p1 = new Person(); $c1->calculateAge("something"); $p1->calculateAge("something More"); Output: calculateAge called of Customer Class calculateAge called of Person Class PHP5 Inheritance - Invoking parent methods When you override a method of the base class, it’s functionality is completely hidden unless it has been explicitly invoked from the child class. To invoke a parent class method you should use the keyword parent followed by the scope resolution operator followed by the name of the method as mentioned below: parent::function_name(); Look at the example below: class Person { public function showData() { echo "This is Person's showData()n"; } } class Customer extends Person{ public function showData() { parent::showData(); echo "This is Customer's showData()n"; } } $c = new Customer(); $c->showData();
  • 20. Output: This is Person’s showData() This is Customer’s showData() In the above example, look at the way in which the showData() function in the Customer child class is invoking the the Person parent class’s showData() function. When the program executes the showData() method if the Customer class is called which inturn calls the showData() function of the parent class. After the parent class’s showData() function complets its execution the remaining code in showData() function of the Customer class is executed. PHP5 Inheritance - Invoking parent Constructor and Destructor We can get the parent PHP5 constructor and PHP5 Destructor to be invoked in the same way as invoking the parent method, refer to the example below: class Person{ public function __construct() { echo "This is Person's __construct()n"; } public function __destruct() { echo "This is Person's __destruct()n"; } } class Customer extends Person{ public function __construct() { parent::__construct(); echo "This is Customer's __construct()n"; } public function __destruct() { parent::__destruct(); echo "This is Customer's __destruct()n"; } } $c = new Customer(); Output: This is Person’s __construct() This is Customer’s __construct() This is Person’s __destruct() This is Customer’s __destruct() What is an exception?
  • 21. An exception is a logical/system error that occurs during the normal execution of a script. The exception could either be raised by the system or the program itself it the exception cannot be handled and the caller script/function needs to be informed about the same. The use of a try…catch block PHP5 introduces the try…catch block to trap exceptions. Look at the example below. try { check(); } catch(Exception $e) { echo "Message : " . $e->getMessage(); echo "Code : " . $e->getCode(); } function check() { if(some error condition) { throw new Exception("Error String",Error Code); } } In the above example, the method check() is called between the try {} block. The try{} block is the area where you will place your code that could raise an exception. Below the try{} block is the catch() {} block. The catch block expects the Exception type of object as a parameter. Within the catch() {} block you will place your logic to either fix the issue or log the error. In the function check(), we raise an Exception using the ‘throw’ keyword. The statement following ‘throw’ is the syntax of creating a new object of Exception type. The exception class accepts two parameters. The left parameter is a string that is the error message and the right parameter is the integer error code that you wish to assign to that error. Anatomy of PHP5 Exception class class Exception { protected $message; protected $code; protected $file; protected $line; private $string; private $trace; public function __construct($message = null, $code = 0); public function __toString(); final public function getCode();
  • 22. final public function getMessage(); final public function getFile(); final public function getLine(); final public function getTrace(); final public function getTraceAsString(); final private __clone(); } In the above example, except for __construct and __toString(), no other method can be overridden as all other methods are ‘final’. Extending the Exception class You can also extend the exception class as follows: class CustomerException extends Exception { public function __construct($message = null, $code = 0) { $t_message = "Exception raised in CustomerException "; $t_message .= "with message : " . $message; parent::__construct($t_message, $code); } } function testException() { throw new CustomerException("CustomerException has been raised",101); } try { testException(); } catch(CustomerException $e) { echo "Error Message : " $e->getMessage(); echo "Error Code : " $e->getCode(); } Output: Error Message : CustomerException has been raised Error Code : 101 What is an Abstract Class?
  • 23. An abstract class is a class with or without data members that provides some functionality and leaves the remaining functionality for its child class to implement. The child class must provide the functionality not provided by the abstract class or else the child class also becomes abstract. Objects of an abstract and interface class cannot be created i.e. only objects of concrete class can be created To define a class as Abstract, the keyword abstract is to be used e.g. abstract class ClassName {} Example of Abstract Class abstract class Furniture { private $height, width, length; public function setData($h, $w, $l) { $this->height = $h; $this->width = $w; $this->length = $l; } //this function is declared as abstract and hence the function //body will have to be provided in the child class public abstract function getPrice(); } class BookShelf extends Furniture { private $price; public setData($h, $w, $l, $p) { parent::setData($h, $w, $l); $this->price = $p; } //this is the function body of the parent abstract method public function getPrice() { return $this->price; } } In the above example, the method getPrice() in class Furniture has been declared as Abstract. This means that its the responsibility of the child class to provide the functionality of getPrice(). The BookShelf class is a child of the Furniture class and hence provides the function body for getPrice(). Private methods cannot be abstract
  • 24. If a method is defined as abstract then it cannot be declared as private (it can only be public or protected). This is because a private method cannot be inherited. abstract class BaseClass { private abstract function myFun(); } class DerivedClass extends BaseClass { public function myFun() { //logic here } } $d = new DerivedClass(); //will cause error What is an Interface? An interface is a contract between unrelated objects to perform a common function. An interface enables you to specify that an object is capable of performing a certain function, but it does not necessarily tell you how the object does so, this means that it leaves for classes implementing an interface to define its behaviour. To extend from an Interface, keyword implements is used. We can have a class extend from more than one Interface. interface Storable { function getContentsAsText(); } class Document implements Storable { public function getContentsAsText() { return "This is Text of the Documentn"; } } class Indexer { public function readAndIndex(Storable $s) { $textData = $s->getContentsAsText(); //do necessary logic to index echo $textData; } } $p = new Document(); $i = new Indexer(); $i->readAndIndex($p);
  • 25. In the above example, Document and the Indexer class are two independant classes. The Indexer class is designed to index the contents of any text. Using the Storable interface above, we declare a method getContentsAsText() in the Document class. Because the Indexer class is only concerned with the TEXT, hence we can call getContentsAsText() method on the object of Document. This way any class if it implements the method getContentsAsText() can get indexed Difference between Abstract Class and Interface Abstract Classes 1. An abstract class can provide some functionality and leave the rest for derived class 2. The derived class may or may not override the concrete functions defined in base class 3. The child class extended from an abstract class should logically be related Interface 1. An interface cannot contain any functionality. It only contains definitions of the methods 2. The derived class must provide code for all the methods defined in the interface 3. Completely different and non-related classes can be logically be grouped together using an interface Meaning of Polymorphism Polymorphism is derived from two Greek words. Poly (meaning many) and morph (meaning forms). Polymorphism means many forms. In C you have two methods with the same name that have different function signatures and hence by passing the correct function signature you can invoke the correct method. This is how polymorphism is achieved in languages like C where in a function sum(int, int) differs from sum(float, float). Therefore the method sum() has many forms depending on the parameters being passed to it. The meaning with Object Oriented languages changes. With Object Oriented language polymorphism happens: When the decision to invoke a function call is made by inspecting the object at runtime it is called Polymorphism Why method polymorphism cannot be achieved The reason why polymorphism for methods is not possible in PHP is because you can have a method that accepts two parameters and call it by passing three parameters. This is because PHP is not strict and contains methods like func_num_args() and func_get_arg() to find the number of arguments passed and get a particular parameter.
  • 26. Because PHP is not type strict and allows variable arguments, this is why method polymorphism is not possible. PHP 5 Polymorphism Since PHP 5 introduces the concept of Type Hinting, polymorphism is possible with class methods. The basis of polymorphism is Inheritance and overridden methods. Lets look at an example: class BaseClass { public function myMethod() { echo "BaseClass method called"; } } class DerivedClass extends BaseClass { public function myMethod() { echo "DerivedClass method called"; } } function processClass(BaseClass $c) { $c->myMethod(); } $c = new DerivedClass(); processClass($c); In the above example, object $c of class DerievedClass is executed and passed to the processClass() method. The parameter accepted in processClass() is that of BassClass. Within the processClass() the method myMethod() is being called. Since the method is being called on the class variable of BaseClass, it would not be wrong to assume that myMethod() of class BaseClass will be called. But, as per the definition “When the decision to invoke a function call is made by inspecting the object at runtime it is called Polymorphism”, myMethod() will be called on object DerievedClass. The reason why this happens is because the object of DerievedClass is being passed and hence the method myMethod() of DerievedClass will be called. Why method polymorphism cannot be achieved The reason why polymorphism for methods is not possible in PHP is because you can have a method that accepts two parameters and call it by passing three parameters. This is because PHP is not strict and contains methods like func_num_args() and func_get_arg() to find the number of arguments passed and get a particular parameter.
  • 27. Because PHP is not type strict and allows variable arguments, this is why method polymorphism is not possible. PHP 5 Polymorphism Since PHP 5 introduces the concept of Type Hinting, polymorphism is possible with class methods. The basis of polymorphism is Inheritance and overridden methods. Lets look at an example: class BaseClass { public function myMethod() { echo "BaseClass method called"; } } class DerivedClass extends BaseClass { public function myMethod() { echo "DerivedClass method called"; } } function processClass(BaseClass $c) { $c->myMethod(); } $c = new DerivedClass(); processClass($c); In the above example, object $c of class DerievedClass is executed and passed to the processClass() method. The parameter accepted in processClass() is that of BassClass. Within the processClass() the method myMethod() is being called. Since the method is being called on the class variable of BaseClass, it would not be wrong to assume that myMethod() of class BaseClass will be called. But, as per the definition “When the decision to invoke a function call is made by inspecting the object at runtime it is called Polymorphism”, myMethod() will be called on object DerievedClass. The reason why this happens is because the object of DerievedClass is being passed and hence the method myMethod() of DerievedClass will be called. PHP magic methods
  • 28. PHP5 provides a magic method by the name of __toString() (double underscore followed by toString()) which is useful for debugging purposes. The __toString() method is automatically called when an object in PHP5 is converted into a string for the purpose of display or concatenation Following is the example of the __toString() method: <?php class Customer { private $firstName, $lastName, $email; public function __construct($firstName, $lastName, $email) { $this->firstName = $firstName; $this->lastName = $lastName; $this->email = $email; } public function __toString() { return “Debug message from Customer Class : First Name = ” . $this->firstName . “, Last Name = ” . $this->lastName . “, Email = ” . $this->email; } } $c = new Customer(”Sunil”,”Bhatia”,”email@domain.com”); echo “Customer Object is >>” . $c; ?> Output: Customer Object is >> Debug message from Customer Class : First Name = Sunil, Last Name = Bhatia, Email = email@domain.com See how in this example $c Customer Object got converted into a string type when used with the dot (.) concatenation operator. In the background the magic method __toString() is automatically called when such a conversion happens. Security Tip: Be careful not to include sensitive data as part of the output as you could compromise security by leaking secure information. Many applications are written to write object states in a log file, therefore you should ensure that sensitive information like Credit Card information, etc is not made available through the magic method __toString()
  • 29. By default PHP is a Loosely typed language and therefore it is not necessary to declare variables before using them. This also holds true for using class members. Look at an example below. <?php class Customer { public $name; } $c = new Customer(); $c->name = “Sunil”; // $name is set because its public $c->email = “email@domain.com”; //assigning email@domain.com to the $email variable. ?> Ideally in a strict language this would have been an error. But, with PHP this works perfectly well as you can assign values to an undefined variable. Because of the above limitation, PHP engine provides two magic methods __get() and __set(). __get() is used when value from an undefined variable is to be read and __set() is used when a value is to be assigned to a undefined variable of a class. __set() allows you to provide functionality to validate data being stored. See example below: <?php class Customer { public $name; private $data = array(); public function __set($dt, $vl) { $this->data[$dt] = $vl; } public function __get($dt) { return $this->data[$dt]; } } $c = new Customer(); $c->name = “Sunil”; // $name is set because its public $c->email = “email@domain.com”; //assigning email@domain.com to the $email variable.
  • 30. echo $c->email; ?> In the above example when email@domain.com is assigned to the undefined variable $email, the magic method __set() is called. To this __set() method the name of the variable is passed into $dt variable of __set() method and the value i.e. email@domain.com is passed to $vl variable of the __set() method. The next step is to store these values into the $data array so that you could retrieve it later. The __get() method works in the similar fashion. When you echo $c->email, __get() method is called and the name email is passed in the $dt of the __get() method. Tip: It is possible to stop this behavior of PHP to assign values to undefined issues. The solution is that you raise an exception from within __set() method. Look at the code below: <? class Customer { private $name; public function __set($dt, $vl) { throw new Exception(”Cannot assign values to undefined variables”,1); } } $c = new Customer(); $c->email = “email@domain.com”; //this will cause an exception to be raised ?> magic methods __isset() and __unset() These methods are automatically called internally when isset() and unset() is called on undeclared data members. The magic method __isset() method receives an argument - the value of which is the name of the variable that the program wants to test if the variable is set or not. The magic method __unset() method receives an argument - the value of which is the name of the variable that the program wants to unset.
  • 31. Look at the example below: class Customer { private $data = array(); public function __set($dt, $vl) { $this->data[$dt] = $vl; } public function __get($dt) { return $this->data[$dt]; } public function __isset($dt) { return isset($this->data[$dt]); } public function __unset($dt) { return unset($this->data[dt]); } } $c = new Customer(); $c->name = “Sunil Bhatia”; echo isset($c->name).”n”; echo unset($c->name); In the example above the script creates a new Customer Object. The program assigns a string value to an undeclared variable i.e. $c->name. The undeclared variable is handled by the magic method __set(). The program ties to check if the undeclared variable i.e., $c->name has been set or not using the PHP method isset(). Since $c->name is an undeclared variable the PHP5 magic method __isset() is invoked that takes the name of the undeclared variable i.e. ‘name’ and checks if the internal array $data[’name’] is set or not. Similarly, when the program calls unset() on the undeclared variable i.e. $c->name, the PHP5 magic method __unset() is invoked that takes the name of the undeclared variable i.e. ‘name’ and unsets the internal array $data[’name’]. The magic method __call() is to undeclared methods what __get() and __set() are to undeclared data member. These methods are automatically called internally when the program tires to execute a method that has not been defined within the class at the time of development.
  • 32. The magic method __call() takes two arguments. The first argument is the name of the undeclared method invoked by the program and the second is an array that contains a list of parameters passed to the undeclared array. Look at the example below: class Customer { public function __call($name, $args) { var_dump($name); echo "n"; var_dump($args); echo "n"; } } $c = new Customer(); $c->setName("Sunil","Bhatia"); Output: string(7) “setName” array(2) { [0]=> string(5) “Sunil” [1]=> string(6) “Bhatia” } In the example above, an object of the Customer class is created and an undeclared method viz. $c->setName is called. The magic method __call() is internally executed which accepts two parameters. The first parameter ‘$name’ contains the name of the method i.e. ’setName’ and the second parameter ‘$args’ contains the arguments passed to the ’setName’ method i.e ‘Sunil’ & ‘Bhatia’. Using this method, you can provide code to handle calls to undeclared method. To disallow programs to call an undeclared method, you should raise an exception from within __call() magic method. Look at the example below: class Customer { public function __call($name, $args) { throw new Exception("Undeclared method execution not allowed",10); } }
  • 33. $c = new Customer(); $c->setName("Sunil","Bhatia"); Output: Fatal error: Uncaught exception ‘Exception’ with message ‘Undeclared method execution not allowed’ in D:sunilbwebsiteprogsmagic_call.php:6 Stack trace: #0 [internal function]: Customer->__call(’setName’, Array) #1 D:sunilbwebsiteprogsmagic_call.php(11): Customer->setName(’Sunil’, ‘Bhatia’) #2 {main} thrown in D:sunilbwebsiteprogsmagic_call.php on line 6 In the above program, when the script calls an undeclared variable $c->setName(), the magic method __call() is executed. On executing the magic method __call(), an exception is raised and the execution of the program stops there (unless we use the try..catch statements) Many people debate that the magic method __autoload() causes a performance overhead. Well, that is not the case. There is no performance penalty to pay. In fact, there may be performance improvements if not all classes are used all the time. This is explained below. Using the magic method __autoload has the beneficial side effect of requiring strict naming conventions for files that hold class definitions. Look at the example below: include “customer.php”; include “orders.php”; $c = new Customer(); In the example displayed above, an instance of class Customer is created. Therefore, we only need the customers.php file. The file orders.php is not needed. This means that we should only have included the customer.php file. But, what if during execution on the basis of a condition, an instance of class Orders would have to be created. Therefore you need to include both the files i.e. customer.php and orders.php But this causes performance issues. Each time the above script is executed, orders.php is included. To avoid this performance hit, we would have to do additional programming to ensure that the file orders.php is loaded only when needed. This is the reason why magic method __autoload() should be used. Look at the example below:
  • 34. function __autoload($class) { require $class . '.php'; //is substituted as require Customer.php (with capital 'C') } $c = new Customer(); In the above program, we don’t explicitly include customer.php and orders.php file. When an instance of the customer class is to be created, the PHP engine checks to see if the file Customer.php is loaded. It does not raise an warning on finding that Customer.php has not been loaded, it in turn calls the magic method __autoload(). The __autoload() magic method accepts a parameter which is the name of the class that needs to be loaded Therefore, on the line when an instance of the customer class is created i.e. object $c, magic method __autoload() is called with the parameter $class containing value ‘Customer’. Within the __autoload() method we call the ‘require’ method. The require method tries to load $class.’php’ file i.e. Customer.php. Therefore, as stated earlier, the __autoload() method has its beneficial side effect of requiring strict file naming convention. The __autoload() method is called only once for each new class that needs to be loaded. Subsequent instantiation of the Customer class object will not call the __autoload() method again. Therefore, this offers performance improvements in your scripts because, unless the class is needed - files are not loaded. Therefore, the PHP engine does not have to parse and compile an unnecessary file. Working with the magic method __sleep() __sleep() magic method is called when the object of a class is about to be serialized. This magic method __sleep() does not accept any parameter and returns an array. The array should contain a list of class members that should be serialized. This means that if you don’t wish to serialize a particular class member, you should not include it in the array. Look at the example below: class Customer { private $name; private $credit_card_number; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setCC($cc) { $this->credit_card_number = $cc;
  • 35. } public function getCC() { return $this->credit_card_number; } public function __sleep() { return array("name"); //because of this, only name is serialized } } $c = new Customer(); $c->setName("Sunil"); $c->setCC("1234567890123456"); $data = serialize($c)."n"; echo $data."n"; Output: O:8:”Customer”:1:{s:14:” Customer name”;s:5:”Sunil”;} In the above example, you can see that the serialized string data only contains the name of the Customer Object. This is because the __sleep() magic method returned an array containing only the ‘name’ data member. Working with the magic method __wakeup() __wakeup() magic method is the opposite of the __sleep() method. It is called when the object of a class is about to be unserialized. This magic method __wakeup() does not accept any parameter nor returns anything. The __wakeup() method is responsible for setup operations after an object has been unserialized. Look at the example below: class Customer { private $name; private $credit_card_number; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setCC($cc) { $this->credit_card_number = $cc; } public function getCC() { return $this->credit_card_number; }
  • 36. public function __sleep() { return array("name"); } public function __wakeup() { if($this->name == "Sunil") { //you would ideally fetch CC data from Database $this->credit_card_number = "1234567890123456"; } } } $c = new Customer(); $c->setName("Sunil"); $c->setCC("1234567890123456"); $data = serialize($c)."n"; var_dump(unserialize($data)); Output: object(Customer)#2 (2) { [”name:private”]=> string(5) “Sunil” [”credit_card_number:private”]=> string(16) “1234567890123456″ } In the above example, you can see that after the $c object has been serialized and the output stored in $data variable, we use the $data variable and pass it to the unserialize(). Before the object is unserizlied and object created, the __wakeup() method is called. In the __wakeup() method you should ideally make a database call to fetch data of the missing member variable. To clone an object means to create a duplicate of an object. With regular variables $a = $b means that a new variable $a gets created that contains the value of $b. This means that 2 variables get created. With objects $obj2 = $obj1 does not mean that a new object i.e. $obj2 gets created. When we execute $obj2 = $obj1, the reference of $obj1 is assigned to $obj2. This means that $obj1 and $obj2 point to the same memory space. Look at the diagram below.
  • 37. Lets look at an example where only references are assigned to another object: class Customer { private $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } $c1 = new Customer(); $c1->setName("Sunil"); $c2 = $c1; //only reference or memory assigned to $c2 $c2->setName("Vishal"); echo $c1->getName()."n"; echo $c2->getName()."n"; Output: Vishal Vishal In the above example, $c2 has the reference of $c1; therefore, when you set a new name in the $c2 object - $c1 object changes as well. Therefore, when an object is assigned as a reference; changes made to one object are also reflected in the other. Therefore, to create a new $obj2 object we must clone an object to create a new one. To clone an PHP5 Object a special keyword i.e. clone is used. Example below: $obj2 = clone $obj1; After the above line is executed $obj2 with a new memory space is created with the data members having the same value as that of $obj1. This is also referred to as shallow copy.
  • 38. The above technique works with a class having data members that are of intrinsic type i.e. int, boolean, string, float, etc.. However, this technique will not work with a class that has a data member which is an object of another class. In such a scenario, the cloned object continues to share the reference of the data member object of the class that was cloned. So, how do we resolve this issue? Doing a regular shallow copy won’t help us. To allow aggregated objects (i.e. data members that are objects of another class) to also get cloned properly we need to use the concept of ‘deep copy‘ as opposed to ‘shallow copy‘. To implement a ‘deep copy‘ you should implement the magic method __clone(). You could also provide the implementation of __clone() magic method even when you don’t have an aggregated object. You would want to do this for providing necessary clean up operations, conversions or validations. Lets explore a very simple example of cloning intrinsic data types: class Customer { private $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function __clone() { $c = new Customer(); $c->setName($this->name); return $c; } } $c1 = new Customer(); $c1->setName("Sunil"); $c2 = clone $c1; //new object $c2 created $c2->setName("Vishal"); echo $c1->getName()."n"; echo $c2->getName()."n"; Output: Sunil Vishal In the above example, observe the line where the statement $c2 = clone $c1 is executed. This is internally represented as $c2 = $c1.__clone(). However, you cannot explicitly call the __clone()
  • 39. method on an object as the __clone() is automatically called. Now that $c1 and $c2 are two individual objects, changes made to one object is not reflected in the other. Cloning aggregate objects (i.e. data members that are objects of another class) To clone a class having aggregated objects, you should perform ‘deep copy‘. Please refer to the example below: class Order { private $order_id; private $customer; public function setOrderId($order_id) { $this->order_id = $order_id; } public function getOrderId() { return $this->order_id; } public function setCustomer(Customer $customer) { $this->customer = clone $customer; } public function getCustomer() { return $this->customer; } public function __clone() { $o = new Order(); $o->setOrderId($this->order_id); //force a copy of the same object to itself, otherwise //it takes the same instance. Seems like a bug to me $this->customer = clone $this->customer; $o->setCustomer($this->customer); return $o; } } class Customer { private $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function __clone() {
  • 40. $c = new Customer(); $c->setName($this->name); return $c; } } $c = new Customer(); $c->setName("Sunil"); $o1 = new Order(); $o1->setOrderId("OD0001"); $o1->setCustomer($c); $o2 = clone $o1; $o2->getCustomer()->setName("Vishal"); var_dump($c); var_dump($o1); var_dump($o2); Output: object(Customer)#1 (1) { [”name:private”]=> string(5) “Sunil” } object(Order)#2 (2) { [”order_id:private”]=> string(6) “OD0001″ [”customer:private”]=> object(Customer)#3 (1) { [”name:private”]=> string(5) “Sunil” } } object(Order)#4 (2) { [”order_id:private”]=> string(6) “OD0001″ [”customer:private”]=> object(Customer)#6 (1) { [”name:private”]=> string(6) “Vishal” } } In the above example both $o1 and $o2 have their own set of customer objects, therefore changes made to one object is not reflected in another. This example implements the concepts of ‘deep copy‘.
  • 41. A special note on $this->customer = clone $this->customer; For some reason it is necessary to do this for proper working of aggregated cloning.