...

/

Working with the static Return Type

Working with the static Return Type

Learn about static return type methods in PHP 8.

Another potentially significant change seen in PHP 8 is that several methods are now declared static. If we are already using the classes and methods described here as direct object instances, then we do not have a problem.

The following methods are now declared as static:

  • tidy::repairString()

  • tidy::repairFile()

  • XMLReader::open()

  • XMLReader::xml()

The potential for a code break may occur if we override one of the classes mentioned previously. In this case, we must declare the overridden method as static.

Working with the static return type

The static keyword is used in several contexts in PHP. Its basic uses are beyond the scope of this discussion. In this section, we will focus on a new usage for static as a return data type.

Since static is considered a subtype of self, it can be used to widen the narrower return type of self. The static keyword cannot be used as a type hint, however, as it would violate the Liskov Substitution Principle. It would also confuse developers because static is already used in too many other contexts.

The most common use for this new return data type would be in classes that use the fluent interface. This a technique whereby an object method returns an instance of the current object state, thus allowing a chain of method calls to be used in a fluent (readable) manner. In the following example, note how the object builds an SQL SELECT statement:

<?php
require_once __DIR__ . '/src/Server/Autoload/Loader.php';
$loader = new \Server\Autoload\Loader();
use Php8\Sql\Select;
$start = "'2021-06-01'";
$end   = "'2021-12-31'";
$select = new Select();
echo $select->from('events')
           ->cols(['id', 'event_name', 'event_date'])
           ->limit(10)
           ->where('event_date', '>=', $start)
           ->where('AND', 'event_date', '<=', $end)
           ->render();
echo "\n";
?>
Generating an SQL SELECT query with PHP 8

Let’s get into the code.

  • In the Where.php file:

    • We must define a Where class that accepts an unlimited number of arguments to form an SQL WHERE clause. Note the return data type of static.

  • In the Select.php file:

    • Now, let’s define the main class, Select, which provides methods for building parts of an SQL SELECT statement. Again, notice that the methods shown all return the current class instance and have a return data type of static.

  • In the main.php file:

    • Finally, we must define a calling program that provides the values needed to build the SQL statement. Note that the echo statement uses the fluent interface to make programmatically creating the SQL statement much easier to follow.

This example doesn’t work in PHP 7, of course, because the static keyword is not available as a return data type. Next, let’s have a look at the extended use of the special ::class constant.

Extending the use of the ::class constant

The special ::class constant is an extremely useful construct in that it can silently expand into a full namespace plus a class name string. Understanding how it is used, as well as how its use has been extended in PHP 8, can save us lots of time. Its use can also make our code much more readable, especially if we’re dealing with lengthy namespaces and class names.

The special ::class constant is a combination of the scope resolution operator (::) and the class keyword. Unlike ::parent, ::self, and ::static, however, the ::class construct can be used outside a class definition. In a sense, the ::class construct is a sort of magic constant in that it causes the class it’s associated with to magically expand into its full namespace plus class name.

Before we get into how its use has been expanded in PHP 8, let’s have a look at its conventional usage.

Conventional ::class constant usage

The special ::class constant is frequently used in situations where we have a lengthy namespace and wish to not only save ourselves a lot of unneeded typing but also preserve the readability of our source code.

In this simple example, using the Php7\Image\Strategy namespace, we wish to create a list of strategy classes: