oops introduction


Object Oriented Programming (OOP) is a type of programming language in PHP that facilitates a developer in creating complex and reusable web applications. Before working on OOPs, we need to know a few things that are explained below.

CLASS AND OBJECTS

Class is a user defined data type that can hold variables also known as properties or attributes, constants as well as methods. Variables can be defined as public scope or var scope while constants are defined as const scope. If a scope is not defined for the methods they are assumed as of public scope. We can create any number of objects in order to point to that class. An object is a keyword to hold the variables or methods defined in a class.

<?php
class Mobile{

	// define variable with some value
	var $qty = 20;

	// define variable with null value
	public $price;

	// define method
	function totalSales($x,$y){
		return ($x * $y);
	}
}	

// create an object to hold all the variables and methods from the class Mobile using pointer
$obj = new Mobile;

// calling the method printing the result
echo $obj->totalSales(10,7000);

// printing one of the variables defined in the class
echo $obj->qty;

// passing defined variable value 
echo $obj->totalSales($obj->qty,5000);

$this

Now, we knew that we need to create an object to use the variables but what if you need to use those variables inside the class. The method we learned works fine but there's another method to use such variables in OOPs and that is the use of $this which says the object of the class being used.

Method We Learned Earlier

class DollarThis{

	public $x,$y;

	function sum(){
		$a= new DollarThis;
		return ($a->x + $a->y);
	}
}	

Use of $this

class DollarThis{

	public $x,$y;

	function sum(){		
		return ($this->x + $this->y);
	}
}	

Static properties

If all the properties of a class are defined as static then it's not necessary to create an object to use them outside the class although that would also work fine. Instead we can use scope resolution operator :: after the class name to call those properties.

class StaticTest{

	public static $a = 10;
	static public $b = 20;

	static function sum($x,$y){
		return($x + $y);
	}
}	

echo StaticTest::sum(10,20);

Constant

Lets see how we can define a constant in OOPs. In this example, we're also defining default value of a variable as 0.

class ConstantData{
	
	const PI = 3.14;
	
	function areaOfCircle($r=0){
		return(self::PI*(pow($r,2));
	}
}	

$obj = new ConstantData;
$obj->areaOfCircle(7);

ENCAPSULATION

Encapsulation is the method of protecting properties of a class from being used outside of the class. Public methods can be used outside the class creating an object but if a method is defined as private or protected then that method can't be used outside of the class.

class SimpleInterest{
	
	public $p,$t,$r;

	function takeValue($x,$y,$z){
		$this->p = $x;
		$this->t = $y;
		$this->r = $z;
		return $this->calculate();
	}

	function calculate(){
		return ($this->p * $this->t * $this->r) / 100;
	}
}	

$obj = new SimpleInterest;
echo $obj->takeValue(2000,3,7);

// another method 
$obj->p = 2000;
$obj->t = 3;
$obj->r = 7;
$obj->calculate();

In this class SimpleInterest, we want to perform the operation by using the method takevalue() and that's being done but you can see that the method calculate() can also be used to perform the operation by defining the values for all required variables as all those are public properties. To prevent that method from being accessible outside the class we can define them as private or protected function as shown below.

class SimpleInterest{
	
	private public $p,$t,$r;

	function takeValue($x,$y,$z){
		$this->p = $x;
		$this->t = $y;
		$this->r = $z;
		return $this->calculate();
	}

	private function calculate(){
		return ($this->p * $this->t * $this->r) / 100;
	}
}	

$obj = new SimpleInterest;
echo $obj->takeValue(2000,3,7);

Now, if you try to use those private methods outside the class then php will throw error exceptions.

INHERITANCE

The properties of the parent class can be accessed by their child class which is called inheritance in php. The child class can inherit the parent method and give own method implementation too. All the public and protected properties or methods of a parent class can be used by the child class while private properties can't be used outside of the class where it's defined.

class ParentClass{

	public $a = 20;
	public $b = 30;
	protected $c = 40;
	private $d = 50;

	protected function hello{
		return 'Hello World';
	}
}	

class ChildClass extends ParentClass{

	public function sum(){
		return ($this->a + $this->b + $this->c);
	}

	public function callHello(){
		return $this->hello();
	}
}

$obj = new ChildClass;
echo $obj->sum();
echo $obj->callHello();

'extends' key creates a parent-child relationship between two classes where the properties of parent class can be used by the child class. public properties can be used directly while protected properties or methods can be used in methods of child class.

OVERRIDING

The child class can inherit the parent method and give own method implementation which is known as overriding in php.

class ParentClass{
	public function calculate($x,$y){
		return ($x + $y);
	}		
}	

class ChildClass extends parentClass{
	public function calculate($x,$y){
		return ($x - $y);
	}
}
$obj = new ChildClass;
$obj->calculate();

In cases where both parent and child class have identical method names, the method of parent class is nullified and that of the child class comes to existence. That's what we call overriding in OOPs. We ccan still use the method from parent class along with the child class as shown below.

class ParentClass{
	public function calculate($x,$y){
		return ($x + $y);
	}		
}	

class ChildClass extends parentClass{
	public function calculate($x,$y){
		parent::calculate();
		return ($x - $y);
	}
}
$obj = new ChildClass;
$obj->calculate();	

LATE STATIC BINDING

Late static binding allows us to use the static method of child class in it's parent class.

class ParentClass{
	public static function lateBinds(){
		static::print();
	}		
}	

class ChildClass extends parentClass{
	public static function print(){
		echo 'HELLO WORLD';
	}
}

ChildClass::lateBinds();		

ABSTRACT CLASS

Abstract classes are those classes which can't be instantiated or whose object can't be created. The methods and properties defined inside it can only be ued ny its child class. Abstract methods too can't have body and must be overriddern in child class. Abstract methods can only be declared in abstract classes only.

abstract class AbstractClass{
	abstract public function test();
} 

class childClass extends AbstractClass{
	public function test(){
		echo 'Hello World';
	}	
}

INTERFACE

Interface are holders that contain constants and methods and can only be used by classes using a key named implements followed by the interface names. Methods defined in interfaces work similar to abstract methods.

interface A{
	const PI = 3.14;
}	

interface B{
	const DB = mydb;
	public function interFace();
}

class myClass implements A,B{
	public function interFace(){
		echo A::PI;
		echo B::DB;
	}
}

$obj = new myClass;
$obj->interFace();

METHOD CHAINING

Method chaining is a syntax that handles multiple method calls in OOPs. Each method needs to return object that allows multiple method calls to be chained in a single statement as shown below.

class Chain{
	
	private $arr = [];

	public function setA($a){
		$this->arr[] = $a;
		return $this;
	}

	public function setB($a){
		$this->arr[] = $a;
		return $this;
	}

	public function setC($a){
		$this->arr[] = $a;
		return $this;
	}
}	

$obj = new Chain;
$obj->setA(10)->setB(20)->setC(30);

Method chaining can be highly useful in preparing SQL statements in OOPs depending upon situations as shown below.

class SqlStatement{

	// declaring no query
	private $_query = null;
	
	// setting query
	public function setQuery($query){
		$this->_query = $query;
		return $this;
	}

	// adding where clause if there's query
	public function where($field,$operator,$value){
		if(empty($this->_query)) return false;
		$this->_query .= 'WHERE '.$field.' '.$operator.' '.$value.';
	}

	// function to get query
	public function getQuery(){
		return $this->_query;
	}
}	

$obj = new SqlStatement;
$obj->setQuery('SELECT * FROM table')->where('id','=',1);

echo $obj->getQuery();

Magic Method

Magic methods are identified by __ prefix and are automatically called when certain conditions are met.

class MagicMethod{
	
