1Fabio
Author: - Post Category: PHP, Resources - Date:October 8, 2019

Object Oriented PHP – Crash Course

A beginners guide

Make sure to check out my services.. As developers we must keep our skills updated and refresh our knowledge from time to time, no matter what. During my journey as Full stack developer I have collected resources, taken notes of courses and guides. There is one of my resource that today I want to share.

PHP Object Oriented Crash Course Image

Make sure to check out my services..


As developers we must keep our skills updated and refresh our knowledge from time to time, no matter what. During my journey as Full stack developer I have collected resources, taken notes of courses and guides. There is one of my resource that today I want to share. I made it in form of guide for those interested in learning more about the OOP (object oriented programming ) and for me as handy reference. Welcome to my crash course about Object Oriented Programming in PHP.

 

I will cover the fundamentals of OOP, I will try to use real word examples, no foo bar or value1, value 2 etc. as I realised that they don’t often make much sense to beginners.

I will start by covering how to use DocBlocks to document our code, declare a class using the class keyword, declare and access properties including those private and protected, how to use the __constructor() method, how to instantiate an object using the new keyword, class methods, sub-classes, and some extras including magic methods.

This guide is still incomplete, I will complete it as soon as possible and follow up with a video version of this article.

 
 
[Video Coming soon]
 
 

Course Topics:

  1. Define our Project structure
  2. Using the Doc Blocks
  3. Define a class using the class keyword
  4. Define properties: public, protected, private
  5. The Class Constructor
  6. Class Methods
  7. Sub-classes
  8. Properties & Visibility
  9. Methods & Visibility
  10. Output our Classes to the browser (Coming soon)
  11. Extras (Coming soon)

1. Define our project Structure

 
Let’s start by defining a bit of structure for our example project.
  1. We create a new folder that we call oop-crash-course
  2. create an index.php file inside our project root
  3. create two folders Classes and Views
  4. create a class.product.php inside the Classess folder
  5. create a index.view.php file inside the views folder.

Using VisualStudio Code lets open the integrated terminal and type the following commands to create our project structure

mkdir oop-crash-course && cd oop-crash-course
touch index.php
mkdir Classes && mkdir Views
cd Classes && touch class.product.php && cd ..
cd Views && touch index.view.php && cd ..
 
Now this is what we should have
 
| oop-crash-course
    | Classes
        class.product.php
    |Views
        index.view.php
    index.php

Now we need to do two more things:

  1. Open our index.php file and import at the top our Product class using the require statement
  2. include our view file at the bottom using the include statement.

Inside the index.php file:

require "./classes/class.product.php";
//our code goes here.
include "./views/index.view.php";

2. Using the DocBlocks

DocBlocks are used by programmers to document their code, and make it easy to understand by other developers. Doc blocks are
interpreted by text editors like VSCode, Sublime, Atom etc, and they provide a set of information about each bit of code.
A DocBlock is defined using the following syntax
/** */

Inside that we place a set of instruction holding specific information about each code bit we write under them. The following are the annotations that we will use during this tutorial:

  • @author is used to specify the author of the current element (can be a class, file, method or any bit of code);
  • @copyright Year and name of the copyright holder ie. 2019 Fabio Pacifici;
  • @license This links to the license for the current element ie. https://example.com/my-license License name;
  • @var holds the type and description of a variable or class property. ie ( type element description)
  • @param holds type and description of a parameter of a function or method. ie. (type $element_name description)
  • @return holds the type and description of the return value of a function or method. (type return element description )

3. Declare a Class using the class keyword

A class is a blue print that is used to create multiple objects with similar characteristics.
A class is like a 2D draw that a bicycle manufacturer uses to build many bicycle of the same model. Inside a class we can declare properties and methods(functions) that each object has access to. In the same way a bicycle has a frame, a seat, two wheels, an handlebar and so on a class has multiple properties and methods.
 
To create a class we use the “class” keyword followed by the name of the class starting with a capital letter, if a class has multiple words they should be capitalised like so:  ThisIsMyClass.
 
A DocBlock is required as it provides reference and instruction for us and other developers about how to read and use our code. It’s useful to familiarize with it right from the beginning.
Let’s define our first class inside our Class/class.product.php file, remember to add the PHP opening tag at the top of the file like so:
<?php
/**
* Product Class
* @author Fabio P
* @copyright 2019 Fabio P
*
*/
class Product {
// class properties and methods here
}
The DocBlock above our class defines some information about the class, like it’s name, the author and the copyright.
Once our class is declared we can open our index.php file and instanciate our new object using our product class and the “new” keyword. It’s a good practice to store the class in a variable.
 
