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.