Skip to content
Home » What’s New in PHP 8+: Features and Performance Gains

What’s New in PHP 8+: Features and Performance Gains

Key Takeaways

  • Introduction to PHP 8’s revolutionary features and performance improvements.
  • Detailed exploration of the Just-In-Time (JIT) Compiler for enhanced speed.
  • Insights into new attributes in PHP 8 for cleaner and more expressive code.
  • Understanding the significance of Union Types in PHP 8 for flexible type declarations.
  • The impact of Named Arguments on code readability and maintenance.
  • Exploration of Match Expressions for concise conditional structures.
  • The introduction of Constructor Property Promotion for streamlined class structures.
  • Overview of Nullsafe Operator’s role in simplifying null handling.
  • A look into Weak Maps and their use in memory management.
php 8
php 8

PHP 8.x marks a significant update in the PHP language, offering new features and performance gains that are essential for developers in the ever-evolving landscape of web development. This article delves into the key enhancements introduced in PHP 8 and its subsequent minor versions, providing concrete examples and use cases to demonstrate their practical applications.

Just-In-Time (JIT) Compiler in PHP 8

PHP 8 introduces the Just-In-Time (JIT) Compiler, a major feature aimed at improving the performance of PHP applications. Unlike the traditional PHP bytecode compilation process, the JIT compiler compiles parts of the code at runtime, converting it directly into machine code for faster execution. This can lead to significant performance improvements, especially in CPU-intensive tasks.

Example Use Case:
Consider a complex mathematical operation that is repeatedly executed in a PHP application. With JIT, this operation can be compiled into machine code, reducing the execution time on each subsequent run. This is particularly beneficial in scenarios like data analytics, where large datasets are processed.

New Attributes Syntax

PHP 8 introduces a cleaner and more expressive way to define attributes. Attributes in PHP are metadata for classes, methods, functions, parameters, and properties. They allow you to specify additional information in a structured way directly in the code.

Example:

#[ExampleAttribute]
class MyClass {
    #[ExampleAttribute]
    public function myFunction() {}
}

This new syntax is clearer and more concise compared to the previous method of using doc-comments for metadata.

Union Types

Union Types are a significant addition in PHP 8, allowing more than one type to be specified for function arguments, return types, and class properties. This introduces a level of flexibility in type declarations, enhancing the language’s capability to handle diverse data types.

Example:

function processInput(int|string $input): void {
    // Function implementation
}

In this example, the processInput function can accept either an integer or a string, offering greater flexibility.

Named Arguments

PHP 8 introduces Named Arguments, allowing developers to pass arguments to a function based on their names, rather than strictly following the order in which the parameters were defined. This enhances code readability and makes function calls more flexible.

Example:

function setCookie(string $name, int $expire, string $path) {}

setCookie(expire: 3600, name: "test_cookie", path: "/");

Here, arguments are passed out of order but are clearly identified by their names, improving clarity.

Match Expressions

The Match Expression in PHP 8 is a new feature that offers a more concise and readable alternative to switch statements. It acts similarly to a switch statement but with safer semantics and greater flexibility.

Example:

$result = match($input) {
    'apple' => 'fruit',
    'carrot' => 'vegetable',
    default => 'unknown',
};

In this example, the match expression is used to categorize an input, providing a clear and concise way to handle conditional logic.

Constructor Property Promotion

PHP 8 introduces Constructor Property Promotion, a feature that simplifies class constructor code. It allows developers to declare and initialize class properties in the constructor’s parameters, reducing boilerplate code.

Example:

class User {
    public function __construct(
        public string $name,
        public string $email
    ) {}
}

In this example, $name and $email are both declared and initialized in the constructor, streamlining the class structure.

Nullsafe Operator

The Nullsafe Operator in PHP 8 provides a streamlined way to execute methods or access properties on an object that may be null without the need for explicit null checking. This reduces the verbosity of null handling in PHP code.

Example:

$result = $object?->getValue();

Here, if $object is not null, getValue() is called. Otherwise, $result is set to null without causing an error, simplifying null handling.

Weak Maps

Weak Maps in PHP 8 offer a way to efficiently manage memory by holding references to objects without preventing those objects from being garbage collected. This is particularly useful in applications that require large or complex graphs of objects.