Inside the index.php file:
// Our code goes here
$eDesk = new Product();
 
The above creates an empty object and store it inside the $desk variable so we can use it later. Using the var_dump() php function we can see the output produced by our code when we parse the index.php file.
// Our code goes here
$eDesk = new Product();
var_dump($eDesk);
We can parse our index.php file by typing in the terminal the following

php -f index.php

 The expected output is
 
object(Product)#5 (0) {
}
 
 

4. Define properties: public, protected, private

  • Public properties are accessible from anywhere, either inside or outside our class definition. They are declared using the “public” keyword
  • Protected properties are only accessible within our class or sub-classes. They are defined using the “protected” keyword.
  • Private properties are  only accessible within our class. Declared using the “private” keyword.

 Public Properties:

Inside our class definition we declare tree properties and include a DocBlock at the top to describe them.
 
<?php
/**
* Product Class
* @author Fabio P
* @copyright 2019 Fabio P
*
*/
class Product
{
/**
* Class Variables
* @var string name The product name
* @var string description The product description
* @var float price The product price
*/
public $name = "Eco Desk"; // <- this is a public property
public $description = " Ergonomic desk for developers";
public $price = 120;
}
If we execute the index.php file again  we will see the following output this time with the data we declared
        object(Product)#5 (3) {
["name"]=>
string(8) "Eco Desk"
["description"]=>
string(30) " Ergonomic desk for developers"
["price"]=>
int(120)
}
 
 Because our properties are public properties, defined using the “public” keyword, we can access their content using the following syntax
 
var_dump($eDesk->name);
var_dump($eDesk->description);
var_dump($eDesk->price);

When we var_dump() them now the output will be the following

string(8) "Eco Desk"
string(30) " Ergonomic desk for developers"
int(120)
Setting the any of the class proterties (name, description and price) to “private” or  “protected” will trow an error if accessed in the same way.
PHP Fatal error:  Uncaught Error: Cannot access protected property Product::$name
PHP Fatal error:  Uncaught Error: Cannot access private property Product::$name
We will cover that later.
 
Our class isn’t much useful as it is at moment. We need magic method called contruct to see its real powers.

The class Construct Method

A constructor is a special function that is run every time our class is instantiated. It’s helpful to define properties for our class that we want to define when a new object is instantiated.
The DocBlock here uses the @param annotation that provides instructions every time a new object is instantiated using our class.
A class with a construct method looks like the following:
 
inside our Classes/class.product.php file
<?php
/**
* Product Class
* @author Fabio P
* @copyright 2019 Fabio P
* */
class Product
{
/**
* Class Variables
* @var string name The product name
* @var string description The product description
* @var float price The product price
*/
public $name;
public $description;
public $price;
/**
* Class Constructor
* @param string $name The product name
* @param string $description The product description
* @param float $price The product price
*/
public function __construct($name, $description, $price)
{
$this->name = $name;
$this->description = $description;
$this->price = $price;
}
}
 
We can now use the magic of constructor to define multiple objects using our class and assign to each object a different set of properties.
 
inside our index.php file:
// Our code goes here
$eDesk = new Product("Ergo desk", "comfortable desk for developers", 120);
$eDesk2 = new Product("Simple desk", "comfortable desk for students", 50);
$eDesk3 = new Product("Office desk", "comfortable desk for managers", 80);
var_dump($eDesk);
var_dump($eDesk2);
var_dump($eDesk3);
 
The code above will output the following when we execute our index.php file.
 
        object(Product)#5 (3) {
["name"]=>
string(9) "Ergo desk"
["description"]=>
string(31) "comfortable desk for developers"
["price"]=>
int(120)
}
object(Product)#6 (3) {
["name"]=>
string(11) "Simple desk"
["description"]=>
string(29) "comfortable desk for students"
["price"]=>
int(50)
}
object(Product)#7 (3) {
["name"]=>
string(11) "Office desk"
["description"]=>
string(29) "comfortable desk for managers"
["price"]=>
int(80)
}
 

 Assign a default value to a parameter

We can assign a default value to our class parameters by simply assigning a value to the parameter inside our the class constructor. This allows us to instantiate a new object and omit that parameter and the new object will always have the default value attached to it unless we specify something else.

 
public function __construct($name, $description, $price, $color = "white") {
$this->name = $name;
$this->description = $description;
$this->price = $price;
$this->color = $color;

}
 
 In the code above we assigned white to the $color property of the construct method, meaning that each time we instantiate a new object using our Product class it will have a color of white unless we pass a different color.
For example let’s create two new objects using our product class inside our index.php file
 
