Object-Oriented PHP and reusing code

Declaring a Class

We define a class with the class keyword. Class definitions contain the class name (which is case-sensitive), its properties, and its methods.

PHP

<?php
class User
{
  public $Name;
  public $Age;
  public $Password;
  public $Email;
  public $Country;
  public $City;
  public $Phone;
  public $Address;
function Print_Name()
{
    return $this->Name;
}
}
?>

Result

It will create a class named User.

Creating an Object

To create an object with a specified class, use the new keyword.

PHP

<?php
$A_User = new User;
$A_User->Name = "Karim";
$A_User->Age = 25;
echo "<h1>" . $A_User->Print_Name() . " is " . $A_User->Age . " years old.</h1>";
?>

Result

Karim is 25 years old.

Constructors

A constructor is declared in the same way as other operations, but has the special name __construct(). (that is, construct preceded by two underscore characters).

PHP

<?php
$A_User = new User("Amel");
class User
{
function __construct($param)
{
$this->Name = $param;
echo "<h1>User " . $this->Print_Name() . " is created.</h1>";
}
}
?>

Result

User Amel is created.

Destructors

The opposite of a constructor is a destructor. They are called when an object is destroyed.
Similar to the way constructors are named, the destructor for a class must be named __destruct().
Destructors cannot take parameters.
The __destruct() function that is automatically called at the end of the script.

PHP

<?php
class User
{
function __destruct()
{
echo "<h1>The User: " . $this->Print_Name() . " has been terminated.</h1>";
}
}
?>

Result

The User: Amel has been terminated.

Writing Methods

Declaring a method is similar to declaring a function.
Method names beginning with a double underscore (__) are reserved.
The syntax for accessing an object's property is $object->property. Likewise, you call a method like this: $object->method().
Properties and methods do not have $ signs in front of them.
A special variable called $this, which can be used to access the current object's properties.

PHP

<?php
$A_User->Change_Name("Karim");
$A_User = new User("Amine");
class User
{
function Change_Name($param)
{
echo "<h1>The User: " . $this->Print_Name() . " has changed his name to ";
$this->Name = $param;
echo $this->Print_Name() . "</h1>";
}
}
?>

Result

The User: Amine has changed his name to Karim

Declaring Properties

It is not necessary to explicitly declare properties within classes, as they can be implicitly defined when first used.
You can place functions and class definitions anywhere in your code, before or after statements that use them. Generally, though, it is considered good practice to place them toward the end of a file.

PHP

<?php
$A_User = new User();
$A_User->name = "Karim";
echo $A_User->name;
class User
{
// Class definition
}
?>

Result

Property and Method Scope

PHP provides three keywords for controlling the scope of properties and methods (members):
  • public: Public members can be referenced anywhere, including by other classes and instances of the object. Methods and properties are assumed to be public by default.
  • protected: These members can be referenced only by the object's class methods and those of any subclasses. The protected access modifier means that the marked item can be accessed only from inside the class. It also exists in any subclasses.
  • private: These members can be referenced only by methods within the same class—not by subclasses.

Writing Accessor Functions

One of the advantages of an object-oriented approach is that it encourages encapsulation. You can enforce this with the use of __get and __set functions.
Note that __get() takes one parameter—the name of an attribute—and returns the value of that attribute. Similarly, the __set() function takes two parameters: the name of an attribute and the value you want to set it to.
You do not directly call these functions. The double underscore in front of the name shows that these functions have a special meaning in PHP, just like the __construct() and __destruct() functions.
These functions will not be used, even if declared, when accessing attributes declared to be public.
$A_User->Age = 25;
this statement implicitly calls the __set() function with the value of $Parameter_Name set to "Age", and the value of $value set to 25. You need to write the __set() function to do any error checking you require.
The __get() function works in a similar way. If, in your code, you reference
$A_User->Age;
this expression implicitly calls the __get() function with the parameter $Parameter_Name set to "Age" It is up to you to write the __get() function to return the value.

PHP

<?php
$A_User = new User();
$A_User->Name = "Kamel";
$A_User->Age = 25;
echo "<h1>" . $A_User->Name . "</h1><br>";
echo "<h1>" . $A_User->Age . "</h1>";
class User
{
private $Name;
private $Age;
function __get($Parameter_Name)
{
return "The value of $Parameter_Name is " . $this->$Parameter_Name;
}
function __set($Parameter_Name, $Its_value)
{
if ($Parameter_Name == "Age" && $Its_value < 18)
{ throw new Exception("Age must be greater than 18"); }
$this->$Parameter_Name = $Its_value;
}
}
?>

Result

The value of Name is Kamel


The value of Age is 25

Static Methods

You can define a method as static, which means that it is called on a class, not on an object. A static method has no access to any object properties.
Note how we call the class itself, along with the static method, using a double colon (also known as the scope resolution operator), not ->.
If you try to access $this->property, or other object properties from within a static function, you will receive an error message.

PHP

<?php

?>

Result

Static Properties

declaring members of a class static makes them accessible without an instantiation of the class. A property declared static cannot be directly accessed within an instance of a class, but a static method can.

PHP

<?php

?>

Result

Inheritance

