New Deprecate methods using attributes in PHP 8.4

Video Lesson: Deprecate methods using attributes in PHP 8.4

Lesson Content

PHP 8.4 introduces a cleaner way to mark code as deprecated with the new #[Deprecated] attribute. Let's see how this improves a real-world scenario using a file uploader class.

Here’s how we would handle a deprecated implementation before PHP 8.4 by using a docblock and call to trigger_error():

<?php

declare(strict_types=1);

class FileUploader {
    /**
     * @deprecated Use uploadFile() which handles validation
     */
    public function upload(
        string $path,
    ): void {
        trigger_error(
            "Method FileUploader::upload() is deprecated, use uploadFile() instead",
            E_USER_DEPRECATED,
        );
        // Upload implementation
    }

    public function uploadFile(
        string $path,
    ): void {
        // Improved upload implementation with validation
    }
}

But with PHP 8.4, we can simplify this using the #[Deprecated] attribute. We can also pass along our custom message to this attribute with the message argument:

<?php

declare(strict_types=1);

class FileUploader {
    #[Deprecated(
        message: "Method FileUploader::upload() is deprecated, use uploadFile() instead",
    )]
    public function upload(
		    string $path,
    ): void 
        // Upload implementation
    }
    
    public function uploadFile(
        string $path,
    ): void {
        // Improved upload implementation with validation
    }
}

PHP will now automatically emit a generic deprecation warning whenever code calls this method! This means that we also no longer need to manually trigger the trigger_error() call. When we implement this code, we will still receive our deprecation notice:

<?php

require_once "FileUploader.php";

new FileUploader()->upload(".");

We can further enhance our code by specifying which version introduced the deprecation with the since argument. And because the since argument automatically adds a callout to include when the function was deprecated, we can also simplify our message:

<?php

declare(strict_types=1);

class FileUploader {
    #[Deprecated(
        message: "use uploadFile() instead",
        since: "2.0.0",
    )]
    public function upload(
        string $path,
    ): void {
        // Upload implementation
    }

    public function uploadFile(
        string $path,
    ): void {
        // Improved upload implementation with validation
    }
}

Now when someone uses the deprecated method, they'll see the deprecated version notice along with the message:

Method FileUploader::upload() is deprecated since 2.0.0, use uploadFile() instead

This attribute works with functions, class methods, class constants, and enums. It's not available for class declarations or function parameters though.

The #[Deprecated] attribute is also automatically detected by PHP's Reflection API, so methods like isDeprecated() will return true for attributed functions.