$eDesk = new Product("Tito Desk", "Professional desk for coding", 199); // returns an object with the color set to white.
$eDeskDark = new Product("Tito Desk", "Professional desk for coding", 199, "black"); // returns an object with the color set to black.
 

Class methods

Inside a class a classic function is called method. Like properties a method can be public, protected and private. Methods can also be static. Inside a method we use the “$this” keyword that refers to the object it-self.
 
  • Public methods are accessible from anywhere, either inside or outside our class definition. They are declared using the “public” keyword
  • Protected methods are only accessible within our class or sub-classes. They are defined using the “protected” keyword.
  • Private methods are  only accessible within our class. Declared using the “private” keyword.
  • Static methods can be accessed without instantiate a new class using the :: operator.

Using public methods:

Let’s imagine that after we have instantiate a new object we want to change it’s name. We will define a method to accomplish this task so
Inside the class.product.php file just under the construct method we will add a new method.
 
        /**
* Set a Name
* @param string $name The product name
* @return string return $name New product name
*/
public function setName($name)
{
$this->name = $name;
return $name;
}
 
Now back in our index.php file we instantiate the object then we will call the setName() method to change the name of the object.
 
$eDesk4 = new Product("Desk initial Name", "a description for the desk here", 120); // instantiate a new object
var_dump($eDesk4->name); // returns "Desk Initial Name"
The setName Method above will accept a $name parameter and return the new name for an object. A method can be accessed using the following syntax
 
$eDesk4->setName("Ergo Desk"); // sets a new name for our desk
var_dump($eDesk4->name); // returns "Ergo Desk"

The var_dump() output will be the following when we execute our index.php file from the terminal.

string(17) "Desk initial Name"
string(9) "Ergo Desk"
 
Let’s define a few more methods inside our Product class that will be useful later to explain sub-classes and Visibility later.
 

/**
* Product Class
*
* @author Fabio Pacifici
* @copyright 2019 Fabio Pacifici
*/
class Product
{
/**
* Class Variables
* @var string _name the product name
* @var float _price the price of the product
* @var string _desc the description of the product
*/
protected $name;
protected $description;
protected $price;
/**
* @param string $name product name
* @param string $description the product description
* @param float $price the product price
*
*/
public function __construct($name, $description, $price)
{
$this->name = $name;
$this->desc = $description;
$this->price = $price;
}
/**
* Set a Name
* @param string $name The product name
* @return string return $name New product name
*/
public function setName($name)
{
$this->name = $name;
return $name;
}
/**
* Set the product price
* @param float $price product price
* @return float return $price product price
*/
public function setPrice($price)
{
$this->price = $price;
return $price;
}
/**
* @return float return price product price
*/
public function getPrice()
{
return $this->price;
}
/**
* @return string return name product name
*/
public function getName()
{
return $this->name;
}
/**
* @return float return desc product description
*/
public function getDescription()
{
return $this->description;
}
public function calcStockValue($qty)
{
$calc = $this->_price * $qty;
return $calc;
}
}
Our class now has six new functions: setName(), setPrice(), getPrice(), getName(), getDescription() and a calcStockValue() function.
Before dive into the Properties and Methods visibility and use the classes we defined, let’s see how to create a sub-class and see how inheritance between classes works.
 

Sub-Classes

To define a sub-class we use the “extends” keyword. A sub-class inherits methods and properties form the parent class.  A sub-class can also override methods and properties of the parent class by re-declaring them.  Continuing with our Product class let’s create a bicycle sub-class.
 
Create a separate file inside the Classes folder and name it class.bicycle.php
<?php
/**
* Bicycle class extends the Product class
* @author Fabio P
* @copyright 2019 Fabio P
*/
class Bicycle extends Product
{
/**
* @var float frameSize Bicycle frame size
* @var int wheelSize Bicycle wheel size
*
*/
public $frameSize;
public $wheelSize;
/**
* Bicycle Constructor
*
* @param string $name the name
* @param string $description the description
* @param float $price the price
* @param int $frameSize the size of the bicycle frame
* @param int $wheelSize the size of the wheels
*/
public function __construct($name, $description, $price, $frameSize, $wheelSize)
{
parent::__construct($name, $description, $price);
$this->frameSize = $frameSize;
$this->wheelSize = $wheelSize;
}
}
 
 As always we start opening the php tag then we use a DocBlock to document our class and we declare our class using the class keyword. But this time we want our new class to inherit functions and properties from another class that is the Product class therefore we use the extends keyword then the name of the class that we want to extend.
 
Inside our new class we can declare new properties and methods that are specific of this class or use and extend any property and class declared inside our parent class.
 
