Object Oriented Programming is about writing code using Objects. Once we understand the concept of an "Object" and its main Principles, we are ready to start writing OOP code.

Prerequisites:

 

OOP always start with a main file where the main entry point is located. This is the file that the Web Server will refer the client requests if this file is part of a Web Application.

This file is commonly named as index and in the case of PHP Language is called index.php

 In this file we include the main "Object" and a call to the main "Method" on this "Object" that will be the entry point of the entire Application.

Examples of these:

Symfony 5.4:

<?php

use App\Kernel;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
    return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
};

 

Legacy Symfony 2.8 app_dev (index when in dev mode):

<?php

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Debug\Debug;

// If you don't want to setup permissions the proper way, just uncomment the following PHP line
// read http://symfony.com/doc/current/book/installation.html#checking-symfony-application-configuration-and-setup
// for more information
//umask(0000);

/**
 * @var Composer\Autoload\ClassLoader $loader
 */
$loader = require __DIR__.'/../app/autoload.php';
Debug::enable(E_RECOVERABLE_ERROR & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED, false);
//switch to Debug::enable(); for all messages
$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

Joomla 3.4 index:

<?php
/**
 * @package    Joomla.Site
 *
 * @copyright  (C) 2005 Open Source Matters, Inc. <https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

/**
 * Define the application's minimum supported PHP version as a constant so it can be referenced within the application.
 */
define('JOOMLA_MINIMUM_PHP', '5.3.10');

if (version_compare(PHP_VERSION, JOOMLA_MINIMUM_PHP, '<'))
{
	die('Your host needs to use PHP ' . JOOMLA_MINIMUM_PHP . ' or higher to run this version of Joomla!');
}

// Saves the start time and memory usage.
$startTime = microtime(1);
$startMem  = memory_get_usage();

/**
 * Constant that is checked in included files to prevent direct access.
 * define() is used in the installation folder rather than "const" to not error for PHP 5.2 and lower
 */
define('_JEXEC', 1);

if (file_exists(__DIR__ . '/defines.php'))
{
	include_once __DIR__ . '/defines.php';
}

if (!defined('_JDEFINES'))
{
	define('JPATH_BASE', __DIR__);
	require_once JPATH_BASE . '/includes/defines.php';
}

require_once JPATH_BASE . '/includes/framework.php';

// Set profiler start time and memory usage and mark afterLoad in the profiler.
JDEBUG ? JProfiler::getInstance('Application')->setStart($startTime, $startMem)->mark('afterLoad') : null;

// Instantiate the application.
$app = JFactory::getApplication('site');

// Execute the application.
$app->execute();

Wordpress index:

<?php
/**
 * Front to the WordPress application. This file doesn't do anything, but loads
 * wp-blog-header.php which does and tells WordPress to load the theme.
 *
 * @package WordPress
 */

/**
 * Tells WordPress to load the WordPress theme and output it.
 *
 * @var bool
 */
define('WP_USE_THEMES', true);

/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );

 

If you are building your Application from scratch, I encourage you to follow this pattern on having a single point of entry through the index.php file:

<?php
/*
 * Index file
 */

//------------------------------------------------
// Basic autoloader
include 'autoloader.php';

$app = new services\router();

$app->run();

 

In modern PHP Applications, the code is encapsulated in "Objects" called "Classes" and as Best Practice, there is always one "Class" per PHP file. These PHP files are organized in sub-directories of the main root directory of the Application. For easy access and handling of these, PHP has a concept called "namespace". In each PHP file before the class definition, the file's namespace is declared:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * Employees
 *
 * @ORM\Table(name="employees", indexes={@ORM\Index(name="fk_employees_bank_accounts1_idx", columns={"bank_accounts_id"}), @ORM\Index(name="fk_employees_tax_info1_idx", columns={"tax_info_id"}), @ORM\Index(name="fk_employees_audit_log1_idx", columns={"audit_log_id"}), @ORM\Index(name="fk_employees_contact_info1_idx", columns={"contact_info_id"})})
 * @ORM\Entity
 */
