Discuss your project

PHP Powerhouses: 10 Must Know PHP Features for Developers – PART 1

/* by Dharmesh Patel - September 6, 2024 */

This blog will showcase some excellent features of the PHP scripting language that can significantly improve your coding experience. By utilizing these features, you can write cleaner, more readable code. Let’s dive into the top 10 PHP features that can enhance your development process.

1. Readonly Properties

Readonly properties, introduced in PHP 8.1, allow you to define properties that can only be written once. This is useful for creating immutable objects where once a property is set, it cannot be changed. This can help ensure data integrity and reduce bugs in your code.

Here’s a quick example of how to use readonly properties in PHP:

class User {
    public readonly string $username;

    public function __construct(string $username) {
        $this->username = $username;
    }
}

$user = new User('dharmesh');
echo $user->username; // Outputs: dharmesh

// Trying to modify the readonly property will result in an error
$user->username = 'dharm'; // Error: Cannot modify readonly property

Readonly properties in PHP are particularly useful in scenarios where you want to ensure that certain values remain constant after they’ve been set. This is common in cases where an object’s state should not be altered once it has been initialized, promoting immutability in your code.

Benefits:

  1. Data Integrity: Readonly properties help protect the integrity of the data within your objects. Once set, the value cannot be tampered with, which is particularly important in secure and critical applications.
  2. Simplified Debugging: Since the value of a readonly property can’t change after initialization, it reduces the complexity when debugging. You can be sure that the property value remains consistent throughout the object’s lifecycle.
  3. Thread Safety: In multi-threaded environments, readonly properties can prevent race conditions where multiple threads might try to modify the same property simultaneously.

Practical Scenario:

Imagine you’re building a financial application where each Transaction object has an amount and transactionId. Once these are set, they shouldn’t be changed, as altering them could lead to serious financial discrepancies.

Readonly properties in PHP bring a higher level of control and safety to your code, particularly when working with critical data that should remain constant after being set.

2. Enums

Enums (short for “Enumerations”) were introduced in PHP 8.1 and provide a way to define a set of named values that a property can have. They are useful for representing a fixed set of possible values in a type-safe way, which makes your code more readable, maintainable, and less prone to errors.

Basic Structure of Enums in PHP

An enum in PHP is defined using the enum keyword. Enums can have either pure values (which don’t contain any data) or backed values (which map to scalar values like strings or integers).

Pure Enums:

Pure enums are simple and don’t have any associated values. They are useful when you just need a named set of constants.

enum Status {
    case Pending;
    case InProgress;
    case Completed;
}

$status = Status::Pending;

if ($status === Status::Pending) {
    echo "The task is pending.";
}

Backed Enums:

Backed enums associate each case with a specific scalar value (like a string or an integer). This is useful when the enum needs to interface with other systems or when you need to persist these values, such as in a database.

enum OrderStatus: string {
    case Pending = 'pending';
    case Shipped = 'shipped';
    case Delivered = 'delivered';
    case Cancelled = 'cancelled';
}

$orderStatus = OrderStatus::Shipped;

echo $orderStatus->value; // Outputs: shipped

// You can also create an enum instance from a scalar value
$orderStatus = OrderStatus::from('delivered');

echo $orderStatus->value; // Outputs: delivered

Benefits:

  1. Type Safety: Enums ensure that only predefined values are used, preventing bugs caused by invalid values. If you try to use a value that isn’t part of the enum, you’ll get an error.
  2. Better Code Readability: Enums give names to constants, making the code more descriptive and easier to understand.
  3. Data Validation: Enums automatically validate that a property is set to one of the predefined values, reducing the need for additional validation logic.
  4. Integration with Databases: Backed enums are particularly useful when you need to store enum values in a database. You can easily map enum values to strings or integers that can be stored in a database column.

Practical Scenario: Payment Methods:

Suppose you’re building a payment processing system where users can choose different payment methods (Credit Card, Paypal, Bank Transfer). Enums can help enforce that only valid payment methods are selected.

Enums in PHP add a robust way to manage a fixed set of values, ensuring your code is both safer and easier to maintain. They are especially beneficial in scenarios where a variable can only hold a limited number of possible values, such as statuses, types, or categories.

3. Match Expressions

Match expressions, introduced in PHP 8.0, are a simpler and more efficient way to do what switch statements do. They let you compare values and return a result in one step. Match expressions are shorter, reduce errors, and allow for strict type comparison while directly returning the result.

Basic Structure of a Match Expression

$result = match($variable) {
    value1 => result1,
    value2 => result2,
    value3, value4 => result3, // Multiple values can be matched to the same result
    default => defaultResult, // Default case (optional)
};

Example: Basic Match Expression

$day = 'Monday';

$typeOfDay = match($day) {
    'Saturday', 'Sunday' => 'Weekend',
    'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday' => 'Weekday',
    default => 'Unknown', // Default case, if none of the cases match
};

echo $typeOfDay; // Outputs: Weekday