Then we has a construct method inside our new class and we pass to it the parameters defined inside our parent class and a couple more parameters.
Then inside the construct method we use the parent::__constructor() method right at the beginning to inherit from the parent constructor the properties declared there.
Follows the frameSize and wheelSize properties declared as usual inside the constructor.
 
Our Bicycle class has access to all the properties and methods declared inside the Product class:
  • $name
  • $description
  • $price
  • setName(),
  • setPrice(),
  • getPrice(),
  • getName(),
  • getDescription()
  • calcStockValue()
 
It can use or change them by re-declaring props and methods but it can also create new properties and methods that are specific to the Bicycle class and only available to it.
 

Properties Visibility (Access protected and private props)

Now that we know how to define a method inside a class and how to declare a sub-class we can see how to access protected and private properties.
A Protected property is only accessible inside the class or a subclass while a private property is accessible from a class only but not the its sub-class.
  • Public properties are accessible from anywhere, either inside or outside our class definition. They are declared using the “public” keyword
  • Protected properties are only accessible within our class or sub-classes. They are defined using the “protected” keyword.
  • Private properties are  only accessible within our class. Declared using the “private” keyword.
Protected Properties:
In the class methods example above we defined a few methods getName(), getPrice() and getDescription() but also set our properties as protected.  Now we can use these methods to and access them.
 
Our $name, $description, $price variables are protected properties of our class, meaning that we can only access them from inside a class or subclass.
Access them as we did so far will return a PHP fatal error.
 

Inside our index.php file

$tshirt = new Product("V-neck t-shirt", "cotton t-shirt for man", 12.99);
var_dump($tshirt->name);
//returns a Fatal error
PHP Fatal error:  Uncaught Error: Cannot access protected property Product::$name
This is because as we said protected properties are only accessible inside the class where they are defined, therefore the methods getName(), getDescription and getPrice() have  access to the class properties and can return them but we cannot do that directly.
 
var_dump($tshirt->getName());
var_dump($tshirt->getDescription());
var_dump($tshirt->getPrice());
// output
string(14) "V-neck t-shirt"
string(22) "cotton t-shirt for man"
int(12)
Since protected properties are available also from a sub-class we can use the same methods defined in the Product class to get the name, description and price from our Bicycle sub-class.
$bmx = new Bicycle("BMX bicycle", "professional bmx bicycle", 1200.99, 21, 20);
var_dump($bmx->getName());
var_dump($bmx->getDescription());
var_dump($bmx->getPrice());
 
 
Private Properties:
 
Since private properties are only available within the class where they are declared we won’t be able to access them from within a sub-class like our Bicycle class.
 
The result of trying to call the method to get the name of our object will be an error.
PHP Fatal error:  Uncaught Error: Cannot access private property Bicycle::$name
 

Methods & Visibility

  • Public methods are accessible from anywhere, either inside or outside our class definition. They are declared using the “public” keyword
  • Protected methods are only accessible within our class or sub-classes. They are defined using the “protected” keyword.
  • Private methods are  only accessible within our class. Declared using the “private” keyword.
  • Static methods can be accessed without instantiate a new class using the :: operator.

Public method:
A public method defined inside our Product class in a class.product.php file
as follow

public function calcStockValue($qty)
{
$calc = $this->_price * $qty;
return $calc;
}

Is available for both the class where it’s defined and its sub-classes

// from the main class

$tshirt = new Product("Spring tee", "V-neck tshirt for man", 20);
var_dump($tshirt->calcStockValue(120)); // returns 2400

// from the subclass

$bicycle = new Bicycle("my bmx", "my spure bmx", 1200, 21, 20);
var_dump($bicycle->calcStockValue(25)); // returns 30000

Protected Method:

A protected method can only be called from within the class or its sub-classes
by changing the previous method to protected we will get an error when we try to call it either
for the class or the subclass. If the previous method is set to protected like below

/**
* @return string return _desc product description
*/
protected function getDescription()
{
return $this->_desc;
}

Then we try to instanciate an object and var_dump() it, we will get a PHP fatal error.

from the main class

$tshirt = new Product("Spring tee", "V-neck tshirt for man", 20); // create a new object
var_dump("Protected Description: " . $tshirt->getDescription()); // returns fatal error.

The above dump will return the error below if we try to call the function from either the class or the subclass.

PHP Fatal error:  Uncaught Error: Call to protected method Product::calcProfit() from context '' in /mnt/c/Users/FabioHood/projects/Learning/PHP/oop/index.php:17

To make this work we need to create another public method inside our class that has access to the protected method.
Then we can call the method to return the protected values returned from the function.

