DEV Community

Vincent Tommi
Vincent Tommi

Posted on

Fixing Laravel PHP 8.5 Deprecation Warnings: A Practical Dependency Debugging Guide

Upgrading PHP can expose compatibility problems in older Laravel projects. I recently encountered this while running a Laravel 10 application on PHP 8.5.4.

The application was working, but the terminal was filled with deprecation warnings such as:

PHP Deprecated: Monolog\Logger::addRecord():
Implicitly marking parameter $datetime as nullable is deprecated

and:

PHP Deprecated: Illuminate\Log\Logger::__construct():
Implicitly marking parameter $dispatcher as nullable is deprecated

At first, these errors looked like application-level problems. However, the real issue was an outdated dependency stack.

This article explains how I diagnosed and fixed the problem.

The Environment

The project was a Laravel application called samupos.

The initial environment was:

PHP 8.5.4
Laravel 10.25.1
Monolog 3.4.0
HTMLPurifier 4.16.0

The project had originally been built around an older PHP/Laravel ecosystem.

The first important lesson was:

A project can satisfy the PHP version declared in composer.json while still having dependencies that are incompatible with the actual PHP version installed on your machine.

  1. The Initial Error

When starting the Laravel development server, I received:

PHP Deprecated: Illuminate\Log\Logger::__construct():
Implicitly marking parameter $dispatcher as nullable is deprecated,
the explicit nullable type must be used instead

The warning pointed to:

vendor/laravel/framework/src/Illuminate/Log/Logger.php

I also encountered a similar warning from Monolog:

PHP Deprecated: Monolog\Logger::addRecord():
Implicitly marking parameter $datetime as nullable is deprecated,
the explicit nullable type must be used instead

The important thing here is that both warnings originated from the vendor directory.

That immediately suggested a dependency compatibility problem.

  1. Check the PHP Version

The first thing to verify was the PHP version:

php -v

The result was:

PHP 8.5.4 (cli)

This was important because newer PHP releases introduce deprecations that older frameworks and packages may not have accounted for.

  1. Make Sure Composer Is Running in the Correct Directory

Initially, Composer reported:

Composer could not find a composer.json file

The reason was simple: Composer was being executed from:

~/Desktop/Development

instead of the Laravel project directory.

The project was actually located at:

~/Desktop/Development/samupos

So I changed into the project directory:

cd ~/Desktop/Development/samupos

Then verified the project files:

ls

A Laravel project should contain files such as:

artisan
composer.json
composer.lock
app/
bootstrap/
config/
public/
resources/
routes/
vendor/

This is an easy mistake to make, but it is important because Composer searches for composer.json in the current working directory.

  1. Check the Laravel Version

Next, I checked the installed Laravel version:

composer show laravel/framework | head -15

The result showed:

versions : * v10.25.1

So the project was running Laravel 10.25.1.

  1. Check the Monolog Version

Next:

composer show monolog/monolog | head -15

The result was:

versions : * 3.4.0

This was another important clue.

The project was using an older Monolog release while running on PHP 8.5.

  1. Check Platform Requirements

Composer provides a useful command for detecting PHP and extension compatibility problems:

composer check-platform-reqs

Most requirements passed, but PHP itself failed because of an outdated package:

ezyang/htmlpurifier requires php
...
< 8.3.0

This meant that although the project's composer.json allowed PHP 8.5:

"php": "^8.1"

one of the installed dependencies did not support PHP 8.5.

This is a critical distinction.

The root project requirement said:

PHP >= 8.1 < 9.0

but individual packages can have much stricter requirements.

  1. Find Out Who Requires HTMLPurifier

Instead of guessing, I used Composer to find out which package depended on HTMLPurifier:

composer why ezyang/htmlpurifier

The result was:

phpoffice/phpspreadsheet 1.29.0 requires ezyang/htmlpurifier (^4.15)

So the dependency chain was:

PhpSpreadsheet

HTMLPurifier

PHP version restriction

This showed that HTMLPurifier was not a package I had directly installed. It was an indirect dependency.

  1. Inspect the Installed HTMLPurifier Version

I then checked:

composer show ezyang/htmlpurifier

The installed version was:

v4.16.0

Its PHP requirements included:

~8.0.0 || ~8.1.0 || ~8.2.0

Therefore PHP 8.5 was outside its declared supported range.

  1. Find All Packages Blocking PHP 8.5

Composer has another extremely useful command:

composer why-not php 8.5

The result identified several blockers:

ezyang/htmlpurifier v4.16.0
nette/schema v1.2.4
nette/utils v4.0.2

For example:

ezyang/htmlpurifier v4.16.0 requires PHP ... < 8.3

and:

