Legacy PHP

PHP 5.6 to PHP 8: what breaks, and four ways off

PHP 5.6 stopped getting fixes on 31 December 2018. If your system still runs on it, here is what fails when it meets PHP 8, in the order you will meet it, and the four realistic ways off.

By itmarkerz Technologies. Updated 30 October 2026.

What fails, in the order you will hit it

1. The application doesn’t start

PHP 7.0 removed the mysql, ereg, mssql and sybase_ct extensions, so the first page that touches the database dies. Search your code to see how much this covers.

grep -rnE "mysql_[a-z_]+\(|ereg(i)?(_replace)?\(|split\(|mcrypt_" --include="*.php" .

PHP 8 itself also rejects some old forms outright: create_function() and each() have gone, and a method named after its class is no longer a constructor. That last one matters in old PHP 4 style classes, because the object is simply created without the setup you expected.

2. Pages start, then stop part way through

Many fatal errors became exceptions in PHP 7, so custom error handlers may no longer fire. Calling a function with too few arguments throws from 7.1. Calling count() on something that can’t be counted warns from 7.2 and throws a TypeError from 8.0. Older code tends to do this on database results that came back empty, so it fails only when there is no data, which is the case nobody tested.

3. Everything appears to work, but some results are different

This is the expensive group, because nothing tells you. The main ones:

  • Loose comparison. In PHP 8, 0 == "foo" is false where it used to be true. Status checks and rule tables built on loose comparison can take a different branch.
  • Random numbers. From 7.1, rand(), shuffle() and array_rand() give different output for the same seed. That matters if you stored or relied on a seeded sequence.
  • Array iteration. foreach no longer moves the internal array pointer, and list() assigns in a different order, so code that depended on either behaves differently.
  • Database types. From 8.1, PDO returns native integers and floats for MySQL, so a strict comparison against a string starts to fail.
  • Case conversion. From 8.2, strtolower() and its relatives are ASCII-only, which changes results for accented names if your code relied on a locale.

4. Data you can’t read any more

Check for mcrypt, which left core in 7.2. Anything stored with it has to be decrypted and re-encrypted, and that is best planned while the old system can still read it. Also check character encoding: old systems on MySQL 5 are often latin1 at the database level with UTF-8 text inside. Our MySQL 5 to 8 checklist covers this.

For every step in between, see the full PHP upgrade matrix.

Four ways off

Four routes off PHP 5.6, and when each one fits
RouteWhat it meansFits whenMain risk
In-place upgradeSame code, new PHP. Fix what breaks.Small system, tidy code, current design is still fine.Silent behaviour changes, if there are no tests.
Staged upgradeMove through a midpoint such as 7.4, releasing as you go.Larger system that can’t freeze, with a team that can keep shipping.It runs long, and the midpoint becomes the new resting place.
Re-platformRebuild the application on a framework, keeping the data and every business rule.No framework or a dead one, but the system’s logic is correct and well used.Rules nobody wrote down get lost. Needs a side-by-side check.
RebuildDesign the system again, including changes to how it works.The workflows themselves are wrong, or the business has outgrown them.Largest scope, and the old system keeps needing care meanwhile.

Real timelines from our own projects

Published durations for this work are rare, so here are ours. Both are re-platforms, and they sit at very different ends of the range.

  • Loyalty-card system, two months. We had built the original on PHP 5.6 ourselves, so we already knew the code. We rebuilt it on Laravel, migrated the data, and kept every card, balance and rule.
  • Cabinet manufacturer, about eight months. Ordering, quoting, dealer portal and inventory moved from PHP 5.6 and MySQL 5.0 to Laravel 13, PHP 8.5, MySQL 8 and a new Next.js front end. We audited the code and schema first, validated data at every step of the migration, and checked each workflow against the old system running in parallel.

The gap between them isn’t only size. We already knew the loyalty system’s code, and the cabinet project’s scope also took in a database move and a new front end. Don’t read either as a benchmark. Our rewrite or upgrade comparison looks at what drove the difference, and the cost guide has our published prices.

Choosing: three questions

  1. Are the business rules correct? If yes, keep them, which rules out a redesign. If people work around the system every day, an upgrade only preserves the problem.
  2. Can you tell when something has broken? Without tests, a side-by-side run or people who can check results, an in-place upgrade is riskier than it looks.
  3. Can you hire for what you end up with? The cabinet manufacturer’s system was impossible to hire for. Moving to a supported runtime without moving off an unusual codebase may not solve that.

If you want someone else to run this, see our legacy PHP modernisation service. If your system is already Laravel, however old, Laravel rescue is likely a better starting point.

The two projects above

Questions

How long does moving from PHP 5.6 to PHP 8 take?

It depends on size, tests and how much the system must keep doing while it moves. Our two projects off PHP 5.6 took two months and about eight months, and both were re-platforms rather than in-place upgrades. We can't give you a meaningful number for your system without reading the code.

Can a tool do the migration for me?

Tools such as Rector and static analysers handle repetitive syntax changes well. They can't tell you whether a discount still calculates correctly after the comparison rules changed, or decide what happens to data encrypted with mcrypt. Use them for the routine part and spend the time you save on checking behaviour.

Should I go to PHP 8.5 or an earlier 8.x?

Aim for the latest version your framework and packages support. PHP 8.5 gets security fixes until 31 December 2029, the longest window available today. PHP 8.2 ends on 31 December 2026, so there is little reason to target it now.

More on legacy PHP

Tell us what your PHP 5.6 system does

We will read the code and tell you which of the four routes we would take, and why.

We reply within one business day (IST).