	public function __construct(){
		echo 'Construtor Running';
	}

	public function __destruct(){
		echo 'Destruct Function Called';
	}

	public function __get($value){
		echo $value .'not defined';
	}

	public function __set($name,$value){
		$this->$name = $value;
	}

	public function __call($name,$arguments){
		echo $name;
		print_r($arguments); // as the arguments will be in array
	}
}	

$obj = new MagicMethod;
echo $obj->data; // invokes __get()
$obj->a = 20;
echo $obj->a; // will return the value set by the line $obj->a = 20;
$obj->calltest(); // invokes __call();

__construct() gets initiated automatically.

__destruct() is the last method to be called from the class after executing all other methods.

__get() runs when an undefined variable is called in the script where the variable is replaced by undefined variable.

__set() gets invoked when a value is tried to be set on undefined variable.

__call() gets invoked when a method that doesn't exist is called.

TYPEHINTING

Typehinting is supported in PHP 7 only. It allows us to define the data type to be accepted in methods.

class TypeHinting{
	public function sum($a,$b){
		return ($a + $b);
	}	 
}	
$obj = new TypeHinting;
echo $obj->sum(1,2); // returns 3
echo $obj->sum('apple','ball'); returns 0 as when string is converted to integer the value will be 0

In PHP 7

class TypeHinting{
	public function sum(int $a, int $b){
		return ($a + $b);
	}	 
}	
$obj = new TypeHinting;
echo $obj->sum(1,2); // returns 3
echo $obj->sum('apple','ball'); displays as error and asks to enter integer

AUTOLOAD

Autoload allows us to keep our php files clean by keeping a series of functions in it and prevent any file from adding include or require function multiple times. The autoload class must get registered first using spl_autoload_register($methodName) to be funtional.

function autoload($className){
	$path = $className.'.php';
	require_once($path);
}	

spl_autoload_register('autoload');

new Validation();
new DataBase();

Here, the autoload function is invoked eachtime a class is tried to instantiate. It searches for the file as defined in $path and includes that file in the current file. This way, including multiple class files in a file where it's needed is made much convenient.

TRAITS

Traits are similar to classes that helps us to make the methods from classes more organized. In the example below, we've a file with class User that deals with all the operations related to the user. While working on an application, huge number of methods might need to be created and the file might look clumsy, unorganized and unreadable but if we separated those methods using one or multiple traits, we can keep it more organized. Here, all the authentication methods will be placed in trait named Authenticateuser while the database operations will be placed in the main class. The only thing we need to do to use those methods from traits is to add a command use traitName inside the class. Then, all those methods can be called from the object created with reference to the class.

trait AuhenticateUser{
	// all authentication methods
}	

class User{
	use AuthenticateUser;
	// all database operation methods
}
$objUser = new User;
$obj->methodFromTrait();

NAMESPACE

Namespace is another way of encapsulation of classes. Namespaces are designed to avoid conflict between classnames or constants or functions. It is also used to group related classes, interfaces, functions and constants. It's added on top of the class files.

namespace Directory\Subdirectory\Filename;	
class User{
	
}	

After adding namespaces, the instantiation of classes in other files just by creating an object won't be possible. Instead, you need to add a command line use Directory\Subdirectory\Filename\Classname;

use Directory\Subdirectory\Filename\Classname;

new User();	

EXCEPTION HANDLING

While working on php, we come across a lot of errors. Rather than displaying such errors in production environment, we can define our own error message and display it instead of those php error messages irrevalent to users.

function exceptionHandling($a,$b){
	if( $b == 0 ){
		throw new Exception('Division by zero');
	}
	return ($a / $b);
}
try{
	echo exceptionHandling(10,10);
}catch(Exception $e){
	echo $e->getMessage();	
}

We'll try to execute the method from try block. If the method gets executed successfully, there won't be any errors but in another case, catch() will hold the error message we defined and display it to the user.