Book Image

The Art of Modern PHP 8

By : Joseph Edmonds
5 (1)
Book Image

The Art of Modern PHP 8

5 (1)
By: Joseph Edmonds

Overview of this book

PHP has come a long way since its introduction. While the language has evolved with PHP 8, there are still a lot of websites running on a version of PHP that is no longer supported. If you are a PHP developer working with legacy PHP systems and want to discover the tenants of modern PHP, this is the book for you. The Art of Modern PHP 8 walks you through the latest PHP features and language concepts. The book helps you upgrade your knowledge of PHP programming and practices. Starting with object-oriented programming (OOP) in PHP and related language features, you'll work through modern programming techniques such as inheritance, understand how it contrasts with composition, and finally look at more advanced language features. You'll learn about the MVC pattern by developing your own MVC system and advance to understanding what a DI container does by building a toy DI container. The book gives you an overview of Composer and how to use it to create reusable PHP packages. You’ll also find techniques for deploying these packages to package libraries for other developers to explore. By the end of this PHP book, you'll have equipped yourself with modern server-side programming techniques using the latest versions of PHP.
Table of Contents (19 chapters)
1
Section 1 – PHP 8 OOP
Free Chapter
2
Chapter 1: Object-Oriented PHP
5
Section 2 – PHP Types
7
Chapter 5: Object Types, Interfaces, and Unions
9
Section 3 – Clean PHP 8 Patterns and Style
13
Section 4 – PHP 8 Composer Package Management (and PHP 8.1)
16
Section 5 – Bonus Section - PHP 8.1

What is OOP?

If you don't really know what OOP even means, then this section is for you! We're going to take a step back and start right from the beginning to try to understand the meaning of the phrase, then try to understand OOP as compared to other programming styles, and finally, have a quick tour of some modern object-oriented PHP packages and projects.

So, let's get started with looking at what OOP really means.

Understanding the phrase

OOP stands for object-oriented programming. It sounds like one of those CS phrases that get bandied about quite a bit without people really understanding what they mean. Let's unpack it, starting from the end

Programming

Hopefully, you already have a good idea of what we mean by programming. PHP is a programming language and by that we mean simply that it is a set of coding words, symbols, and phrases that you can use to create code that ultimately does something.

There is a lot of inane debate about whether PHP truly is a programming language but let's not go there. We're here to get things done and that is where PHP excels.

Oriented

Oriented means "showing the direction in which something is aimed, directed towards or interested in something." So, we're programming in a way that is directed toward or interested in something. The "something" we are interested in is objects. In OOP, we use classes and objects for everything.

Object

What is an object? Well, in PHP, an object is an "instance" of a "class."

Here is the simplest class in PHP

<?php
class Foo {}

Simply enough, it is defined with the word class and it has a name and then a body, which is delineated by the curly braces. On its own, this is pretty useless, of course. It gets more interesting as we add code to the body of the class and meta information to the class definition.

To create an object, we use the word new and can then optionally assign the result of this call to a variable. We now have an object:

<?php
$foo = new Foo();

When we are talking about OOP, what we really mean is that we will compose our program entirely using objects. There must always be some code that resides at the global scope, but in an OOP program, this code is very limited indeed and is simply used to bootstrap and initialize the OOP code.

For example, this is the index.php file that all web requests are directed to when looking for a page in a Symfony project:

public/index.php

Repo: https://git.io/JqJxu

<?php
use App\Kernel;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\ErrorHandler\Debug;
use Symfony\Component\HttpFoundation\Request;
require dirname(__DIR__).'/vendor/autoload.php';
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
if ($_SERVER['APP_DEBUG']) {
    umask(0000);
    Debug::enable();
}
if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) {
    Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}
if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
    Request::setTrustedHosts([$trustedHosts]);
}
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

As you can see, every single line of code apart from the call to umask is instantiating or calling methods on classes or objects. The file procedurally represents an entire application, and the entire application's code is encapsulated in the classes instantiated in this file, and the classes they are composed of.

OOP alternatives

It might be easier to understand what OOP is if we compare it with other programming styles. Let's explore two other programming styles to help deepen our understanding.

Procedural programming

This is the classic PHP style and is probably the reason why PHP often gets bad press. Procedural code works like a long list of instructions. You start at the top and continue reading till you hit the bottom.

Of course, all code works like this really, but the point is that in procedural code, there is much less use of scoping. A lot of work is done in the global scope, though there will generally be lots of calls to global functions and maybe even a few objects floating around.

The benefit of procedural code is that it is highly optimized for writing. You can write the code like a logical stream of consciousness.

The downsides to procedural code are that it can be quite difficult to reuse chunks of code, there can be a large number of variables in the global scope, which can make debugging things somewhat challenging, and finally, the ability to test distinct parts of the code is somewhat diminished – you can only really test the system as a whole with end-to-end tests.