Example Use Case:
Consider a cache that stores user objects. With Weak Maps, when a user object is no longer in use elsewhere in the application, it can be automatically removed from the cache, freeing memory.

Saner String to Number Comparisons

PHP 8 addresses inconsistencies in string to number comparisons. In previous versions, strings were sometimes converted to numbers in non-intuitive ways during comparisons. PHP 8 improves this by using a more straightforward comparison strategy.

Example:

var_dump("8" == "08"); // PHP 7: true, PHP 8: false

In PHP 8, this comparison is false because the strings are different, leading to more predictable and safer behavior.

php8 2

Consistent Type Errors for Internal Functions

PHP 8 standardizes the error handling for internal functions. When a type error occurs, it consistently throws a TypeError exception. This harmonization makes error handling more predictable and manageable in PHP applications.

Example:

try {
    strlen([]);
} catch (TypeError $e) {
    echo "Type error: " . $e->getMessage();
}

In this code, passing an array to strlen() triggers a TypeError, which can be caught and handled gracefully.

Mixed Type

The mixed type is introduced in PHP 8, allowing for a parameter or return type to indicate that it accepts/returns multiple (but not all) types. This is useful in cases where a function needs to handle various types but can’t specify all of them individually.

Example:

function processMixed(mixed $input): mixed {
    return is_array($input) ? array_reverse($input) : $input;
}

In this function, processMixed can accept any type and return any type, making it versatile in handling different data types.

New String Functions

PHP 8 introduces several new string functions, which are helpful additions for string manipulation. These functions enhance the language’s capabilities in handling and processing strings.

Example:

$str = "   Hello World!   ";
echo str_starts_with($str, " Hello"); // false
echo str_ends_with($str, "!   "); // true
echo str_contains($str, "World"); // true

These functions (str_starts_with, str_ends_with, and str_contains) provide easy-to-use and intuitive ways to check the contents of strings.

Non-capturing Exception Catch Blocks

PHP 8.x allows for catch blocks to handle exceptions without the need to define a variable for the exception. This is particularly useful when the exception data is not needed in the catch block.

Example:

try {
    // code that might throw an exception
} catch (SpecificException) {
    echo "An error occurred.";
}

In this example, SpecificException is caught without the need to store it in a variable, simplifying the error handling process.

New str_contains() Function

PHP 8 introduces str_contains(), a straightforward and intuitive function for checking if a string contains a specific substring. This simplifies the process of string content checking.

Example:

$text = "This is a sample text.";
if (str_contains($text, "sample")) {
    echo "The text contains 'sample'.";
}

In this case, str_contains() efficiently checks if $text contains the substring “sample”.

New in_array() and array_search() Behaviors

PHP 8.x modifies the behaviors of in_array() and array_search() to be more strict and consistent. By default, these functions now use strict type checking, reducing the chances of unexpected behaviors due to type juggling.

Example:

$array = [0, '1', 2];
if (in_array(1, $array, true)) {
    echo "Found 1 as strict type";
}

The third parameter true enforces strict type checking, ensuring that ‘1’ as a string is not considered equal to 1 as an integer.

New Static Return Type

PHP 8 introduces the static return type for methods, allowing for a more accurate type hinting, especially in fluent interfaces and inheritance scenarios.

Example:

class ParentClass {
    public static function newInstance(): static {
        return new static();
    }
}

class ChildClass extends ParentClass {}

$child = ChildClass::newInstance();

In this example, newInstance() in ChildClass will return an instance of ChildClass due to the static return type.

php 8 3

New Value Error Exception

PHP 8.x introduces ValueError exception, which is thrown when a function receives an argument of the correct type but an invalid value. This improves error handling by providing a more specific exception type.

Example:

try {
    strlen(['not', 'a', 'string']);
} catch (ValueError $e) {
    echo "Invalid value provided";
}

ValueError is triggered by passing an array to strlen(), which expects a string.

New str_contains(), str_starts_with(), and str_ends_with() Functions

PHP 8 brings in three new string functions: str_contains(), str_starts_with(), and str_ends_with(), each providing a straightforward way to perform common string operations.