Match expressions in PHP can return not just simple values like strings or numbers, but also more complex data types like arrays, objects, or the results of functions. This flexibility allows match expressions to handle more detailed operations and return structured data based on the matched case.

class Animal {
    public function __construct(public $type, public $sound) {}
}

function getBirdDetails() {
    return ['type' => 'animal', 'sound' => 'tweet'];
}

$input = 'dog';

$result = match ($input) {
    'cat' => ['type' => 'animal', 'sound' => 'meow'],
    'dog' => new Animal('dog', 'bark'),
    'bird' => getBirdDetails(),
    default => null,
};

Benefits:

  1. Strict Comparison: Match expressions use strict comparison (===), so the types must match exactly. This helps avoid bugs that can happen with loose comparison in switch statements.
  2. Returning Values: Unlike switch statements, match expressions directly return a value, making them usable in assignments or as function arguments.
  3. No Fallthrough: In switch statements, you have to manually add a break to avoid fallthrough. Match expressions don’t require this, reducing errors.
  4. Cleaner and Simpler: Match expressions are more compact and easier to read, especially with many conditions.

Match expressions in PHP offer a cleaner and more powerful way to handle conditional logic. They make your code easier to read, reduce repetitive code, and ensure strict comparisons, leading to fewer errors. Whether you’re matching values, handling different cases, or returning complex data, match expressions can simplify and improve your PHP code.

4. Constructor Property Promotion

Constructor Property Promotion, introduced in PHP 8.0, simplifies the way you define and initialize class properties. It lets you declare and assign properties directly in the constructor, cutting down on repetitive code and making your classes shorter and easier to read.

Traditional Approach vs. Constructor Property Promotion

Traditional Approach:

In the traditional way, you have to declare class properties and then assign values to them inside the constructor. This often leads to repetitive code.

class User {
    private string $name;
    private int $age;

    public function __construct(string $name, int $age) {
        $this->name = $name;
        $this->age = $age;
    }
}

Constructor Property Promotion:

With Constructor Property Promotion, you can declare and initialize properties directly within the constructor’s parameter list, simplifying the code.

class User {
    public function __construct(
        private string $name,
        private int $age
    ) {}
}

How It Works

In the constructor signature:

  • The visibility keyword (public, protected, private) is used to define the property.
  • The property type and name are specified as usual.
  • PHP automatically creates the property and assigns the value passed during object creation.

Benefits:

  1. Less Code: Write and maintain less code, especially in classes with many properties.
  2. Improved Readability: The class is clearer because property declarations and their setup are all in the constructor.
  3. Reduced Errors: Fewer lines of code mean fewer opportunities for typos or mistakes, such as forgetting to assign a property.
  4. Better Refactoring: When refactoring, changes are easier to make since property declarations and assignments are in a single location.

Constructor Property Promotion in PHP 8.0 makes creating classes easier, especially with many properties. It cuts down on repetitive code, makes your code clearer, and helps avoid mistakes. This feature is useful for PHP developers working on anything from simple data objects to complex models, making code more elegant and easier to maintain.

5. Named Arguments

Named arguments, introduced in PHP 8.0, let you pass arguments to a function or method by specifying the parameter names. This makes your code clearer and more flexible by showing exactly which arguments are being used, regardless of their order.

function createUser(string $name, int $age, string $email = 'not_provided') {
    // Function body
}

createUser(name: 'John Doe', age: 30, email: '[email protected]');

Benefits:

  1. Improved Readability: Named arguments make it clear which values go to which parameters, making your code easier to read and less ambiguous.
  2. Flexibility with Parameter Order: You can pass arguments in any order, which is helpful when a function or method has many optional parameters.
  3. Reduced Error Potential: Named arguments reduce mistakes by clearly showing which value is assigned to which parameter, lowering the chance of passing arguments in the wrong order.

Example: Function with Optional Parameters

// Consider a function that generates a report with various options:

function generateReport(
    string $title,
    string $author,
    string $format = 'pdf',
    bool $includeSummary = false,
    bool $includeCharts = true
) {
    // Function body
}

// Calling with named arguments
generateReport(
    title: 'Annual Sales Report',
    author: 'Jane Smith',
    includeSummary: true,
    format: 'docx'
);

In this example, the format and includeSummary parameters are specified in a different order than their declaration, making the function call clearer and more flexible.

Limitations and Considerations

  1. Order of Parameters: Required parameters still need to be provided in the order they appear before any optional ones, even though named arguments allow flexibility in the order of optional parameters.
  2. Compatibility: Named arguments are only available in PHP 8.0 and later. They won’t work in older versions of PHP.
  3. Readability vs. Verbosity: Named arguments enhance readability, but using them too much where arguments are already clear can make the code more verbose.

Named arguments in PHP 8.0 are a great feature for enhancing code readability and flexibility. They let you specify arguments by name instead of position, making function and method calls clearer and easier to maintain, especially for functions with many parameters or optional values.


In next blog we will discuss and learn about Nullsafe Operator, Union Types, Array Unpacking with String Keys, JSON_THROW_ON_ERROR and JIT Compilation. Click to learn more