class Employees
{
   ...

 

The namespace is the path from the Application's root directory to the directory where the PHP file is actually placed.

In the PHP index file, the first thing to be done is to register these namespaces and files, so PHP can locate and load them with the "use" directive. A simple auto-loader script may look like this:

<?php
//namespace private;

/**
 * Basic autoload implementation
 */
function loadClass($className) {
        $fileName = '';
        $namespace = '';

        // Sets the include path as the "src" directory
        $includePath = dirname(__FILE__).DIRECTORY_SEPARATOR.'app';

        if (false !== ($lastNsPos = strripos($className, '\\'))) {
            $namespace = substr($className, 0, $lastNsPos);
            $className = substr($className, $lastNsPos + 1);
            $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
        }
        $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
        $fullFileName = $includePath . DIRECTORY_SEPARATOR . $fileName;
      
        if (file_exists($fullFileName)) {
            require $fullFileName;
        } else {
            echo 'Class "'.$className.'" does not exist.';
        }
    }

spl_autoload_register('loadClass'); // Registers the autoloader

 

A better and simpler way to implement class auto-loading is to use composer package manager, even if you are not using any open source package, you can leverage the auto-loading logic provided by composer.

I suggest to place in the root of your Application a composer.json file like this:

{
    "type": "project",
    "license": "proprietary",
    "description": "Cool Project built from Scratch.",
    "require": {
        "php": ">=8.2"
    },
    "require-dev": {
    },
    "config": {
        "preferred-install": {
            "*": "dist"
        },
        "sort-packages": true,
        "allow-plugins": {
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests/"
        }
    },
    "replace": {
    },
    "scripts": {
    },
    "conflict": {
    },
    "extra": {
    }
}

Then open a SSH console and run:

$> composer install

 Composer will create a vendor folder and will put in it all these files used to register and auto-load all the PHP files.

 

 After that, all PHP class files placed in the "src" folder can be name-spaced starting with "App\" no matter how many sub-directory levels are needed to reach the PHP file:

<?php

namespace App\ProductsBundle\Api\Transformers;

...

 

The purpose of all Computer programs is to process an Input Request, process it according to some Business Logic and produce an Output Response.

In the case of PHP Web based Applications, the incoming client request is catch by the Web Server, then redirected to the PHP index file where the program will get the data out of the "Request Object" sent by the Web Server, process it, build a "Response Object" and send it back to the Web Server, which in turn send it back to the client's Browser.  This is called the Request - Response cycle.

 A typical visit to a web page produces a Web Request like this:

 

 And the response in this case is a Html page used to render the web page in the Browser's Tab Window along with all required Style Sheets and Javascript code as separate Requests.

 

 

PHP is a very popular and used Computer Language mostly for building web based software applications. It is an interpreted language, meaning that every time a request is made to run a PHP Script, the interpreter translates the human readable code into machine code. Since PHP 5.5, the human readable code can be precompiled into bytecode and stored in shared memory, to be reused by all other requests, making PHP to execute very fast. For this to happen, you need to have OP Cache extension installed.

Refer to this articles to help you have a ready to use, High Performance, OP Cache ready PHP Interpreter along with a Nginx Web Server and a Maria DB Server for you to start learning how to write PHP Enterprise Class Software Applications:

 

A typical PHP Script file looks like this:

<?php

//This prints Hello World in the Browser
echo "Hello World!";

//This prints Hello World in the Browser too
print_r('Hello World!');

//Assign a value to a variable
$helloWorld = 'Hello World!';

//Print in the Browser the content of the variable
echo $helloWorld;


?>

 Refer to PHP Basic Syntax for more on this.

A computer program is a set of lines of code where you tell the computer what it needs to do.

PHP is a programming language where you use human friendly language statements to tell the computer what to do.

Basically PHP (and all other computer programs) has these 3 main parts:

Get Input Data from User or other Source.

Input data from User is most likely coming from a filled form. Typical Html Form looks like this:

<html>
<head></head>
<body>
<form name="user" action="backend-enpoint-url" method="post">
    <input type="text" value="" name="firstName">
    <input type="text" value="" name="lastName">
    <input type="submit" value="save">
</form>
</body>

</html>

Input Data from other Source is mostly coming in the request body as a json string. Other common format is xml string.

{
	"id": 3,
	"lineItemsId": "12154",
	"notes": "I have this idea 4"
}

 

For a Html Form Request:

//When the form is submitted and the form method is Post,  PHP gets the input values from the Web Server in a Global Variable $_POST
//Here we assign these $_POST values to these variables for better handling
$formInputFirstName = $_POST['firstName'];
$formInputLastName = $_POST['lastName'];

This Data is read from the Request and stored in variables for further processing

 

Process Request.

All statements in PHP (and all other languages) can be grouped into:

Assignment Instructions:

// "take the value from this and assign it to a single scalar variable"
$formInputFirstName = $_POST['firstName'];
$formInputLastName = $_POST['lastName'];

// "take the value from this and assign it to an array variable"
$userName['firstName'] = $_POST['firstName'];
$userName['lastName'] = $_POST['lastName'];

// "take the value from this and assign it to an object property"
$zebra = new Animal();
$zebra->setSpecies($_POST['firstName'] . $_POST['lastname']);

