Skip to content
Efficience IT

Need an outside perspective on your project?

Contact us
FR
·8 min read·ArchitectureRecently updated

Taking Over a Poorly Coded Symfony App: The Method

By Louis-Arnaud Catoire

Updated on

Taking Over a Poorly Coded Symfony App: The Method

You have a Symfony application that runs, but every change is an ordeal. Only one developer claims to understand it, deployments are done by hand and cause a surge of anxiety, and nobody dares touch the core of the code for fear of breaking everything. The provider who built it has disappeared, no longer answers, or bills every fix at a premium. You inherit a codebase that nobody documented and whose access you do not even fully control.

This is an extremely common situation, and the good news is that it can be handled with a method. Contrary to intuition, the solution is almost never to throw everything away and start from scratch. This article describes the four-phase method we apply on missions to take over Symfony applications inherited from another provider: regain control, stabilize, then evolve with confidence.

Recognizing a Poorly Delivered Symfony Application

Before talking method, you need to be able to name the problem. A poorly delivered application cannot be recognized by its appearance, which may be perfectly polished on the user side, but by a series of engineering signals.

The first signal is knowledge concentrated in a single person, the famous bus factor of 1. If only one individual knows how the application works, you do not have an asset, you have a dependency. The second signal is the absence of automated tests on the core business logic: without a safety net, every change becomes Russian roulette, which explains the fear of touching the code. The third is manual deployment, long and stressful, with no repeatable procedure.

Then come the signs of neglected maintenance: a Symfony version past end of support (in French), exposed to unpatched vulnerabilities and blocking any version upgrade of the ecosystem, abandoned Composer dependencies, and an accumulation of technical debt (in French) that slows down every new feature. Taken individually, none of these signals is dramatic. Together, they describe an application you endure instead of steer.

Why a Complete Rewrite Is Almost Always a Mistake

Faced with this finding, the temptation is strong to erase everything and start over on a clean base. It is the most damaging mistake possible, and the reflex any serious provider should advise you against.

An application running in production, even a poorly coded one, contains years of implicit business rules. Special cases, fixes accumulated in response to real problems, behaviors your users expect: all of it is encoded in the existing code, often without documentation. A full rewrite starts from zero on that knowledge and reproduces the same bugs the first version had eventually fixed, for long months during which you pay a new team without delivering any new value to your clients.

In nearly all cases, modernizing a legacy PHP application without rewriting everything (in French) is less risky and faster to pay off. A rewrite is only justified when the effort of remediation truly exceeds the residual value of the application, which remains exceptional. Our approach always starts from what exists rather than from a blank page.

Phase 1: Regain Control Before Writing a Single Line

The first phase contains no code. It consists of taking full possession of your asset again, which is too often overlooked in the rush.

Recover Access and Ownership

Make a complete inventory of what you really own. The Git repository with its history, access to the servers or hosting, domain name management at the registrar, DNS records, application secrets, and the accounts of the third-party services the application uses: payment, email sending, storage, monitoring. It is not unusual for a client to discover at this stage that they do not own the domain their entire revenue depends on.

If the previous provider does not cooperate, remember that custom-built code belongs to you as long as your contract provides for an express assignment of rights, which you should check before any action. A formal written request, followed if needed by a formal notice, unlocks most situations. In parallel, a competent takeover provider can rebuild part of the access from what you already have.

Secure the Bare Minimum

Once you have access, you secure things immediately. The first action is to check that a recent, restorable backup exists, and to test it, because a backup that has never been restored is only a hypothesis. The second is secret rotation, especially if the relationship with the previous provider ended badly: change passwords, regenerate API keys, revoke access that is no longer needed. The third is a quick review of the application's security (in French), starting with the Symfony and PHP versions and exposure to known vulnerabilities.

Need support on your project?

Let's talk

Phase 2: The Technical Assessment

With control regained, you draw up an objective diagnosis. This phase looks like an audit, but with an operational goal: deciding what to do and in what order. It is lighter than a technical due diligence (in French) carried out in an acquisition context, where the aim is to value an asset, but it shares the same tools.

You start with static analysis. PHPStan (in French) configured at the highest level the codebase supports reveals the scale of typing and consistency problems in minutes. You then measure real automated test (in French) coverage, distinguishing tests that truly protect the business logic from decoration that tests nothing. You scan dependencies with the official composer audit command, identify the dead code (in French) that pollutes readability, and spot structural anti-patterns.