Examples:

  • str_contains() checks if a string contains a specific substring.
    if (str_contains('hello world', 'world')) {
      echo 'Contains "world"';
    }
    
  • str_starts_with() checks if a string starts with a specified substring.
    if (str_starts_with('hello world', 'hello')) {
      echo 'Starts with "hello"';
    }
    
  • str_ends_with() checks if a string ends with a specified substring.
    if (str_ends_with('hello world', 'world')) {
      echo 'Ends with "world"';
    }
    

    These functions greatly simplify common string checks, enhancing code readability and reducing complexity.

Trailing Commas in Parameter Lists

PHP 8.x extends the use of trailing commas to parameter lists and closure use lists, enhancing the readability and maintainability of the code, especially in version control systems. This feature allows for cleaner diffs when adding new parameters.

Example:

function exampleFunction(
    string $param1,
    int $param2,
    bool $param3,
) {
    // Function implementation
}

Here, a trailing comma is added after $param3, facilitating easier additions of new parameters in the future without modifying existing lines.

New Fetch Properties on Exception

In PHP 8.x, exceptions have been enhanced with the ability to fetch properties directly. This feature simplifies the process of extracting and handling information from exceptions.

Example:

try {
    // Some code that may throw an exception
} catch (Exception $e) {
    echo $e->file; // Directly accessing the file property
    echo $e->line; // Directly accessing the line property
}

Direct property access on the Exception object allows for more concise and readable error handling.

Explicit Octal Numeral Notation

PHP 8 introduces an explicit octal numeral notation. This change clarifies the intention of using an octal number, reducing the confusion and potential errors associated with the previous notation.

Example:

$octalNumber = 0o123;
echo $octalNumber; // Outputs the octal number as decimal

The 0o prefix clearly indicates that 123 is an octal number, enhancing code readability and preventing accidental misinterpretation.

New Stringable Interface

PHP 8.x adds the Stringable interface, which is automatically implemented by classes that define the __toString() method. This enables type-checking for classes that can be converted to strings.

Example:

class SampleClass implements Stringable {
    public function __toString(): string {
        return "SampleClass String Representation";
    }
}

function printString(Stringable $obj) {
    echo $obj;
}

printString(new SampleClass());

In this example, SampleClass implements Stringable, allowing it to be type-hinted in functions expecting a stringable object.

New fdiv() Function

PHP 8 introduces the fdiv() function, which performs a floating-point division while handling division by zero errors gracefully. This function returns INF, -INF, or NAN as appropriate, providing safer and more predictable behavior in mathematical operations.

Example:

$result = fdiv(10, 0); // Returns INF
$result = fdiv(-10, 0); // Returns -INF
$result = fdiv(0, 0); // Returns NAN

fdiv() ensures safe handling of divisions by zero, avoiding the traditional warnings or errors and instead returning special floating-point values.

Readonly Properties in PHP 8.1

PHP 8.1 introduces readonly properties, allowing class properties to be written once and then become immutable. This is particularly useful for value objects and data transfer objects where immutability is desired.

Example:

class UserInfo {
    public function __construct(
        public readonly string $username,
        public readonly string $email
    ) {}
}

$user = new UserInfo("johndoe", "john@example.com");
// $user->username = "newname"; // This would cause an error

The readonly keyword ensures that once a UserInfo object is constructed, its properties cannot be modified.

Fibers in PHP 8.1

PHP 8.1 introduces Fibers, a low-level mechanism for implementing lightweight cooperative multitasking. Fibers allow suspending and resuming execution in different parts of the code, which can be useful for implementing non-blocking I/O operations.

Example Use Case:
Fibers can be used to manage asynchronous tasks such as database queries or API calls without blocking the main execution flow, improving the application’s responsiveness.

php8 3

Enums in PHP 8.1

PHP 8.1 introduces enums (enumerations), which are a way of defining a set of named values. Enums are a significant addition for developers who require a fixed set of values that are semantically connected and don’t need to change.

Example:

enum Status: string {
    case Pending = 'pending';
    case Processing = 'processing';
    case Complete = 'complete';
}

Enums like Status provide a clear, concise way to work with such sets of values, enhancing code readability and reducing errors.

Readonly Classes in PHP 8.2

Expanding on readonly properties, PHP 8.2 introduces the concept of readonly classes. This feature makes all properties of a class readonly by default, ensuring immutability of the entire object.

Example:

readonly class Config {
    public function __construct(
        public string $environment,
        public string $version
    ) {}
}