 Refer to PHP Assignment Operators and to PHP Operators for more on this.

 

 Control Statements:

The most common ones are for compare and for iteration:

/*
 * Compare
 */
$a = 1;
$b = 2;

if ($a == $b) {
    //Do this if its true
} else {
    //Do this if its false
}

if ($a < $b) {
    //Do this if its true
} elseif ($a == $b) {
    //Do this if its true
} else {
    //Do this iif none is true
}


/*
 * Iterate
 */
$c = ['a', 'b', 'c', 'd'];

foreach ($c as $letter) {
    //Do this for each one of the elements in the $c array
}

The if statement is a bifurcation in the flow of the code. It evaluates the condition and it continues the execution in the section that correspond.

The foreach statement is one of the few different kinds of loops. It basically iterates over each one of the elements of an Array or the properties in an Object and executes the statements in it.

When writing a PHP program, you will use these statements to process the input Data, apply business logic based on evaluating conditions, maybe store the Data and or its result in some physical device like a Database in a Hard Drive for later use and transform the Data and or the Results into a Response.

Refer to PHP Control Structures for more on this.

 

 Presentation Statements:

When the transformed Data or the Results obtained after applying some sort of Business logic to it is ready to be sent to the User most commonly these statements are used:

$a = 1;
$b = 2;

$result = ((3 * $a) + ($b/2))/100 ;

echo "The Resulting percentage is " . $result . "%\n";

$f = "The resulting percentage: %e was obtained evaluating from %d and %d";
echo sprintf($f, $result, $a, $b);

Refer to PHP Print Functions for more on this.

 

Return Response Data to User via Web Browser / Console or send it to other Source.

If the Response is sent back to the User's browser we ask PHP to instruct the Web Server to respond with a Html Response Page displaying embedded data and result using PHP tags:

<html>
<head></head>
<body>
<h1>Results:</h1>
<p>Input Data A: <?php echo $a; ?></p>
<p>Input Data B: <?php echo $b; ?></p>
<p>Result Percentage: <?php echo $result; ?></p>
</body>
</html>

 

 

 

 

 

 

As many other languages, PHP handles many different data types. Data types and their correct use are key for implementing a very Robust Enterprise Class PHP Application.

Prerequisites:

 

These are the most common data types in PHP:

null 

This type represents a void or nothing stored in the variable set with this data type. Nulls are difficult to understand at first, but were designed for the developer to be able to differentiate a variable with nothing in it, from a variable with an empty string or a variable with a zero value.

$a = null; // This variable exists but doesnt has any value nor a data type

(string) $b = ''; // This variable exists and it has type casted as string with 0 length

(int) $c = 0; // This variable exists and it has type casted as an integer which value is 0

(bool) $d = false; // This variable exists and it has type casted as a boolean  with value false

(bool) $e = 0; // This variable exists and it has type casted as boolean with value false

if you compare these variables each one against the others , none of them are equal, except for the last 2, a boolean false is equal as a boolean 0

Refer to PHP Types Intro for more on this.


bool

This type represents a Boolean value and can be either true or false

Because in earlier versions of PHP and other languages, booleans were declared as 1 for true and 0 for false  nowadays these values are interchangeable, but as best practice, it is highly recommended to use true / false

This data type is used for Boolean Algebra and / or for setting flags that helps in validation routines.

Refer to PHP Booleans for more info.


int

This data type represents any positive or negative Integer Number within the permitted range. Ints can be specified in decimal (base 10), hexadecimal (base 16), octal (base 8) or binary (base 2) notation and you can do any sort of arithmetic operations with them.

Refer to PHP Int Data Type  and  PHP Arithmetic Operators for more on this.


float (floating-point number)

 A float can be any positive or negative number and it differentiates from the int data type because this can have as many decimal numbers as allowed by the precision set in the PHP configuration. They allow the "e" nototation.

$a = 1.23456;
$b = 2.3e4;
$c= 4.56e-5;

refer to PHP Floating Numbers for more on this.


string

This data type is the most generic one and it can contain any combination of valid ASCII characters

$singleQuotedString = 'This is a string';

$doubleQuotedString = "This is a string";

$heredocString = <<<HEREDOC
This is a really long string
and can contain many paragraphs
until reaching the end.
HEREDOC;

Refer to PHP String Types for more info on this.

 

array