We implement inheritance using the extends keyword.
If an attribute or method is specified as private, it will not be inherited. If an attribute or method is specified as protected, it will not be visible outside the class (much like a private element) but will be inherited.

PHP

<?php
$A_Customer = new Customer();
echo $A_Customer->Child_func();
class User
{
public function func_1()
{
echo "This is function 1";
}
protected function func_2()
{
echo "This is function 2";
}
private function func_3()
{
echo "This is function 3";
}
}
class Customer extends User
{
function Child_func()
{
$this->func_1();
echo "<br>";
$this->func_2();
echo "<br>";
$this->func_3();
}
}
?>

Result

This is function 1
This is function 2
Fatal error: Uncaught Error: Call to private method User::func_3() from scope Customer in....

Overriding

Overriding is to redeclare the same attributes and operations. To give an attribute in the subclass a different default value to the same attribute in its superclass or to give an operation in the subclass different functionality to the same operation in its superclass. This action is called overriding.
Declaring B does not affect the original definition of A.
A subclass will inherit all the attributes and operations of its superclass, unless you provide replacements. If you provide a replacement definition, it takes precedence and overrides the original definition.

PHP

<?php
$A_Customer = new Customer;
echo $A_Customer->Parameter . "<br>";
echo $A_Customer->func_1();
$A_user = new User;
echo $A_user->Parameter . "<br>";
echo $A_user->func_1();
class User
{
public $Parameter = "This is the parent parameter";
function func_1()
{
echo "This is the parent function";
}
}
class Customer extends User
{
public $Parameter = "This is the child parameter";
function func_1()
{
echo "This is the child function";
}
}
?>

Result

This is the child parameter
This is the child function
This is the parent parameter
This is the parent function

The parent keyword

The parent keyword allows you to call the original version of the operation in the parent class.
Although you call the operation from the parent class, PHP uses the attribute values from the current class.

PHP

<?php
$A_Customer = new Customer;
echo $A_Customer->func_1() . "<br>";
class User
{
public $Parameter = "This is the parent parameter";
function func_1()
{
echo "Parent class: " . $this->Parameter;
}
}
class Customer extends User
{
public $Parameter = "This is the child parameter";
function func_1()
{
parent::func_1();
}
}
?>

Result

Parent class: This is the child parameter

Final methods

When you wish to prevent a subclass from overriding a superclass method, you can use the final keyword.
When you use the keyword final in front of a function declaration, that function cannot be overridden in any subclasses.
You can also use the final keyword to prevent a class from being subclassed at all. For instance, final class User{...}. If you then try to inherit from A, you will get an error.

PHP

<?php
$A_Customer = new Customer;
echo $A_Customer->func_1() . "<br>";
class User
{
public $Parameter = "This is the parent parameter";
final function func_1()
{
echo "Parent class: " . $this->Parameter;
}
}
class Customer extends User
{
public $Parameter = "This is the child parameter";
function func_1()
{
echo "Child class: " . $this->Parameter;
}
}
?>

Result

Fatal error: Cannot override final method User::func_1() in .....

Multiple inheritance using Traits

PHP does not support true multiple inheritance. This means that each class can inherit from only one parent.
However, you can use traits to simulate multiple inheritance.
A class can combine multiple traits, and traits can inherit from one another.
You create a trait the same way as a class, but using the keyword trait instead.
The sub-class could override the method by declaring its own, if needed. However, you should note that if the class had inherited a method from a parent, by default the trait method would override it. That is, a trait's methods override inherited methods, but the current's class methods override a trait's methods.
You can combine multiple traits and when there are methods with the same names, you can explicitly specify which trait's functionality you wish to use.
Because each of the traits implements the same method, we must specify which one to use. If you don't specify this, PHP will generate a fatal error as it will not be able to resolve the conflict.
You can specify which one to use by using the insteadof keyword or by using the as keyword to give the method a new name.

PHP

<?php
trait Trait_1
{
function func_1() { echo "Trait_1 <br>"; }
}
trait Trait_2
{
function func_1() { echo "Trait_2 <br>"; }
}
class Customer
{
use Trait_1, Trait_2 {
Trait_1::func_1 insteadof Trait_2;
Trait_2::func_1 as func_2;
}
function Customer_func() {
$this->func_1();
$this->func_2();
}
}
$A_Customer = new Customer();
$A_Customer->Customer_func();
?>

Result

Trait_1
Trait_2

Including and Requiring Files

  • The include Statement:
    Using include, you can tell PHP to fetch a particular file and load all its contents. It's as if you pasted the included file into the current file at the insertion point.
  • Using include_once:
    Each time you issue the include directive, it includes the requested file again, even if you have already inserted it. Use include_once instead of include. Then, any further attempts to include the same file (with include or include_once) will be ignored. To determine whether the requested file has already been executed, the absolute filepath is matched after all relative paths are resolved (to their absolute paths) and the file is found in your include path.
  • Using require and require_once:
    A potential problem with include and include_once is that PHP will only attempt to include the requested file. Program execution continues even if the file is not found. When it is absolutely essential to include a file, require it.

PHP

<?php
include "the_other_file.php";
include_once "another_file.php";
require "the_other_file.php";
require_once "another_file.php";
?>

Result