One procedural project that has stood the test of time and is almost unbelievably popular and successful is WordPress:

GitHub – WordPress/wordpress-develop

https://github.com/WordPress/wordpress-develop

I think it would be fair to say that the exception proves the rule, though – the general trajectory of modern PHP has gone very much toward OOP.

Procedural code can be great for creating smaller scripts of maybe 1-200 lines, but for building full-blown projects it is no longer regarded as a good idea by most PHP developers.

The chunk of code you are about to read is entirely fictional but created from long years of dealing with this kind of code in production. It's big, verbose, and old-fashioned. I'm sure many of you will recognize this kind of file. Those of you that don't, count your blessings!

<?php
# product_admin.php
// bring in an application top file that contains 1000 lines of bootstrapping and including things
require __DIR__.'/../../application_top.php';
if(isset($_GET['products_id'])){
    // 500 lines of product related stuff
    if(isset($_POST['action'])){
        switch($_POST['action']){
            // 1000 lines of various post actions that might be happening
        }   
    }
}

In procedural code, it is normal for each page type to have its own file – this means that public traffic can be loading lots of different PHP files. Your public htdocs folder will generally include a number of PHP files that are publicly accessible and executable, possibly in subfolders as well for different system areas.

Functional programming

Functional programming, as its name implies, predominantly uses functions as the building blocks of code. In functional programming, we try to use "pure functions."

Pure functions are those functions that, when given specific values as inputs, will do the following things:

  1. Always return the same value
  2. Never cause any side effects

Pure functions are fantastic because they are very easy to reason about, very easy to test, and are completely 100% decoupled from any other code or state.

PHP has a powerful functional model and can be a great language for functional styles. I will admit I have never seen a code base in PHP that you would regard as purely written in the functional programming style, but you do often see functional programming styles utilized in OOP and procedural code.

A deep dive into functional programming in PHP is beyond the scope of this book; however, I really encourage you to learn more about functional programming in PHP and hit these docs pages:

Here is a contrived example of how a functional programming index.php file might look:

<?php
declare(strict_types=1);
require __DIR__.'/../functions.php';
(function(string $responseTxt, array $headers):void{
    array_map(
        fn(string $header):void => header($header), 
        $headers
    );
    echo $responseTxt;
})(...(function(array $request):array{        
    $headers=[];
    $responseTxt='';
    // some code to actually generate the page and headers
    return ['headers'=>$headers, 'responseTxt'=>$responseTxt];
})($_REQUEST));

While I have never actually seen a proper functional programming-based project in the real world, you can and do see functional programming styles applied to OOP and procedural projects. The benefits of using pure functions and avoiding a shared state are applicable to all forms of programming.

So, now that we have looked at some alternative programming styles, let's move on to ways you can start to learn object-oriented PHP.

Learning object-oriented PHP

The first resource you should hit when learning PHP is the official documentation:

PHP: Classes and Objects - Manual

https://www.php.net/manual/en/language.oop5.php

This is good, though I do suggest you avoid the comments as many are very old and not relevant at all.

Probably the easiest way to get your head around OOP in PHP is to work on an existing open source project or framework that is written in the OOP style. There are many to choose from, though the quality can vary.

Here is a quick introduction to some popular projects.

Frameworks

The two most popular PHP frameworks are Laravel and Symfony. All modern PHP frameworks that I am aware of adopt the Model, View, Controller (MVC) structure.

In a nutshell, this means that all requests are directed to a single "front controller," which then handles deciding exactly what the request is asking for and then routing that to the correct Controller. What that means is that there is a single publicly accessible index.php file as the only public PHP file in the htdocs folder.

The Controller's job is to utilize the Model to retrieve any data required and perform any required processing before finally utilizing the View to return a string of text to be rendered as HTML. It's worth reading more on MVC if this is not something you are familiar with.

Symfony

Symfony is one of the oldest PHP frameworks (in active development since 2005) and has matured with the language over time.

It is a great choice for "enterprise" projects that require stability and a clear support lifetime. The general wisdom is that Symfony might be a better choice for long-term projects that are likely to grow in complexity over time.

The way that modern Symfony is constructed is highly modular; it allows you to keep the scale of your application as lean as possible, only bringing in functionality that you need.

Symfony is built upon the concept of "Components," which are actually framework-agnostic decoupled libraries that perform a certain function. This means that the code base as a whole is kept very clean, and you can work in a way that is less about the framework.

To find out more about Symfony, visit:

GitHub - symfony/symfony: The Symfony PHP framework

https://github.com/symfony/symfony

Laravel