 Arrays are one of the most important data types in PHP and can contain many different kinds of Data Structures like List, Vector, Map, Hash Table, Dictionary, Stack, Queue, Trees, and many others. Basically all of these are based on the concept of key - value pairs . Arrays are declared in PHP this way:

use App\Entity\Animal;

// Array notation.
$a = array();// Empty array assigned to $a.

// Bracket notation. 
$b = [];//Empty array assigned to $b.

//These two arrays are equal
$a = array('key1' => 'value1', 'key2' => 'value2', 'keyn' => 'valuen');
$b = ['key1' => 'value1', 'key2' => 'value2', 'keyn' => 'valuen'];

//Array keys can be strings or integers
$c = [0 => 'value1', 1 => 'value2', 2 =>'value3'];

//Array values can be any other data type including other arrays, objects, collections, etc...
$d = [
    'k1' => 1, //value is an integer
    'k2' => 'a string',//value is a string
    'k3' => ['kk1' => 'vv1', 'kk2' => 'vv2'], //value is another array
    'k4' => new Animal('Zebra'),//value is an object
    12 => 3.4e5,//value is a float
];

//Arrays can be a simple list where the keys are not shown but the key pointer is kept nternally
$list = ['a','b','c', 'd','e'];//letter 'c'  key is 2 -- THis representation only allows integer values for the keys

//Arrays can be multi dimensional
$multiDimensional['x']['y']['z'] = [1,2,3,4,5,6,7,8,9];

refer to PHP Arrays for more on this. 

 

object

 To better understand the concept of object, please refer to this post: Basics of Object Oriented Programming in PHP - Part I

In terms of PHP Data Type, and Object is a special type of Array , where each key is either a property or a method and their corresponding value stores the content of it. If you do this:

$zebra = new Animal('zebra');
$zebra->setEyes(2);
$zebra->setLegs(4);
$zebra->setTail(3.5);
$zebra->setMotionSpeed(23.45);


print_r($zebra);

Then in the Browser you'll see this:

When you ask PHP to print out an object it will only shows the properties, not the methods. however internally, these methods are stored in key value pairs so PHP can point at them when needed.

If the object's Class definition has only properties, you can convert this to an array:

$object = new \StdClass();//Creates a new Generic Object
$object->key1 = 1;
$object->key2 = 'a string';
$object->key3 = [1,2,3];

print_r((array) $object);

Then in the Browser:

 

 Also, if you have an Array, it can be converted into an object where the array keys become object properties:

$d = [
    'k1' => 1, //value is an integer
    'k2' => '--- a string ---',//value is a string
    'k3' => ['kk1' => 'vv1', 'kk2' => 'vv2'], //value is another array
    'k4' => new Animal('Zebra'),//value is an object
    'k5' => 3.4e5,//value is a float
];

$dd = (object) $d;

print_r($dd);

echo "\n\n print out the content of property k2: ";
echo "{$dd->k2}";

In the Browser:

Refer to PHP Objects for more on this.

 

 

PHP born as a very simple Computer Language to help building Dynamically Generated Server Side Html pages to be rendered in the Computer using a Web Browser. Since then, new features, new extensions, new statements, new libraries, etc. has been added to the core executable.

Currently it completely supports Object Oriented Programming and it has an outstanding Exception handling. 

Prerequisites:

 

In PHP we create new objects instantiating a Class:

$zebra = new Animal('zebra');

in here we are assigning to the variable $zebra a new Animal Class and we are setting the species property passing 'zebra'  as string parameter to the Class Constructor.

Once we have an object instance, we can access its properties and methods using either  -> (Arrow Function Call) or :: (Scope Resolution Operator).

There are a few rules that apply to accessing properties and methods in PHP:

:: can only be used if the method is declared Static.

<?php
namespace App\Entity;
class Zoo
{
    /**
     * @var string|null
     */
    private ?string $zooName;
    
    /**
     * @param string|null $zooName
     */
    public function __construct(?string $zooName)
    {
        $this->zooName = $zooName;
    }
    
    /**
     *  This method can be called using ::
     * @param string $a
     * @param string $b
     * @return string
     */
    public static function coolZoo(string $a, string $b): string
    {
        return 'This Cool Zoo is for ' . $a . ' and ' . $b;
    }
    
}

Now from other file you can make a static function call like this:

$zoo = new Zoo('N.Y. City Zoo');


echo "Sample use of Static Method: <strong>";
echo $zoo::coolZoo('Girls', 'Boys');
echo "</strong>";

and in the Browser you see this:

 