nette/utils v4.0.2 requires PHP >=8.0 <8.4

This gave us a much clearer picture of the dependency problem.

  1. Don't Immediately Upgrade Laravel

At this point, it would have been tempting to upgrade the entire application from Laravel 10 to a newer major version.

However, that wasn't necessary yet.

The project was already using:

Laravel 10

and its composer.json contained:

"laravel/framework": "^10.23"

The ^10.23 constraint allows Composer to install newer Laravel 10 releases.

Therefore, before performing a major Laravel upgrade, I checked what Composer could already resolve.

  1. Use Composer's Dry Run

This was one of the most useful steps:

composer update --dry-run

The command doesn't actually modify the project. Instead, it shows what Composer would update.

The output showed that Composer could update Laravel from:

10.25.1

to:

10.50.3

It could also update:

HTMLPurifier 4.16.0 → 4.19.1
PhpSpreadsheet 1.29.0 → 1.30.0
Symfony 6.3.x → 6.4.x
Nette Utils 4.0.2 → 4.1.5
Nette Schema 1.2.4 → 1.3.6

There were also many other dependency updates.

This was exactly what we wanted to see.

It meant the existing Laravel 10 project could move forward without immediately performing a major framework migration.

  1. Back Up Composer Files

Before making the real changes, I backed up the dependency configuration:

cp composer.json composer.json.backup
cp composer.lock composer.lock.backup

This is a simple but useful precaution when performing a large dependency update.

  1. Update Dependencies

The actual update was performed with:

composer update -W

The -W option means:

--with-all-dependencies

This allows Composer to update dependencies of your direct dependencies when necessary.

This was important because the problem wasn't isolated to one package.

The dependency tree contained outdated packages throughout the application.

  1. Why We Didn't Edit the Vendor Files

One of the most important lessons from this debugging process is:

Do not manually edit files inside vendor/.

For example, it might be tempting to open:

vendor/laravel/framework/src/Illuminate/Log/Logger.php

and change the nullable parameter manually.

Similarly, you might modify:

vendor/monolog/monolog/src/Monolog/Logger.php

to silence the warning.

That is not the correct long-term solution.

The next time you run:

composer install

or:

composer update

Composer can overwrite those changes.

The correct approach is to update the dependency that contains the incompatible code.

  1. Test the Application Again

After updating the dependencies, I ran:

php artisan serve

And the result was:

INFO Server running on [http://127.0.0.1:8000].

Most importantly, the previous deprecation warning was gone.

There was no longer:

Illuminate\Log\Logger::__construct():
Implicitly marking parameter $dispatcher as nullable is deprecated

The application started normally.

  1. Verify Platform Requirements

After updating the packages, the next step is to run:

composer check-platform-reqs

This verifies that the installed dependencies are compatible with the PHP version and required PHP extensions.

It is a good idea to run this after a major dependency update.

  1. Check for Security Vulnerabilities

During the dependency update, Composer reported:

Found 92 security vulnerability advisories affecting 22 packages.

That is something that should not be ignored.

The next command to run is:

composer audit

This provides more information about the affected packages and available updates.

Dependency maintenance isn't only about eliminating errors and warnings. Security vulnerabilities are equally important.

  1. Useful Composer Commands for Debugging

Here are some Composer commands that proved particularly useful during this process.

Check installed package
composer show package/name

Example:

composer show monolog/monolog
Find out why a package is installed
composer why package/name

Example:

composer why ezyang/htmlpurifier
Find what blocks a PHP version
composer why-not php 8.5
Check platform requirements
composer check-platform-reqs
See available updates
composer outdated
Preview an update
composer update --dry-run
Update dependencies
composer update -W
Check security vulnerabilities
composer audit

These commands are extremely useful when debugging Laravel dependency problems.

Conclusion

The original problem wasn't caused by the Laravel application code itself.

The underlying problem was an outdated dependency tree running on a much newer PHP version.

The environment looked like this:

PHP 8.5.4

Laravel 10.25.1

Monolog 3.4.0

HTMLPurifier 4.16.0

PHP compatibility/deprecation problems

After updating the dependencies:

PHP 8.5.4

Updated Laravel 10 dependencies

Updated Monolog

Updated HTMLPurifier

Compatible dependency tree

Laravel application starts normally

The biggest lesson is simple:

When PHP starts reporting deprecation warnings from the vendor directory, don't immediately edit the vendor files. Investigate the dependency versions and let Composer resolve the compatibility problem.

Commands such as:

composer why
composer why-not
composer outdated
composer update --dry-run
composer check-platform-reqs
composer audit

can turn what looks like a mysterious Laravel error into a traceable dependency problem.

Top comments (0)