Laravel is by far the most popular PHP framework at the moment. Laravel uses a lot of Symfony components under the hood, which underlines how good the Symfony stuff is. Where Laravel and Symfony differ is primarily in their approach and philosophy.

The general wisdom is that Laravel is easier and faster to work with for more simple projects, but if you are expecting to build the kind of project that might grow very complex over time, then Symfony might be a better choice.

To learn more about Laravel, go to:

GitHub - laravel/laravel: A PHP framework for web artisans

https://github.com/laravel/laravel

Slim

If you are looking to build something simple, such as a plain API, then you might enjoy working with more of a micro framework such as Slim.

More information on Slim can be found at:

GitHub - slimphp/Slim: Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs.

https://github.com/slimphp/Slim

Roll your own!

This is not something that I would recommend for a real production site, but for a personal project, you can't really beat the experience of creating your own bespoke MVC framework.

If you want to avoid reinventing the wheel, you could take the same tack as many successful projects and utilize Symfony components for your basic building blocks, such as HttpKernel.

Find out more here:

GitHub - symfony/http-kernel: The HttpKernel component provides a structured process for converting a Request into a Response.

https://github.com/symfony/http-kernel

Applications

Learning frameworks is all well and good, but if you need to solve a fairly standard project such as building an online shop or some form of blog or brochure site, then you might be better off choosing a more complete package that already includes all the basic features you need.

I have pulled together a few suggestions for you. These are all generally framework-based and so can give you some good ideas on how to use a framework in a full application.

E-commerce

An area where PHP really shines in terms of theopen source packages available is e-commerce. The main problem facing the modern e-commerce PHP developer is that there is so much choice!

Sylius

Sylius is Symfony-based and has been built using modern practices such as test-driven development (TDD) and behavior-driven development (BDD). It doesn't really claim to be the "all bells and whistles included" platform that perhaps Magento does, but instead it offers itself as a solid platform for a more bespoke e-commerce solution.

Find Sylius here:

GitHub - Sylius/Sylius: Open Source eCommerce Platform on Symfony

https://github.com/Sylius/Sylius

Magento

Magento is the big daddy in open source PHP e-commerce. Magento is based on quite an old-fashioned framework at its core and is unusual in that it does not use Symfony or Laravel as its framework. Magento 2 uses some interesting strategies such as "aspect-oriented programming" and extensive use of code generation.

Want to know more? Visit:

GitHub - Magento

http://github.com/magento/magento2

Shopware

The latest version of Shopware is Symfony-based and aims to provide Magento levels of functionality with the development best practice approach of Sylius. It's an interesting proposition and definitely worth a look.

Check Shopware out here:

GitHub - shopware/platform: Shopware 6 is an open source e-commerce platform realised by the ideas and the spirit of its community.

https://github.com/shopware/platform

CMS

Content management systems (CMSes) are designed to manage generic content-driven sites such as blogs and brochure sites. WordPress alone powers a huge percentage (at least 30%, maybe close to 40%) of sites on the internet, with big names such as techcrunch.com and blog.mozilla.org proudly running the platform.

Drupal

Drupal has been a very popular CMS in the PHP world for a long time and has gradually morphed from procedural roots into a modern OOP system.

Drupal uses Symfony components such as HttpKernel and routing components along with other more modular components such as Twig and YAML. Drupal 7 had its own components (kernel, router, templating, config management, and so on), and then Drupal 8 was an almost rewrite with more Symfony components and an OOP approach.

It is a large-scale CMS platform suitable for bigger-content projects. It is not a pure Symfony framework project but is a good example of a project that has managed to make itself more object-oriented over time and thereby improved the developer experience significantly.

More on Drupal here:

project / drupal · GitLab

https://git.drupalcode.org

OctoberCMS

October CMS is a much smaller project than Drupal but worth a look if you prefer something Laravel-based.

Check it out here:

GitHub - octobercms/october: Free, open source, self-hosted CMS platform based on the Laravel PHP Framework.

https://github.com/octobercms/october

Joomla

Another CMS project with a long history is Joomla. At the time of writing, version 4 is being actively developed. This brings things significantly up to date in comparison to the current version 3.

The main project is here:

GitHub - joomla/joomla-cms at 4.1-dev

https://git.io/JZZ5h

You can look at some of the various components they have developed here:

Joomla! Framework · GitHub

https://git.io/JZZ5j

So, this is the end of our What is OOP? section. I hope that you now understand what the phrase means and have perhaps even had a chance to peruse some of the code bases suggested so you have an understanding of what object-oriented PHP looks like. Maybe you've even been inspired to kick the tyres on a new project or even have a go at rolling your own. I've heard it said that every PHP developer has an MVC framework in them.

Now it's time to move on to looking at some technical details of object-oriented PHP.