 :: can be used to call a static method in a Class without need to instantiate an object.

echo "Sample use of Static Method: <strong>";
echo Zoo::coolZoo('Girls', 'Boys');
echo "</strong>";

 

Properties and Methods can only be accessed if declared public.

<?php
namespace App\Entity;
class Zoo
{
    /**
     * @var string|null
     */
    private ?string $zooName;
    
    /**
     * @param string|null $zooName
     */
    public function __construct(?string $zooName)
    {
        $this->zooName = $zooName;
    }
    
    /**
     * @param string $a
     * @param string $b
     * @return string
     */
    public function coolZoo(string $a, string $b): string
    {
        $welcome = 'Welcome to ' . $this->zooName . '. ';
        
        return $welcome . $this->doZooStuff($a, $b);
    }
    
    /**
     * @param string $a
     * @param string $b
     * @return string
     */
    private function doZooStuff(string $a, string $b): string
    {
        return 'This Cool Zoo is for ' . $a . ' and ' . $b;
    }
    
}

From other file you can do:

$zoo = new Zoo('N.Y. City Zoo');

//This works
echo $zoo->coolZoo('Girls', 'Boys');
echo "<br/>";
//This wont work and throws error
echo $zoo->doZooStuff('Girls', 'Boys');

 

Welcome to N.Y. City Zoo. This Cool Zoo is for Girls and Boys

Fatal error: Uncaught Error: Call to private method App\Entity\Zoo::doZooStuff() from global scope in /var/www/cool_project/php_code/src/index.php:19 Stack trace: #0 {main} thrown in /var/www/cool_project/php_code/src/index.php on line 19

 

Properties and Methods can only be accessed from one Class to another if declared protected and calling Class is extending the other.

class Animal extends Zoo
{
    /**
     * @var string|null
     */
    private ?string $species;
    
    /**
     * @var int|null
     */
    private ?int $eyes;
    
    /**
     * @var int|null
     */
    private ?int $legs;
    
    /**
     * @var float|null
     */
    private ?float $tail;
    
    /**
     * @param string|null $species
     */
    public function __construct(?string $zooName, ?string $species)
    {
        parent::__construct($zooName);
        $this->species = $species;
    }
    
    /**
     * @return string|null
     */
    public function getAnimalZoo()
    {
        return $this->zooName;
    }
    

From other file you can do:

//Zoo Animals
$zebra = new Animal('S.D. Zoo','zebra');

echo 'This ' . $zebra->getSpecies() . ' lives in ' . $zebra->getAnimalZoo();

and in the Browser:

This zebra lives in S.D. Zoo

 

Pseudo variable $this is used to refer to the object itself from within an object method.

Private Properties and Methods are accessible only from other Method in the same object using $this .

    /**
     * @param string $a
     * @param string $b
     * @return string
     */
    public function coolZoo(string $a, string $b): string
    {
        $welcome = 'Welcome to ' . $this->zooName . '. ';
        
        return $welcome . $this->doZooStuff($a, $b);
    }
    
    /**
     * @param string $a
     * @param string $b
     * @return string
     */
    private function doZooStuff(string $a, string $b): string
    {
        return 'This Cool Zoo is for ' . $a . ' and ' . $b;
    }

 

self can be used to refer to the object itself and use :: to call properties and methods declared as static and magic methods like __construct

class Zoo
{
    /**
     * @var string|null
     */
    protected ?string $zooName;
    
    static ?string $zooHours = '9am to 5pm Mon to Fri';

 

class Animal extends Zoo
{
    /**
     * @var string|null
     */
    private ?string $species;
    
    /**
     * @var int|null
     */
    private ?int $eyes;
    
    /**
     * @var int|null
     */
    private ?int $legs;
    
    /**
     * @var float|null
     */
    private ?float $tail;
    
    /**
     * @param string|null $species
     */
    public function __construct(?string $zooName, ?string $species)
    {
        parent::__construct($zooName);
        $this->species = $species;
    }
    
    /**
     * @return string|null
     */
    public function getAnimalZoo()
    {
        $zooHours = self::$zooHours;
        
        return $this->zooName . 'open from / to :' . $zooHours;
    }

From other file you can do:

//Zoo Animals
$zebra = new Animal('S.D. Zoo','zebra');

echo 'This ' . $zebra->getSpecies() . ' lives in ' . $zebra->getAnimalZoo();

And you get in the Browser:

This zebra lives in S.D. Zooopen from / to :9am to 5pm Mon to Fri

 

Mastering PHP Object Oriented Programming requires a complete understanding of all these basic rules and principles.

 Refer to PHP Classes and Objects for more on this.