/**
* Get the Protected Description
* @return string return the protected description from the getDescription function
*
*/
public function getProtectedDescription()
{
return $this->getDescription();
}

Now we can call the getProtectedDescription() method and return the result of the protected method getDescription()

$tshirt = new Product("Spring tee", "V-neck tshirt for man", 20);
//var_dump("Get Description:" . $tshirt->getDescription()); // returns error
var_dump("Get Description:" . $tshirt->getProtectedDescription()); 
//returns string(37) "Get Description:V-neck tshirt for man"

$bicycle = new Bicycle("my bmx", "my spure bmx", 1200, 21, 20);
var_dump("Get Description:" . $bicycle->getDescription()); // returns error
var_dump("Get Protected Description:" . $bicycle->getProtectedDescription()); // returns the description

The output will be as follow

string(37) "Get Description:V-neck tshirt for man"
This is returned by the child class and overrides the parent methodstring(38) "Get Protected Description:my spure bmx"

Private Methods:

are only accessible from the class where they are defined and not available to the sub-classes.
inside our Product class let’s change the getDescription method to private and see what happens
when we call the getProtectedDescription from our Class or its subclass.

First let’s rename the method to private.

/**
* @return string return _desc product description
*/
private function getDescription()
{
return $this->_desc;
}

Remember that we create a getProtectedDescription method inside our Class and that can be overridden from
its sub-classes. The getProtectedDescription simply returns the getDescription method above that returns the $description property.
Because we are talking about the Private visibility we will copy the method as rename it to Private for consistency.

Than let’s copy the method and call it getPrivateDescription inside our Product class

/**
* Get the Private Description
* @return string return the private description from the getDescription function
*
*/
public function getPrivateDescription()
{
return $this->getDescription();
}

Then let’s override the above method also in the Bicycle child class

 public function getPrivateDescription()
{
$message = "Private method is not available to child classes.\n It shall return error: \n";
echo $message;
return $this->getDescription();
}

Now, we can call this method from the class or its subclass and see what happens.
we expect the fist call to be successful and return the description while the second to be a
PHP fatal error and echo our message.

var_dump("Get private description within the class:" . $tshirt->getPrivateDescription());
// returns the description
string(21) "V-neck tshirt for man"
var_dump("Private Description: " . $bicycle->getPrivateDescription()); // returns the error
Private method is not available to child classes. It shall return errorL
PHP Fatal error:  Uncaught Error: Call to private method Product::getDescription() from context 'Bicycle' in /mnt/c/Users/FabioHood/projects/Learning/PHP/oop/classes/class.bicycle.php:43

Static methods:

A static method can be called without the need to instantiate a new object. We can simply use the class name followed by the scope resolution operator and the method or property.
for instance lets create inside our Product class two methods, one that calculates the stock value, and one that returns the profit.
The first function accepts one parameter that is the quantity and multiply it by the price.
The second function accepts tree parameters: price, qty and the cost. Inside the second function we call the first calcStockValue() function.
Since this is a static method we cannot use the “this” keyword in this contexts and to call the first method we need to call the method prefixing it with the class name and the scope
resolution operator otherwise we will get a PHP fatal error.

/**
* Calculate Stock value
* @param float $price the price
* @param int $qty Quantity
* @return float return $calc The total of the calculation
*/
public static function calcStockValue($price, $qty)
{
$calc = $price * $qty;
return $calc;
}
/**
* Calculate Profit value
* @param float $price the price
* @param int $qty Quantity
* @param float $cost The cost of the item
* @return float return $totalValue the final value
*/
public static function calcProfit($price, $qty, $cost)
{
$totalCost = $cost * $qty;
$totalValue = Product::calcStockValue($price, $qty);
return $totalValue - $totalCost;
}

Let’s call this methods and see the results

$stockValue = Product::calcStockValue(20, 120);
$profit = Product::calcProfit(20, 120, 9);
var_dump("Stock Value: " . $stockValue . ", Profit: " . $profit);
$bicycleStockValue = Bicycle::calcStockValue(399.95, 25);
$bicycleProfit = Bicycle::calcProfit(399.95, 25, 199);
var_dump("BMX Stock Value: " . $bicycleStockValue . ", BMX Profit: " . $bicycleProfit);

Both will return our results as expected

string(31) "Stock Value: 2400, Profit: 1320"
string(45) "BMX Stock Value: 9998.75, BMX Profit: 5023.75"

[Coming soon]

Output our classes to the browser:

  1. Add the HTML inside our Views/index.view.php file
  2. Instanciate some objects inside our index.php file as an array
  3. Echo the values inside our view index.view.php

Extras:


Choose a Green Hosting for your application..