An existing PHP application can remain valuable even when changing it has become uncomfortable. A broken integration, unsupported dependency or fragile deployment does not automatically justify a rewrite. I start by identifying the behaviour the business relies on and the smallest change that can improve it without disturbing unrelated workflows.
The intended business result is a controlled path from a specific problem to a verified release. Tests record the behaviour being preserved, dependency checks expose compatibility constraints, and a release plan separates code rollback from data recovery. This reduces uncertainty; it does not make a legacy system risk-free.
Development and modernization scope
The service covers PHP application maintenance, integration work, runtime upgrades and incremental refactoring. Depending on the repository, that may mean plain PHP, Laravel or Symfony. Framework replacement is a separate decision, not the default answer to an unfamiliar codebase.
An initial review covers the runtime, Composer lock file, database access, uploads, scheduled tasks and external services. I identify an acceptance criterion for the proposed work: a request returns the expected result, a failed provider call is recoverable, or an upgrade preserves a documented workflow. Performance targets require measurements rather than assumptions about newer PHP versions.
A real regression test from DigiSpace
DigiSpace's service search demonstrates a small but meaningful boundary. The public catalogue should show a matching categorized service, not an internal package feature that has no category. HeaderSearchTest creates both records with Service::create(), requests /uk/service-search?search=laravel, then asserts that the first title appears and the orphaned title does not.
This is not an invented Service::factory() example. The test uses the repository's public-site fixture setup and an isolated test database. It provides evidence about that search behaviour only; it does not establish coverage of every integration or admin action. The business connection is direct: internal catalogue data must not become a misleading customer-facing search result.
Choose the smallest useful intervention
An in-place dependency update is often enough when the architecture still serves the product. If one workflow is tightly coupled, an adapter can isolate it before replacement. A full rewrite may be justified when the product itself is changing, but requires an explicit migration and support budget.
The PHP migration guide separates new features, incompatibilities and deprecations. It is a starting point for the relevant upgrade step, not a checklist for every older runtime. For gradual replacement, Martin Fowler's Strangler Fig explanation provides a useful comparison with a single cutover.
When this is not the right solution
Custom PHP work is unnecessary when configuration of a maintained product solves the problem. A project with no reliable backup, no owner for business decisions and no safe test environment needs those foundations before broad refactoring. Language changes should also not be sold as a cure for an unmeasured database or network bottleneck.
Agree on a bounded first step
Read the DigiSpace PHP modernization analysis for the test and release details. Share the current runtime, one failing or costly workflow and the required compatibility constraints. I can then define a focused change, how it will be checked, and what remains outside that scope.