Author: saqibkhan

  • Encapsulation

    PHP implements encapsulation, one of the important principles of OOP with access control keywords: public, private and protected.

    Encapsulation refers to the mechanism of keeping the data members or properties of an object away from the reach of the environment outside the class, allowing controlled access only through the methods or functions available in the class.

    The following diagram illustrates the principle of encapsulation in object-oriented programming methodology.

    PHP Encapsulation 1

    PHP’s keywords list contains the following keywords that determine the accessibility of properties and methods of an object, which is an instance of a class in PHP −

    • Public − Class members are accessible from anywhere, even from outside the scope of the class, but only with the object reference.
    • Private − Class members can be accessed within the class itself. It prevents members from outside class access even with the reference of the class instance.
    • Protected − Members can be accessed within the class and its child class only, nowhere else.

    These three keywords “public, private and protected” are often called access modifiers. They are also referred as visibility modes, as they decide upto what extent a certain class member is available.

    Public Members

    In PHP, the class members (both member variables as well as member functions) are public by default.

    Example

    In the following program, the member variables title and price of the object are freely accessible outside the class because they are public by default, if not otherwise specified.

    Open Compiler

    <?php
       class Person {
       
    
      /* Member variables */
      var $name;
      var $age;
      /*Constructor*/
      function __construct(string $param1="Ravi", int $param2=28) {
         $this-&gt;name = $param1;
         $this-&gt;age = $param2;
      }
      function getName() {
         echo "Name: $this-&gt;name" . PHP_EOL;;
      }
      function getAge() {
         echo "Age: $this-&gt;age" . PHP_EOL;;
      }
    } $b1 = new Person(); $b1->getName(); $b1->getAge(); echo "Name : $b1->name Age: $b1->age" . PHP_EOL; ?>

    It will produce the following output −

    Name: Ravi
    Age: 28
    Name : Ravi Age: 28
    

    Note that the properties all the class members are public by default, you can explicitly declare them as public if desired. As a result, the instance methods getName() and getAge() can be called from outside the class.

    Since properties name and age are also public, hence they can also be accessed outside the class, something which is not desired as per the principle of encapsulation.

    Private Members

    As mentioned above, the principle of encapsulation requires that the member variables should not be accessible directly. Only the methods should have the access to the data members. Hence, we need to make the member variables private and methods public.

    Example

    Let us change the declaration of name and age properties to private and run the following PHP script −

    Open Compiler

    <?php
       class Person {
       
    
      /* Member variables */
      private $name;
      private $age;
      /*Constructor*/
      function __construct(string $param1="Ravi", int $param2=28) {
         $this-&gt;name = $param1;
         $this-&gt;age = $param2;
      }
      public function getName() {
         echo "Name: $this-&gt;name" . PHP_EOL;;
      }
      public function getAge(){
         echo "Age: $this-&gt;age" . PHP_EOL;;
      }
    } $b1 = new Person(); $b1->getName(); $b1->getAge(); echo "Name : $b1->name Age: $b1->age" . PHP_EOL; ?>

    It will produce the following output −

    Name: Ravi
    Age: 28
    PHP Fatal error:  Uncaught Error: Cannot access private property Person::$name in person.php:27
    

    The error message tells the reason that a private property cannot be accessed from a public scope.

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Protected Members

    The effect of specifying protected access to a class member is effective in case of class inheritance. We know that public members are accessible from anywhere outside the class, and private members are denied access from anywhere outside the class.

    The protected keyword grants access to an object of the same class and an object of its inherited class, denying it to any other environment.

    Example

    Let us inherit the person class and define a student class. We shall change the name property from private to protected. The student class has a new public method getDetails() that prints the values of name and age properties.

    Person class

    <?php
    class Person {
    
       /* Member variables */
       protected $name;
       private $age;
    
       /*Constructor*/
       function __construct(string $param1="Ravi", int $param2=28) {
    
      $this-&gt;name = $param1;
      $this-&gt;age = $param2;
    } public function getName(){
      echo "Name: $this-&gt;name" . PHP_EOL;;
    } public function getAge() {
      echo "Age: $this-&gt;age" . PHP_EOL;;
    } }

    Student class

    classstudentextendsPerson{publicfunctiongetDetails(){echo"My Name: $this->name".PHP_EOL;echo"My age: $this->age".PHP_EOL;}}$s1=newstudent();$s1->getDetails();?>

    It will produce the following output −

    My Name: Ravi
    PHP Warning:  Undefined property: student::$age in person.php on line 28
    My age:
    

    The following table illustrates the rules of accessibility of class members in PHP −

    PHP Encapsulation 2
  • Object Iteration

    foreach loop may be employed to iterate through all the publicly visible members of an object of a PHP class. This feature has been available in versions of PHP 5 onwards. You can of course access the list of private properties inside an instance method. PHP also defines Iterator interface which can be used for the purpose.

    Using foreach Loop

    In the example below, the public properties of the class are listed with the use of foreach loop.

    Example

    Open Compiler

    <?php
       class myclass {
    
      private $var;
      protected $var1;
      public $x, $y, $z;
      public function __construct() {
         $this-&gt;var="Hello World";
         $this-&gt;var1=array(1,2,3);
         $this-&gt;x=100;
         $this-&gt;y=200;
         $this-&gt;z=300;
      }
    } $obj = new myclass(); foreach($obj as $key => $value) {
      print "$key =&gt; $value\n";
    } ?>

    It will produce the following output −

    x => 100
    y => 200
    z => 300
    

    Note that only the public members are accessible outside the class. If the class includes a method, all the members (public, private or protected) can be traversed with a foreach loop from inside it.

    Let us add an iterate method in the above myclass.

    publicfunctioniterate(){foreach($thisas$k=>$v){if(is_array($v)){var_dump($v);echoPHP_EOL;}else{echo"$k : $v".PHP_EOL;}}}

    Call this instance method to get the list of all the members.

    It will produce the following output −

    var : Hello World
    array(3) {
       [0]=>
       int(1)
       [1]=>
       int(2)
       [2]=>
       int(3)
    }
    x : 100
    y : 200
    z : 300
    

    Using Iterator Interface

    PHP provides Iterator interface for external iterators or objects that can be iterated themselves internally. It defines following abstract methods which need to be implemented in the user defined class.

    interfaceIteratorextendsTraversable{/* Methods */publiccurrent():mixedpublickey():mixedpublicnext():voidpublicrewind():voidpublicvalid():bool}
    • The rewind() method rewinds the Iterator to the first element. This is the first method called when starting a foreach loop. It will not be executed after foreach loops.
    • The current() method returns the current element.
    • The key() method returns the key of the current element on each iteration of foreach loop.
    • The next() method is called after each iteration of foreach loop and moves forward to next element.
    • The valid() method checks if current position is valid.

    Example

    The following example demonstrates object iteration by implementing Iterator interface

    Open Compiler

    <?php
       class myclass implements Iterator {
    
      private $arr = array('a','b','c');
      public function rewind():void {
         echo "rewinding\n";
         reset($this-&gt;arr);
      }
      public function current() {
         $var = current($this-&gt;arr);
         echo "current: $var\n";
         return $var;
      }
      public function key() {
         $var = key($this-&gt;arr);
         echo "key: $var\n";
         return $var;
      }
      public function next() : void {
         $var = next($this-&gt;arr);
         echo "next: $var\n";
         # return $var;
      }
      public function valid() : bool {
         $key = key($this-&gt;arr);
         $var = ($key !== NULL &amp;&amp; $key !== FALSE);
         echo "valid: $var\n";
         return $var;
      }
    } $obj = new myclass(); foreach ($obj as $k => $v) {
      print "$k: $v\n";
    } ?>

    It will produce the following output −

    rewinding
    valid: 1
    current: a
    key: 0
    0: a
    next: b
    valid: 1
    current: b
    key: 1
    1: b
    next: c
    valid: 1
    current: c
    key: 2
    2: c
    next:
    
  • Namespaces

    We often organize the files in different folders. Usually a folder contains files related to a certain objective, or application or category. A folder can’t contain two files with the same name, though different folders may have a file of the same name so that the path of each file is different.

    The idea of namespaces in PHP is somewhat similar. In PHP, namespaces allow classes or functions or constants of same name be used in different contexts without any conflict, thereby encapsulating these items.

    A PHP namespace is logical grouping of classes/functions etc., depending on their relevance. Just as a file with same name can exist in two different folders, a class of a certain name can be defined in two namespaces. Further, as we specify the complete path of a file to gain access, we need to specify full name of class along with namespace.

    As your application size becomes bigger, involving many class and function definitions, giving give a unique name to each class/function may become tedious and not exactly elegant. Using namespaces lets you organize such code blocks in a neat manner. For example, if we need to declare a calculate() function to calculate area as well as tax, instead of defining them as something like calculate_area() and calculate_tax(), we can create two namespaces area and tax and use calculate() inside them.

    Advantages of Namespace

    Here are some of the advantages of using namespaces in PHP −

    • Namsepaces help in avoiding name collisions between classes/functions/constants defined by someone with third-party classes/functions/constants.
    • Namespaces provide the ability to alias (or shorten) Extra_Long_Names, thereby improving the readability of source code.
    • PHP Namespaces provide a way in which to group related classes, interfaces, functions and constants. Namespace names are case – insensitive.

    Defining a Namespace

    PHP’s namespace keyword is used to define a new namespace.

    namespacemyspace;

    A “.php” file containing a namespace must declare the namespace at the top of the file before any other (except the declare directive). Declaration of class, function and constants inside a namespace affects its access.

    A PHP script may contain other code apart from the definition of a namespace. To load the namespace defined in the same code, PHP has the “use” keyword.

    usemyspace;

    Example

    In the following “hello.php” script, we define a hello() function inside myspace namespace, and call it after loading the namespace in the current script.

    Open Compiler

    <?php
       namespace myspace;
       function hello() {
    
      echo "Hello World";
    } use myspace; myspace\hello(); ?>

    It will produce the following output −

    Hello World
    

    Note that you must qualify the hello() function with its full name that includes the namespace – myspace\hello().

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Include Namespace

    You may have one script consisting of a declaration of a namespace, and the other script in which the namespace is loaded with include statement.

    a.php

    <?php
       namespace myspace {
    
      function hello() {
         echo "Hello World in myspace";
      }
    } ?>

    b.php

    <?php
       include 'a.php';
       myspace\hello();
    ?>

    It will produce the following output −

    Hello World in myspace
    

    There may be a case where the current script (“b.php” as above) also has a function of the same name as in the included file. The fully qualified function that prepends the namespace, helps the parser to resolve the name conflict.

    Example

    Take a look at the following example −

    <?php
       include 'a.php';
       function hello() {
    
      echo "Hello World from current namespace";
    } hello(); myspace\hello(); ?>

    It will produce the following output −

    Hello World from current namespace
    Hello World in myspace
    

    Example

    As mentioned above, the namespace declaration must be at the top, immediately after the opening <?php tag. Otherwise the parser throws a fatal error.

    Open Compiler

    <?php
       echo "hello"
       namespace myspace;
       function hello() {
    
      echo "Hello World";
    } use myspace; myspace\hello(); ?>

    It will produce the following output −

    PHP Parse error:  syntax error, unexpected token "namespace", 
    expecting "," or ";" in /home/cg/root/67771/main.php on line 4
    

    The above error message makes it clear that only the “declare statement” is allowed to appear before the namespace declaration.

    Open Compiler

    <?php
       declare (strict_types=1);
       namespace myspace;
       function hello() {
    
      echo "Hello World";
    } use myspace; myspace\hello(); ?>

    Relative Namespace

    The objects such as functions, classes and constants may be accessed in the current namespace by referring the with relative namespace paths.

    In the following example, “b.php” contains a namespace space1\myspace with a hello() function and a TEMP constant. The same objects are also defined in namespace space1, present in “a.php”.

    Obviously, when “b.php” is included in “a.php”, “myspace” is a subspace of “space1”. Hence, hello() from “myspace” is called by prefixing its relative namespace (also the TEMP constant)

    b.php

    <?php
       namespace space1\myspace;
       const TEMP = 10;
       function hello() {
    
      echo "Hello from current namespace:" . __NAMESPACE__ . ;
    } ?>

    a.php

    <?php
       namespace space1;
       include 'b.php';
       function hello() {
    
      echo "Hello from current namespace:" . __NAMESPACE__ . ;
    } const TEMP = 100; hello(); // current namespace myspace\hello(); // sub namespace echo "TEMP : " . TEMP . " in " . __NAMESPACE__ . ; echo "TEMP : " . myspace\TEMP . " \\in space1\\myspace\n"; ?>

    It will produce the following output −

    Hello from current namespace:space1
    Hello from current namespace:space1\myspace
    TEMP : 100 in space1
    TEMP : 10 in space1\myspace
    

    Absolute Namespace

    You can also access the functions/constants from any namespace by prefixing the absolute namespace path. For example, hello() in “b.php” is “\space\myspace\hello()”.

    a.php

    <?php
       namespace space1;
       include 'b.php';
       function hello() {
    
      echo "Hello from current namespace:" . __NAMESPACE__ . ;
    } const TEMP = 100; \space1\hello(); //current namespace \space1\myspace\hello(); //sub namespace echo "TEMP: " . \space1\TEMP . " in " . __NAMESPACE__ . ; echo "TEMP: " . \space1\myspace\TEMP . " in space1\\myspace\n"; ?>

    The __NAMESPACE__ is a predefined constant in PHP that returns the name of current namespace.

    Namespace Rules

    Any conflict in the names of function/classes/constants appearing between different namespaces is resolved by following these rules −

    • A namespace identifier without namespace separator symbol (/) means it is referring to current namespace. This is an unqualified name.
    • If it contains separator symbol as in myspace\space1, it resolves to a subnamespace space1 under myspace. Such type of naming is relative namespace.
    • Name of fully qualified namespace starts with the “\” character. For example, “\myspace” or “\myspace\space1”.
    • Fully qualified names resolve to absolute namespace. For example \myspace\space1 resolves to myspace\space1 namespace
    • If the name occurs in the global namespace, the “namespace\” prefix is removed. For example, “namespace\space1” resolves to space1.
    • However, if it occurs inside another namespace, it is treated differently. For example, if namespace\space1 is inside myspace, it is equivalent to “myspace\space1”.
    • First segment of the name in qualified name is translated according to the current class/namespace import table.
    • If no import rule applies, the current namespace is prepended to the name.
    • class-like names are translated according to the class/namespace import table, function names according to the function import table and constants according to the constant import table.
    • For unqualified names, if no import rule applies and the name refers to a function or constant and the code is outside the global namespace, the name is resolved at runtime. First it looks for a function from the current namespace, then it tries to find and call the global function.
  • Static Properties

    The “static” keyword in PHP is used to define static properties and static methods in a PHP class. It may be noted that the static keyword is also used to define static variable, and static anonymous functions. Read this chapter to learn about the static properties in a PHP class.

    In a class definition, a variable declared with a static qualifier becomes its static property. The static keyword may appear before or after the access modifier.

    staticprivate$var1;publicstatic$var2;

    If you want to use type hints, the type must not be before the static keyword.

    staticprivatestring$var1;publicstaticfloat$var2;

    The value of the static property in a class is not accessible by its object (with the -> operator). Doing so will result in a notice stating Accessing static property myclass::$var1 as non static. Instead, the static properties are accessed using the Scope Resolution Operator represented by the “::” symbol.

    Example

    Take a look at the following example −

    Open Compiler

    <?php
       class myclass {
    
      static string $var1 = "My Class";
      function __construct() {
         echo "New object declared" . PHP_EOL;
      }
    } $obj = new myclass; echo "accessing static property with scope resolution operator: " . myclass::$var1 . PHP_EOL; echo "accessing static property with -> operator: ". $obj->var1 . PHP_EOL; ?>

    It will produce the following output −

    New object declared
    accessing static property with scope resolution operator: My Class
    PHP Notice:  Accessing static property myclass::$var1 as non static in hello.php on line 14
    

    The “self” Keyword

    To access the static property from inside a method, refer to the current class with the self keyword. In the following example, the class has an integer static property, which is incremented every time a new object is declared.

    Open Compiler

    <?php
       class myclass {
       
    
      /* Member variables */
      static int $var1 = 0;
      function __construct(){
         self::$var1++;
         echo "object number ". self::$var1 . PHP_EOL;
      }
    } for ($i=1; $i<=3; $i++) {
      $obj = new myclass;
    } ?>

    It will produce the following output −

    object number 1
    object number 2
    object number 3
    

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    The “parent” Keyword

    The static property of a base class can be used inside a function of the inherited class by referring to the base by parent keyword. You need to use the “parent::static_property” syntax.

    Example

    Take look at the following example −

    Open Compiler

    <?php
       class myclass {
       
    
      /* Member variables */
      static int $var1 = 0;
      function __construct() {
         self::$var1++;
         echo "object number ". self::$var1 . PHP_EOL;
      }
    } class newclass extends myclass{
      function getstatic() {
         echo "Static property in parent class: " . parent::$var1 . PHP_EOL;
      }
    } $obj = new newclass; $obj->getstatic(); ?>

    It will produce the following output −

    object number 1
    Static property in parent class: 1
    
  • Static Methods

    The “static” keyword in PHP is used to define static properties and static methods in a PHP class. It may be noted that the static keyword is also used to define static variable, and static anonymous functions. This chapter discusses static methods in a PHP class.

    In a class definition, a function declared with a static qualifier becomes its static method.

    classmyclass{publicstaticfunctionmyStaticMethod(){// ...}

    You don’t need to create the instance of the class to call its static method. The static method is called by the class name though the scope resolution operator. The syntax of a static method call is −

    myclass::myStaticMethod();

    As the static methods are callable without creating an instance of the class, the pseudo-variable $this is not available inside static methods. A static method is allowed to be called by an object, although calling an instance method as a static method raises error.

    Example

    Take a look at the following example −

    Open Compiler

    <?php
       class myclass {
       
    
      /* Member variables */
      static int $var1 = 0;
      public static function mystaticmethod() {
         echo "This is a static method".  PHP_EOL;
      }
      public function myinstancemethod() {
         echo "This is an instance method".  PHP_EOL;
      }
    } myclass::mystaticmethod(); $obj = new myclass; $obj->myinstancemethod(); $obj->mystaticmethod(); myclass::myinstancemethod(); ?>

    It will produce the following output −

    This is a static method
    This is an instance method
    This is a static method
    PHP Fatal error:  Uncaught Error: Non-static method 
    myclass::myinstancemethod() cannot be called statically
    

    The “self” Keyword in Static Method

    If you need to call a static method from inside an instance method defined in the same class, you have to use self keyword referring to the name of the class, followed by the scope resolution operator (such as self::mystaticmethod)

    Open Compiler

    <?php
       class myclass {
       
    
      /* Member variables */
      static int $var1 = 0;
      public static function mystaticmethod() {
         echo "This is a static method".  PHP_EOL;
      }
      public function myinstancemethod() {
         echo "This is an instance method".  PHP_EOL;  
         echo "calling static method from instance method" . PHP_EOL;
         self::mystaticmethod();
      }
    } $obj = new myclass; $obj->myinstancemethod(); ?>

    It will produce the following output −

    This is an instance method
    calling static method from instance method
    This is a static method
    

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Using the “parent” Keyword

    In case of inheritance, a static method defined in a base class may be called by an object of derived class, or from inside an instance method of the derived class, by referring it with the “parent” keyword.

    Example

    Take a look at the following example −

    Open Compiler

    <?php
       class myclass {
       
    
      /* Member variables */
      static int $var1 = 0;
      public static function mystaticmethod() {
         echo "This is a static method".  PHP_EOL;
      }
      public function myinstancemethod() {
         echo "This is an instance method".  PHP_EOL;
         echo "calling static method from instance method" . PHP_EOL;
         self::mystaticmethod();
      }
    } class mynewclass extends myclass {
      public function myfunction() {
         echo "This an instance method of the derived class" . PHP_EOL;
         echo "Calling static method of the parent class" . PHP_EOL;
         parent::mystaticmethod();
      }
    } $obj = new mynewclass; mynewclass::mystaticmethod(); $obj->myfunction(); ?>

    It will produce the following output −

    This is a static method
    This an instance method of the derived class
    Calling static method of the parent class
    This is a static method
    

    Static Method Inside Another Class

    It is entirely possible to call the static method from one class in another. You have to qualify its name with its class name followed by the scope resolution operator.

    Example

    Take a look at the following example −

    Open Compiler

    <?php
       class myclass {
       
    
      /* Member variables */
      static int $var1 = 0;
      public static function mystaticmethod() {
         echo "This is a static method".  PHP_EOL;
      }
    } #this is not a derived class class mynewclass {
      public function myfunction() {
         echo "This an instance method" . PHP_EOL;
         echo "Calling static method of the another class" . PHP_EOL;
         myclass::mystaticmethod();
      }
    } $obj = new mynewclass; $obj->myfunction(); ?>

    It will produce the following output −

    This an instance method
    Calling static method of another class
    This is a static method
    

    Since $this pseudo-variable is not available for a static method, the instance variables of an object cannot be accessed inside a static method. It can process only the static properties of the class.

    Example

    Take a look at the following example −

    Open Compiler

    <?php
       class myclass {
       
    
      /* Member variables */
      static int $var1 = 0;
      function __construct() {
         self::$var1++;
         echo "object number ". self::$var1 . PHP_EOL;      
      }
      public static function mystaticmethod() {
         echo "Number of objects available: " . self::$var1 . PHP_EOL;
      }
    } for ($i=1; $i<=3; $i++) {
      $obj = new myclass;
    } myclass::mystaticmethod(); ?>

    It will produce the following output −

    object number 1
    object number 2
    object number 3
    Number of objects available: 3
    
  • Traits

    In PHP, a class can inherit only from one parent class, multiple inheritance is not defined in PHP. Traits in PHP have been introduced to overcome this limitation. You can define one or more method in a trait, which can be reused freely in various independent classes.

    Syntax

    The “trait” keyword is used as per the following syntax −

    traitmytrait{functionmethod1(){/*function body*/}functionmethod2(){/*function body*/}}

    To be able to call the methods in a trait, it needs to made available to another class with use keyword.

    Example

    A Trait is similar to a class, but only intended to group functionality in a fine-grained and consistent way. It is not possible to instantiate a Trait on its own.

    Open Compiler

    <?php
       trait mytrait {
    
      public function hello() {
         echo "Hello World from " . __TRAIT__ . "";
      }
    } class myclass {
      use mytrait;
    } $obj = new myclass(); $obj->hello(); ?>

    It will produce the following output −

    Hello World from mytrait
    

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Example

    A trait can be used in more than one classes. The following example has a mytrait with avg() function int it. It is used inside a marks class. The percent() method internally calls the avg() function from the trait.

    Take a look at the following example −

    Open Compiler

    <?php
       trait mytrait {
    
      function avg($x, $y) {
         return ($x+$y)/2;
      }
    } class marks {
      use mytrait;
      private int $m1, $m2;
      function __construct($x, $y) {
         $this-&gt;m1 = $x;
         $this-&gt;m2 = $y;
      }
      function percent():float {
         return $this-&gt;avg($this-&gt;m1, $this-&gt;m2);
      }
    } $obj = new marks(50, 60); echo "percentage: " . $obj->percent(); ?>

    It will produce the following output −

    percentage: 55
    

    Using Multiple Traits

    A class can use more than one traits. Here we have two traits with one function each performing addition and multiplication of two numbers. Both are used inside a third class.

    Open Compiler

    <?php
       trait addition {
    
      function add($x, $y) {
         return $x+$y;
      }
    } trait multiplication {
      function multiply($x, $y) {
         return $x*$y;
      }
    } class numbers {
      use addition, multiplication;
      private int $m1, $m2;
      function __construct($x, $y) {
         $this-&gt;m1 = $x;
         $this-&gt;m2 = $y;
      }
      function calculate():array {
         $arr = &#91;$this-&gt;add($this-&gt;m1, $this-&gt;m2), $this-&gt;multiply($this-&gt;m1, $this-&gt;m2)];
         return $arr;
      }
    } $obj = new numbers(50, 60); $res = $obj->calculate(); echo "Addition: " . $res[0] . PHP_EOL; echo "Multiplication: " . $res[1] . PHP_EOL; ?>

    It will produce the following output −

    Addition: 110
    Multiplication: 3000
    

    Overriding Trait Function

    When a class uses a certain trait, its function are available to it just as a child class inherits the parent methods. The trait function may also be overridden.

    Open Compiler

    <?php
       trait mytrait {
    
      public function sayHello() {
         echo 'Hello World!';
      }
    } class myclass {
      use mytrait;
      public function sayHello() {
         echo 'Hello PHP!';
      }
    } $o = new myclass(); $o->sayHello(); ?>

    It will produce the following output −

    Hello PHP!
    

    The “insteadof” Keyword

    Sometimes, more two traits might have same name of the function. Hence, using them in a class creates ambiguous situation. PHP provides insteadof keyword to tell the parser function from which trait you intend to use.

    Open Compiler

    <?php
       trait mytrait {
    
      public function sayHello() {
         echo 'Hello World!';
      }
    } trait newtrait {
      public function sayHello() {
         echo 'Hello PHP!';
      }
    } class myclass {
      use mytrait, newtrait{
         newtrait::sayHello insteadof mytrait;
      }
    } $o = new myclass(); $o->sayHello(); ?>

    It will produce the following output −

    Hello PHP!
    

    Aliasing a Trait Function

    If you want to be able to call functions from both traits even if they have function with same name, a workaround is to specify an alias name to one of them.

    Example

    In the following example, we will call sayHello() from mytrait as hello() −

    Open Compiler

    <?php
       trait mytrait {
    
      public function sayHello() {
         echo 'Hello World!' . PHP_EOL;
      }
    } trait newtrait {
      public function sayHello() {
         echo 'Hello PHP!' . PHP_EOL;
      }
    } class myclass {
      use mytrait, newtrait{
         mytrait::sayHello as hello;
         newtrait::sayHello insteadof mytrait;
      }
    } $o = new myclass(); $o->hello(); $o->sayHello(); ?>

    It will produce the following output −

    Hello World!
    Hello PHP!
    
  • Interfaces

    Just as a class is a template for its objects, an interface in PHP can be called as a template for classes. We know that when a class is instantiated, the properties and methods defined in a class are available to it. Similarly, an interface in PHP declares the methods along with their arguments and return value. These methods do not have any body, i.e., no functionality is defined in the interface.

    concrete class has to implement the methods in the interface. In other words, when a class implements an interface, it must provide the functionality for all methods in the interface.

    An interface is defined in the same way as a class is defined, except that the keyword “interface” is used in place of class.

    interfacemyinterface{publicfunctionmyfunction(int$arg1,int$arg2);publicfunctionmymethod(string$arg1,int$arg2);}

    Note that the methods inside the interface have not been provided with any functionality. Definitions of these methods must be provided by the class that implements this interface.

    When we define a child class, we use the keyword “extends“. In this case, the class that must use the keyword “implements“.

    All the methods declared in the interface must be defined, with the same number and type of arguments and return value.

    classmyclassimplementsmyinterface{publicfunctionmyfunction(int$arg1,int$arg2){## implementation of myfunction;}publicfunctionmymethod(string$arg1,int$arg2){# implementation of mymethod;}}

    Note that all the methods declared in an interface must be public.

    Example

    Let us define an interface called shape. A shape has a certain area. You have shapes of different geometrical appearance, such as rectangle, circle etc., each having an area, calculated with different formula. Hence the shape interface declares a method area() that returns a float value.

    interfaceshape{publicfunctionarea():float;}

    Next, we shall define a circle class that implements shape interface, to implement, the class must provide a concrete implementation of the functions in the interface. Here, the area() function in circle class calculates the area of a circle of a given radius.

    classcircleimplementsshape{var$radius;publicfunction__construct($arg1){$this->radius=$arg1;}publicfunctionarea():float{returnpow($this->radius,2)*pi();}}

    We can now declare an object of circle class, and call the area() method.

    $cir=newcircle(5);echo"Radius : ".$cir->radius." Area of Circle: ".$cir->area().PHP_EOL;

    An interface can be implemented by any number of classes (which may be unrelated to each other) provided the implementing class provides functionality of each method in the interface.

    Here is a Square class that implements shape. The area() method returns the square of the side property.

    classsquareimplementsshape{var$side;publicfunction__construct($arg1){$this->side=$arg1;}publicfunctionarea():float{returnpow($this->side,2);}}

    Similarly, create a Square object and call the area() method.

    Example

    Given below is the complete code for a shape interface, implemented by circle and Square classes −

    Open Compiler

    <?php
       interface shape {
    
      public function area(): float;
    } class square implements shape {
      var $side;
      public function __construct($arg1) {
         $this-&gt;side = $arg1; 
      }
      public function area(): float {
         return pow($this-&gt;side, 2);
      }
    } class circle implements shape {
      var $radius;
      public function __construct($arg1) {
         $this-&gt;radius = $arg1;
      }
      public function area(): float {
         return pow($this-&gt;radius,2)*pi();
      }
    } $sq = new square(5); echo "Side: " . $sq->side . " Area of Square: ". $sq->area() . PHP_EOL; $cir = new circle(5); echo "Radius: " . $cir->radius . " Area of Circle: " . $cir->area(). PHP_EOL; ?>

    It will produce the following output −

    Side: 5 Area of Square: 25
    Radius: 5 Area of Circle: 78.539816339745
    

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Multiple Inheritance in PHP

    PHP doesn’t have the provision to build a child class that extends two parent classes. In other words, the statement −

    classchildextendsparent1, parent2 
    

    is not accepted. However, PHP does support having a child class that extends one parent class, and implementing one or more interfaces.

    Let use look at the following example that shows a class that extends another and implements an interface.

    First, the parent class marks. It has three instance variables or properties $m1, $m2, $m3 representing the marks in three subjects. A constructor is provided to initialize the object.

    classmarks{protectedint$m1,$m2,$m3;publicfunction__construct($x,$y,$z){$this->m1=$x;$this->m2=$y;$this->m3=$z;}}

    We now provide an interface called percent that declares a method percent(), which should return a float but doesn’t have a function body.

    interfacepercent{publicfunctionpercent():float;}

    We now develop a class that extends marks class and provides implementation for percent() method in the interface.

    classstudentextendsmarksimplementspercent{publicfunctionpercent():float{return($this->m1+$this->m2+$this->m3)*100/300;}}

    The student class inherits the parent constructor, but provides implementation of parent() method that returns the percentage of marks.

    Example

    The complete code is as follows −

    Open Compiler

    <?php
       class marks {
    
      protected int $m1, $m2, $m3;
      public function __construct($x, $y, $z) {
         $this-&gt;m1 = $x;
         $this-&gt;m2 = $y;
         $this-&gt;m3 = $z;
      }
    } interface percent {
      public function percent(): float;
    } class student extends marks implements percent {
      public function percent(): float {
         return ($this-&gt;m1+$this-&gt;m2+$this-&gt;m3)*100/300;
      }
    } $s1 = new student(50, 60, 70); echo "Percentage of marks: ". $s1->percent() . PHP_EOL; ?>

    It will produce the following output −

    Percentage of marks: 60
    

    The interface in PHP defines a framework of methods that classes use to provide a different but concrete implementation of their own.

  • Abstract Classes

    The list of reserved words in PHP includes the “abstract” keyword. When a class is defined with the “abstract” keyword, it cannot be instantiated, i.e., you cannot declare a new object of such a class. An abstract class can be extended by another class.

    abstractclassmyclass{// class body}

    As mentioned above, you cannot declare an object of this class. Hence, the following statement −

    $obj=newmyclass;

    will result in an error message as shown below −

    PHP Fatal error:  Uncaught Error: Cannot instantiate abstract class myclass
    

    An abstract class may include properties, constants or methods. The class members may be of public, private or protected type. One or more methods in a class may also be defined as abstract.

    If any method in a class is abstract, the class itself must be an abstract class. In other words, a normal class cannot have an abstract method defined in it.

    This will raise an error −

    classmyclass{abstractfunctionmyabsmethod($arg1,$arg2);functionmymethod()#this is a normal method {echo"Hello";}}

    The error message will be shown as −

    PHP Fatal error:  Class myclass contains 1 abstract method 
    and must therefore be declared abstract
    

    You can use an abstract class as a parent and extend it with a child class. However, the child class must provide concrete implementation of each of the abstract methods in the parent class, otherwise an error will be encountered.

    Example

    In the following code, myclass is an abstract class with myabsmethod() as an abstract method. Its derived class is mynewclass, but it doesn’t have the implementation of the abstract method in its parent.

    Open Compiler

    <?php
       abstract class myclass {
    
      abstract function myabsmethod($arg1, $arg2);
      function mymethod() {
         echo "Hello";
      }
    } class newclass extends myclass {
      function newmethod() {
         echo "World";
      }
    } $m1 = new newclass; $m1->mymethod(); ?>

    The error message in such a situation is −

    PHP Fatal error:  Class newclass contains 1 abstract method and must 
    therefore be declared abstract or implement the remaining 
    methods (myclass::myabsmethod) 
    

    It indicates that newclass should either implement the abstract method or it should be declared as an abstract class.

    Example

    In the following PHP script, we have marks as an abstract class with percent() being an abstract method in it. Another student class extends the marks class and implements its percent() method.

    Open Compiler

    <?php
       abstract class marks {
    
      protected int $m1, $m2, $m3;
      abstract public function percent(): float;
    } class student extends marks {
      public function __construct($x, $y, $z) {
         $this-&gt;m1 = $x;
         $this-&gt;m2 = $y;
         $this-&gt;m3 = $z;
      }
      public function percent(): float {
         return ($this-&gt;m1+$this-&gt;m2+$this-&gt;m3)*100/300;
      }
    } $s1 = new student(50, 60, 70); echo "Percentage of marks: ". $s1->percent() . PHP_EOL; ?>

    It will produce the following output −

    Percentage of marks: 60
    

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Difference between Interface and Abstract Class in PHP

    The concept of abstract class in PHP is very similar to interface. However, there are a couple of differences between an interface and an abstract class.

    Abstract classInterface
    Use abstract keyword to define abstract classUse interface keyword to define interface
    Abstract class cannot be instantiatedInterface cannot be instantiated.
    Abstract class may have normal and abstract methodsInterface must declare the methods with arguments and return types only and not with any body.
    Abstract class is extended by child class which must implement all abstract methodsInterface must be implemented by another class, which must provide functionality of all methods in the interface.
    Can have public, private or protected propertiesProperties cannot be declared in interface
  • Class Constants

    PHP allows an identifier in a class to be defined as a “class constant” with a constant value, the one that remains unchanged on a per class basis. To differentiate from a variable or property within class, the name of the constant is not prefixed with the usual “$” symbol and is defined with the “const” qualifier. Note that a PHP program can also have a global constant created using the define() function.

    The default visibility of a constant is public, although other modifiers may be used in the definition. The value of a constant must be an expression and not a variable, nor a function call/property. The value of a constant is accessed through the class name using the scope resolution operator. Inside a method though, it can be referred to through self variable.

    classSomeClass{constCONSTANT='constant value';}echoSomeClass::CONSTANT;

    Constant names are case sensitive. Conventionally, the names of constants are in upper case.

    Example

    This example shows how a Class Constant is defined and accessed −

    Open Compiler

    <?php
       class square {
    
      const PI=M_PI;
      var $side=5;
      function area() {
         $area=$this-&gt;side**2*self::PI;
         return $area;
      }
    } $s1=new square(); echo "PI=". square::PI . "\n"; echo "area=" . $s1->area(); ?>

    It will produce the following output −

    PI=3.1415926535898
    area=78.539816339745
    

    Class Constant as Expression

    In this example, the class constant is assigned an expression −

    Open Compiler

    <?php
       const X = 22;
       const Y=7;
    
       class square {
    
      const PI=X/Y;
      var $side=5;
      function area() {
         $area=$this-&gt;side**2*self::PI;
         return $area;
      }
    } $s1=new square(); echo "PI=". square::PI . "\n"; echo "area=" . $s1->area(); ?>

    It will produce the following output −

    PI=3.1428571428571
    area=78.571428571429
    

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Class Constant Visibility Modifiers

    Take a look at the following example −

    <?php
       class example {
    
      const X=10;
      private const Y=20;
    } $s1=new example(); echo "public=". example::X. "\n"; echo "private=" . $s1->Y ."\n"; echo "private=" . example::Y ."\n"; ?>

    It will produce the following output −

    public=10
    PHP Notice:  Undefined property: example::$Y in  line 11
    
    private=
    PHP Fatal error:  Uncaught Error: Cannot access private const example::Y
    
  • Inheritance

    Inheritance is one of the fundamental principles of object-oriented programming methodology. Inheritance is a software modelling approach that enables extending the capability of an existing class to build new class instead of building from scratch.

    PHP provides all the functionality to implement inheritance in its object model. Incorporating inheritance in PHP software development results in code reuse, remove redundant code duplication and logical organization.

    Imagine that you need to design a new class whose most of the functionality already well defined in an existing class. Inheritance lets you to extend the existing class, add or remove its features and develop a new class. In fact, PHP has the “extends” keyword to establish inheritance relationship between existing and new classes.

    classnewclassextendsoldclass{......}

    Inheritance comes into picture when a new class (henceforth will be called inherited class, sub class, child class, etc.) possesses “IS A” relationship with an existing class (which will be called base class, super class, parent class, etc.).

    PHP Inheritence

    In PHP, when a new class is defined by extending another class, the subclass inherits the public and protected methods, properties and constants from the parent class. You are free to override the functionality of an inherited method, otherwise it will retain its functionality as defined in the parent class.

    Example

    Take a look at the following example −

    Open Compiler

    <?php
       class myclass {
    
      public function hello() {
         echo "Hello from the parent class" . PHP_EOL;      
      }
      public  function thanks() {
         echo "Thank you from parent class" . PHP_EOL;
      }
    } class newclass extends myclass {
      public function thanks() {
         echo "Thank you from the child class" . PHP_EOL;
      }
    } # object of parent class $obj1 = new myclass; $obj1->hello(); $obj1->thanks(); # object of child class $obj2 = new newclass; $obj2->hello(); $obj2->thanks(); ?>

    It will produce the following output −

    Hello from the parent class
    Thank you from parent class
    Hello from the parent class
    Thank you from the child class
    

    As mentioned before, the child class inherits public and protected members (properties and methods) of the parent. The child class may introduce additional properties or methods.

    In the following example, we use the Book class as the parent class. Here, we create an ebook class that extends the Book class. The new class has an additional property – format (indicating ebook’s file format – EPUB, PDF, MOBI etc). The ebook class defines two new methods to initialize and output the ebbok data – getebook() and dispebook() respectively.

    Example

    The complete code of inheritance example is given below −

    Open Compiler

    <?php
       class Book {
       
    
      /* Member variables */
      protected int $price;
      protected string $title;
      public function getbook(string $param1, int $param2) {
         $this-&gt;title = $param1;
         $this-&gt;price = $param2;
      }
      public function dispbook() {
         echo "Title: $this-&gt;title Price: $this-&gt;price \n";
      }
    } class ebook extends Book {
      private string $format;
      public function getebook(string $param1, int $param2, string $param3) {
         $this-&gt;title = $param1;
         $this-&gt;price = $param2;
         $this-&gt;format = $param3;
      }
      public function dispebook() {
         echo "Title: $this-&gt;title Price: $this-&gt;price\n";
         echo "Format: $this-&gt;format \n";
      }
    } $eb = new ebook; $eb->getebook("PHP Fundamentals", 450, "EPUB"); $eb->dispebook(); ?>

    The browser output is as shown below −

    Title: PHP Fundamentals Price: 450
    Format: EPUB
    

    If you take a closer look at the getebook() function, the first two assignment statements are in fact there getbook() function, which the ebook class has inherited. Hence, we can call it with parent keyword and scope resolution operator.

    Change the getebook() function code with the following −

    publicfunctiongetebook(string$param1,int$param2,string$param3){parent::getbook($param1,$param2);$this->format=$param3;}

    Similarly, the first echo statement in dispebook() function is replaced by a call to the dispbook() function in parent class −

    publicfunctiondispebook(){parent::dispbook();echo"Format: $this->format<br/>";}

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Constructor in Inheritance

    The constructor in the parent class constructor is inherited by the child class but it cannot be directly called in the child class if the child class defines a constructor.

    In order to run a parent constructor, a call to parent::__construct() within the child constructor is required.

    Example

    Take a look at the following example −

    Open Compiler

    <?php
       class myclass{
    
      public function __construct(){
         echo "This is parent constructor". PHP_EOL;
      }
    } class newclass extends myclass {
      public function __construct(){
         parent::__construct();
         echo "This is child class destructor" . PHP_EOL;
      }
    } $obj = new newclass(); ?>

    It will produce the following output −

    This is parent constructor
    This is child class destructor
    

    However, if the child does not have a constructor, then it may be inherited from the parent class just like a normal class method (if it was not declared as private).

    Example

    Take a look at the following example −

    Open Compiler

    <?php
       class myclass{
    
      public function __construct(){
         echo "This is parent constructor". PHP_EOL;
      }
    } class newclass extends myclass{ } $obj = new newclass(); ?>

    It will produce the following output −

    This is parent constructor
    

    PHP doesn’t allow developing a class by extending more than one parents. You can have hierarchical inheritance, wherein class B extends class A, class C extends class B, and so on. But PHP doesn’t support multiple inheritance where class C tries to extend both class A and class B. We can however extend one class and implement one or more interfaces. We shall learn about interfaces in one of the subsequent chapters.