$config = new Config("production", "1.0.0");
// $config->environment = "staging"; // This would cause an error

Readonly classes simplify the creation of immutable objects, making state management more predictable and secure.

Disjunctive Normal Form Types in PHP 8.2

PHP 8.2 introduces Disjunctive Normal Form (DNF) Types, enhancing the type system’s expressiveness. This allows for more complex type declarations combining union and intersection types.

Example:

function processInput(int|(string&Validatable) $input): void {
    // Function implementation
}

Here, processInput can accept either an int or a string that also implements the Validatable interface, offering sophisticated type-checking capabilities.

Read-Once Properties in PHP 8.3

PHP 8.3 is expected to introduce read-once properties, which are similar to readonly properties but can be read only once. This feature is beneficial for sensitive data that should be restricted after initial access.

Example Use Case:
Read-once properties can be used for handling sensitive information like one-time tokens or passwords, ensuring they are not accessible after initial use, thereby enhancing security.

Table: Comparative Overview of Key PHP 8.x Features

FeaturePHP 8.0PHP 8.1PHP 8.2PHP 8.3
JIT CompilerIntroducedEnhancedEnhancedEnhanced
New Attributes SyntaxIntroducedEnhancedEnhancedEnhanced
Union TypesIntroducedEnhancedEnhancedEnhanced
Named ArgumentsIntroduced
Match ExpressionsIntroducedEnhanced
Constructor Property PromoIntroduced
Nullsafe OperatorIntroduced
Readonly PropertiesIntroduced
FibersIntroduced
EnumsIntroduced
Readonly ClassesIntroduced
DNF TypesIntroduced
Read-Once PropertiesIntroduced

Conclusion

PHP 8.x series marks a significant evolution in the PHP language, introducing a slew of features and improvements that enhance performance, security, and developer productivity. From the groundbreaking Just-In-Time Compiler in PHP 8.0 to the read-once properties in PHP 8.3, each version has contributed to making PHP more robust and flexible for modern web development. The introduction of attributes, union types, named arguments, and match expressions in PHP 8.0 laid the groundwork for cleaner, more expressive code. PHP 8.1 continued this trend with readonly properties, fibers, and enums, further enhancing the language’s capabilities. PHP 8.2’s introduction of readonly classes and DNF Types shows a commitment to continuous improvement and modernization. As PHP continues to evolve, it solidifies its position as a top choice for web developers, offering a rich set of features that cater to the diverse needs of modern web applications.

Frequently Asked Questions

What are the performance benefits of the JIT Compiler in PHP 8.0?

The JIT Compiler in PHP 8.0 significantly enhances the performance of PHP applications, especially in CPU-intensive tasks and long-running processes. It compiles parts of the code at runtime into machine code, leading to faster execution and improved efficiency.

How do readonly properties in PHP 8.1 enhance code security?

Readonly properties in PHP 8.1 ensure that once a property is set, it cannot be modified. This immutability is crucial for value objects and data transfer objects, ensuring data integrity and preventing unintended side effects.

What are Fibers in PHP 8.1, and how do they improve asynchronous programming?

Fibers in PHP 8.1 provide a mechanism for implementing lightweight cooperative multitasking. They allow for suspending and resuming execution, which is useful for non-blocking I/O operations, improving the responsiveness and efficiency of applications.

Can you explain Enums in PHP 8.1 and their use cases?

Enums in PHP 8.1 allow for defining a set of named values, useful for scenarios where a fixed set of values is needed. They enhance code readability and reduce errors, ideal for defining states, types, or modes in an application.

How do Readonly Classes in PHP 8.2 differ from Readonly Properties?

Readonly classes in PHP 8.2 make all properties of the class readonly by default, ensuring the immutability of the entire object. In contrast, readonly properties apply immutability to individual properties within a class.

How do readonly properties impact the maintainability of PHP applications?

Readonly properties make state management more predictable by ensuring that properties cannot be modified after initialization, reducing the likelihood of bugs related to state changes and improving overall application maintainability.

Are there any backward compatibility concerns with migrating to PHP 8.x?

Migrating to PHP 8.x may involve some backward compatibility issues, particularly with the removal of deprecated features and changes in certain behaviors. It’s essential to thoroughly test applications and update codebases to align with the new features and improvements.