The decisive step is to cross-reference these findings with the Git history. A complex but stable module that nobody ever modifies is not an emergency. A complex module that is constantly reworked is a hot spot that concentrates risk. This prioritization by change frequency is what distinguishes a useful PHP code audit (in French) from a simple list of defects with no hierarchy.

Phase 3: Stabilize, Document, Reduce the Bus Factor

With a clear map, you stabilize before adding anything new. The goal of this phase is simple: being able to deploy with confidence.

You start by putting regression tests on the critical business flows, those where an outage directly hurts clients. These tests do not aim for perfect coverage, but for a safety net on what really matters. You then set up a minimal integration and deployment pipeline that runs static analysis and tests on every change and automates going to production, turning anxious deployment into a non-event.

In parallel, you tackle the bus factor by documenting the essentials. Technical documentation structured with the Diátaxis approach (in French) is enough to make the project transferable: general architecture, key decisions, operating procedures. The goal is not to write a novel, but to make sure a senior Symfony developer can deliver a nontrivial change in a few days, not after weeks of reverse engineering.

Phase 4: Evolve with Confidence

Once the codebase is under control, evolution becomes possible again without anxiety. The golden rule of this phase is to prioritize remediation by business value, not by technical perfection.

Not all imperfections in an inherited codebase are equal. Some truly slow down the roadmap or expose you to risk, others are merely inelegant and can wait. A good remediation plan sequences the work according to its impact on your business, and folds any version upgrades into a gradual migration guide (in French), relying on the official major version upgrade guide rather than a risky big leap. The reference Symfony release calendar serves as a compass to plan these upgrades without being caught out by end of support.

Evolution then happens incrementally, each delivery relying on the test safety net and the pipeline set up in the previous phase. You move from a defensive mode, where you avoid touching the code, to an offensive mode, where you create value again.

Choosing the Right Provider for the Takeover

Taking over an existing project is a different exercise from building a new application, and not every provider is comfortable with it. Choosing the right Symfony provider (in French) for this mission means watching for a few signals.

The first positive signal is a diagnostic stance. A serious partner wants to understand what exists before committing and offers a pre-audit. The opposite warning sign is the one who, before even reading a line of your code, recommends rewriting everything: that is often more comfortable for them than for you. The second criterion is the ability to place the takeover in the long term, through third-party application maintenance (in French) that secures your application beyond the initial diagnosis. A Symfony project takeover (in French) is not a one-off act, it is the start of a restored relationship of trust.

Conclusion

Inheriting a poorly coded Symfony application from another provider is not inevitable, and even less a sentence to rewrite everything. It is a problem handled with a method: regain control of your access, draw up an objective assessment, stabilize so you can deploy with confidence, then evolve by prioritizing value. Each of these phases reduces your dependency and increases the value of your asset.

The first step is always the simplest: getting a diagnosis. If you recognize your situation in this article, take the time for an initial conversation to scope the work. Our Symfony pre-audit (in French) identifies the real state of your application and the action plan to take it back in hand within a few days, with no commitment.

Have a project in mind?

Our team replies within 48 hours to look at your needs and suggest a suitable approach.

Contact us

Frequently asked questions

Custom-built code belongs to you if your service contract provides for an express assignment of rights, which is the first thing to check: under French law, without a written clause, the provider keeps its copyright. Start with a formal written request listing the expected items: the full Git repository, server access, third-party service credentials, and documentation. If there is no reply, a formal notice from your legal counsel unlocks most situations. In parallel, a takeover provider can often rebuild part of the access from what you already have, such as hosting access or a database backup.

Yes. A pre-audit of a few days scopes the real effort and avoids signing a fixed-scope engagement based on wrong assumptions. It measures the Symfony version, test coverage, technical debt, and vulnerabilities, then turns these findings into a quantified action plan. It is also a test of the provider itself: a serious partner offers a diagnosis before committing, while a partner to avoid promises a complete rewrite from the very first meeting.

The control recovery and assessment phase usually takes two to four weeks for a standard scope. Stabilization, meaning the first regression tests and a reliable deployment pipeline, then takes a few more weeks depending on the size of the codebase. The goal is not to fix everything at once, but to be able to deploy with confidence as early as possible.

A complete rewrite is only justified if the effort of remediation exceeds the residual value of the application, which is rare. An application running in production contains years of implicit business rules that a rewrite risks losing. In the vast majority of cases, gradual modernization is less risky and faster to pay off than starting from scratch.

Related articles