Languages
PHP Development Company
PHP quietly runs a large share of the web, and the language of 2026 is not the one that earned the reputation. We write modern, typed, tested PHP, and we make inherited PHP estates safe to change again.
Overview
PHP is a server-side language built for one job and refined over three decades to do it well: take an HTTP request, talk to a database, return HTML or JSON, and get out of the way. Its execution model is the thing people underestimate. Every request starts from a clean slate and the process is torn down afterwards, so there is no shared mutable state between requests, no long-lived heap accumulating leaks, and no class of concurrency bug that dominates other server platforms. That "shared-nothing" design is why PHP applications are unusually simple to reason about and unusually easy to scale horizontally: any request can be served by any process on any machine, because none of them remember anything.
The version matters enormously, and this is where most opinions about PHP are out of date. PHP 8 introduced typed properties, union and intersection types, enums, readonly classes and properties, first-class attributes, constructor property promotion, match expressions, named arguments, fibers and a just-in-time compiler. Combined with strict type declarations and a static analyser such as PHPStan or Psalm running at a high level, modern PHP gives you type guarantees that are close to what people assume only compiled languages offer, and it is dramatically faster than the PHP 5 that formed the reputation. Code written in 2010 and code written today share little beyond the file extension.
At Yarqat we use PHP where it genuinely earns its place: content platforms, e-commerce, transactional business applications, admin back offices, and the integration layers that stitch payment, CRM, accounting and fulfilment systems together. We write it with strict types on, run static analysis in continuous integration, and deploy it on infrastructure that costs a fraction of the equivalent Java or .NET footprint. Because we operate what we ship, we design for the unglamorous production realities: OPcache and preloading configured properly, PHP-FPM worker counts sized against real memory use, queue workers that do not leak, and deploys that do not drop requests mid-flight.
The other half of our PHP work is inherited estates, and we take that seriously rather than treating it as a lead-in to a rewrite. A great many businesses are running on PHP written by people who left years ago, with no tests, no version control history worth the name, and a deploy process that involves a file transfer client and courage. Those systems usually still make money, which means the interesting question is not whether the code is embarrassing, it is what the cheapest safe path forward looks like. Sometimes that is modernising in place. Occasionally it is a targeted replacement of one part. Rarely, and only for specific reasons, it is a rewrite. We will tell you which one applies to you even when it is the less profitable answer for us.
Best for: Content platforms, e-commerce and business web applications that must ship quickly, host cheaply and stay maintainable for years, and organisations with an existing PHP estate that needs to be made safe to change again.
Why teams choose PHP
The lowest total cost to run
PHP hosts anywhere, from inexpensive shared hosting to autoscaling containers, and its per-process memory footprint is small. You are not paying for a heavyweight application server to sit warm just to answer a request, and the difference compounds across every environment you run, every month, for years.
Genuinely fast time to first release
Laravel and Symfony arrive with routing, an ORM, authentication, validation, queues, migrations and a scheduler already agreeing with each other. A working, secure application exists in days rather than weeks, which means user feedback and revenue arrive sooner and the expensive assumptions get tested earlier.
Horizontal scaling almost for free
The shared-nothing model means capacity is added by adding processes or containers, with no session affinity and no distributed state to coordinate in the application tier. Rolling deploys are trivial. This is a real architectural advantage that PHP rarely gets credit for.
A hireable, transferable ecosystem
Packagist carries a library for nearly every integration you will ever need, and PHP engineers are available in every timezone at every level. Your platform does not become an island, and handing it to another team, or bringing it in-house, is a realistic option rather than a threat.
Modern language guarantees when you want them
Strict types, enums, readonly classes and a static analyser at a high level give you a codebase where whole categories of null and type errors are caught in continuous integration rather than in production. Modern PHP reads like a typed language, and we write it that way as a matter of course.
Why businesses choose PHP
- You want a maintainable, secure web application in production quickly, without a large upfront platform investment or a heavyweight hosting footprint.
- Your ongoing hosting and maintenance budget matters, and you would rather spend it on features than on infrastructure that exists to satisfy a runtime.
- You are already on WordPress, Drupal, Magento or a bespoke PHP application, and you want it improved, secured and made safe to change rather than thrown away.
- You need a stack you can hire for and eventually hand over, not a niche technology that ties you permanently to one vendor or one person.
- You have an inherited PHP system nobody wants to touch, and you want an honest assessment of whether to modernise it, replace part of it, or replace all of it.
- You want the correctness discipline of a typed language applied to a stack that is cheap to run: strict types, static analysis and tests, enforced in continuous integration rather than in a coding standards document nobody reads.
What we build with PHP
The capabilities this technology is genuinely strong at, and what we most often build with it.
Bespoke web applications
Typed, tested Laravel or Symfony applications for portals, dashboards, booking systems, back offices and internal tools, built around your actual domain rather than bent onto an off-the-shelf product that nearly fits. Business rules live in plain PHP classes that can be tested without a web server, so they survive framework upgrades intact.
Server-rendered sites and applications
Fast, search-friendly rendering with Blade or Twig, progressively enhanced where interactivity earns it. HTML arrives ready to read, which both search engines and users on poor connections reward, and the front end stays a fraction of the size and complexity of a single-page application.
Content platforms, traditional and headless
WordPress and Drupal delivered as clean, version-controlled, reviewable code rather than a pile of plugins configured through an admin screen, either as conventional sites or as a headless content API feeding a React, Vue or Next.js front end from one editorial source of truth.
E-commerce and payments
Magento and bespoke commerce on Laravel or Symfony, with payment, tax, inventory and fulfilment integrations wired in and tested against the cases that actually cause support tickets: partial shipments, refunds, failed captures, currency rounding, and the same webhook arriving twice.
APIs and system integration
REST and GraphQL APIs, webhook processing and the connective tissue between CRMs, ERPs, accounting packages and payment providers, built with proper idempotency, retry with backoff, dead-letter handling and observability, because integration code fails in production far more often than application code does.
Legacy assessment and rescue
Bringing PHP 5 and early PHP 7 codebases up to a supported version, introducing version control discipline, a reproducible environment, characterisation tests around the paths that matter, types, static analysis and a real deployment pipeline. The aim is a system that is safe to change, not a system that is beautiful.
Version and framework upgrades
Moving applications onto supported PHP and framework releases, using automated refactoring tools such as Rector for the mechanical work and human judgement for the rest. Done incrementally, with tests in front of the risky parts, so the system keeps earning money throughout instead of being frozen for a quarter.
Security remediation
A focused pass over an inherited codebase for the classics: SQL built from request data, unescaped output, file uploads with no type or path checks, admin routes with no authorisation, secrets committed to the repository, and unpatched dependencies. On a neglected estate this is nearly always the first work worth doing.
Use cases
Membership and subscription platforms
Recurring billing, tiered access, a member portal and a queue-driven email lifecycle that survives a traffic spike because the slow work is not happening inside the web request. Payment provider integration built to handle the awkward cases rather than only the happy path.
Multi-editor content operations
Structured content, editorial workflow, roles and approvals, and a headless API serving both a marketing site and a mobile application from a single source of truth, so the content team works in one place and nobody is copying text between systems.
Business back offices and operations systems
Quotes, orders, stock across locations, approvals and reporting, integrating with an accounting package and exposing a secure API to trade customers. Unglamorous systems that a department depends on all day, where reliability and clarity matter far more than novelty.
Integration hubs
A PHP service acting as the connective layer between a website, a CRM, a warehouse system and a payment provider, with queued jobs, idempotent handlers and clear retry semantics so an upstream provider having a bad afternoon does not corrupt your data.
Legacy application rescue
A decade-old bespoke application taken from unversioned, untested and quietly insecure to a containerised, typed, continuously-tested codebase on a supported PHP version, that the existing team can extend again with confidence rather than dread.
Strangling a monolith gradually
Placing new functionality in a modern application alongside the old one, routing traffic path by path, and retiring the legacy system in slices. The business keeps running throughout and each step is individually reversible, which is the opposite of the big-bang rewrite risk profile.
When PHP is the right choice
- Right for content-driven and transactional web applications where you want to be in production quickly, host cheaply, and still have a maintainable codebase in five years. This is the bread and butter of the language and it is very good at it.
- Right when a mature framework already solves most of your problem: Laravel for product velocity, Symfony for long-lived enterprise systems with many teams, or WordPress and Drupal where editorial workflow and a content team are the real requirement.
- Right when hosting and staffing economics matter. PHP runs on effectively any hosting on earth, uses little memory per process, and has one of the deepest talent pools of any language, so your system will not become unmaintainable because one specialist moved on.
- Right when you already have a PHP estate that works. Continuing in a language your business already runs on, with the operational knowledge and hosting already in place, is very often the correct engineering decision even if it is not the exciting one.
- Right for server-rendered applications where HTML arriving ready to read is an advantage: search visibility, first-paint speed, and a far simpler front end than a single-page application would demand.
- Wrong for hard real-time and long-lived stateful connections at scale. WebSockets, live streaming and persistent socket handling fight the request-per-process model. Extensions like Swoole and libraries like ReactPHP exist and work, but if that is the core of your product, Node or Go is the better tool and we will say so.
- Wrong for CPU-bound computation, heavy data pipelines, scientific work or machine learning. The just-in-time compiler helps compute-heavy loops, but the ecosystem is not there and will not be. That work belongs in Python, Go, Rust or the JVM.
- Wrong when you need strong compile-time guarantees enforced by the toolchain rather than by discipline. PHP’s types are checked at runtime, and static analysis is opt-in. A well-run team gets most of the benefit, but a team without that discipline will not, and if that describes your situation honestly then a compiled language protects you better.
PHP: pros and cons
Strengths
- Exceptional time to market, because the mature frameworks have already solved routing, persistence, authentication, queues and migrations properly.
- Genuinely quick on PHP 8: OPcache, preloading and the just-in-time compiler put it firmly in the same performance conversation as its peers for typical database-bound web work.
- The shared-nothing request model eliminates a whole class of concurrency and memory-leak bugs and makes horizontal scaling close to linear.
- The cheapest mainstream stack to host and to staff, with hosting available literally everywhere and an unusually deep pool of engineers at every level.
- Mature frameworks with published long-term-support releases and predictable upgrade paths, so a system built today has a clear multi-year maintenance story.
- Excellent tooling for correctness: PHPStan and Psalm for static analysis, PHPUnit and Pest for testing, Rector for automated modernisation, and profilers that show you where the time actually goes.
Trade-offs
- The reputation problem is real, even though it is out of date, and it has practical consequences: your engineers may resist it, your investors may query it, and recruitment materials that say PHP will attract a different applicant pool than ones that say Go. We think the technical case for modern PHP is strong, but we will not pretend the perception cost is zero, because you may have to spend political capital defending the choice.
- The quality distribution in existing PHP code is genuinely worse than in most languages. Because PHP was many people’s first language and because it tolerated almost anything for years, the average inherited PHP codebase is in poorer condition than the average inherited Java or C# one: untyped, untested, with SQL built by string concatenation and business logic embedded in template files. That is a real cost you inherit, and it is why our rescue work exists.
- The request-per-process model makes real-time features awkward. WebSockets, live streams and persistent connections need an additional runtime such as Swoole or ReactPHP, or a separate service. It can be done, but it is working against the grain rather than with it.
- Concurrency and asynchronous work are second-class compared with Node or Go. Fibers improved things, but the honest pattern is still to push slow work onto queue workers rather than to handle it concurrently within a request.
- Type safety is opt-in and enforced at runtime, not by a compiler. Without strict types declared and static analysis gating merges, the guarantees quietly evaporate, and there is nothing in the language stopping a team from switching that discipline off under deadline pressure.
- The historical standard library is inconsistent, with irregular function naming and argument orders that are kept for backwards compatibility. It is a papercut rather than a wound, but it is a real friction for engineers arriving from more coherent languages.
- Version and dependency drift on neglected systems becomes expensive fast. An application stuck on an end-of-life PHP version cannot receive security patches, and the longer it sits there the larger the jump, because dependencies that would have upgraded one step at a time now all need replacing at once.
How we structure PHP systems
We build around a clear separation between the framework and your domain. Business rules live in plain, strictly typed PHP classes that neither know nor care whether the request arrived over HTTP, from the command line, or from a queue worker. Controllers and console commands are thin adapters that translate input, call into that core, and translate the result back out. This is not architectural purity for its own sake: it is what makes the interesting logic testable in isolation, and it is what makes a framework major-version upgrade an afternoon rather than a quarter, because the parts that matter were never tangled into framework internals.
On top of that we lean on the framework wherever it is genuinely good, because reinventing an ORM, a container or a migration system is a way to get the same features more slowly and with more bugs. Persistence goes through the ORM with explicit relationships and deliberate queries, wiring goes through the container so third-party services are swappable and mockable, every schema change ships as a versioned migration, and anything slow goes on a queue rather than in a request.
Strict types are declared in every file and static analysis runs at a high level in continuous integration, so a whole category of null, type and dead-code errors is caught before a human reviews the change. This is the single highest-value discipline in a modern PHP codebase and it costs almost nothing to maintain once established. It is also what allows a team to refactor confidently, because the analyser tells you what you broke.
The request-per-process model shapes the rest. Because nothing survives between requests, we design for state to live in the database, Redis or object storage, never in the process. That is what makes any node able to serve any request and rolling deploys uneventful. It also means anything long-running is a queue worker or a scheduled command rather than a background thread, which is a constraint but a clarifying one: the slow work is explicit, observable and retryable instead of hidden inside a request that occasionally times out.
Performance in the real world
The largest performance win in PHP is usually not in the language at all. OPcache keeps compiled bytecode resident so each request skips parsing and compiling entirely, and preloading takes it further by holding the framework and your classes in memory across requests. Configuring these properly is the first thing we check on any inherited system, and it is astonishing how often it has simply never been done. The just-in-time compiler in PHP 8 adds further gains on compute-heavy paths, but we are honest that for typical database-bound web work it is nearly irrelevant compared with your queries.
Because the truth is that PHP application performance is almost always database performance. The slow page is slow because a query lacks an index, because an ORM relationship is being lazily loaded inside a loop and issuing one query per row, because a report is scanning a table that has grown by two orders of magnitude since it was written, or because there is no pagination. We profile with real data volumes using tools like Blackfire or Xdebug rather than guessing, and we fix the query doing a thousand round trips before anyone mentions the interpreter.
The next layer is caching, applied deliberately rather than sprayed. Expensive reads go to Redis with a considered invalidation strategy, full-page caching goes in front of genuinely static content, and HTTP caching headers are set so the browser and any content delivery network do their share. Caching should be the thing that makes a fast system faster, not the plaster over a slow query, because a cached bad query is a bad query you can no longer see.
Finally we size the runtime for reality. PHP-FPM worker counts are set against the memory the application actually consumes per request, so the server neither sits idle with unused capacity nor starts swapping under load, which is the failure mode that turns a busy afternoon into an outage. Slow work is pushed onto queue workers so the web tier stays responsive, and workers are configured to restart periodically because long-lived PHP processes were never the design intent. Done properly, a PHP 8 application comfortably serves the traffic most businesses will ever see on modest and inexpensive infrastructure.
Security, in new code and in inherited code
For new work, modern frameworks close the classic vulnerabilities by default and our job is largely to ensure nothing reaches around them. Parameterised queries through the ORM prevent SQL injection, automatic output escaping in Blade and Twig prevents cross-site scripting, cross-site request forgery tokens are built in, and password hashing uses bcrypt or Argon2 out of the box. Danger lives almost entirely in the code that bypasses these defences for convenience, so raw SQL and unescaped output are rare, reviewed and justified, and every piece of user input is validated at the boundary rather than trusted because it came from your own form.
Inherited PHP is a different exercise, and on a neglected estate a security pass is usually the first work worth paying for. The pattern repeats: a query string built by concatenating request data, a file upload that accepts any extension and writes into the web root, an administrative route protected by nothing but obscurity, a password reset that can be replayed, session handling that predates anyone caring, and credentials committed to the repository years ago and never rotated. We find these systematically rather than hoping, close them in priority order, and tell you plainly what we found.
The supply chain matters as much as your own code. Composer dependencies are pinned, audited and kept patched, because the most common real-world breach is a neglected package rather than an exotic exploit. Secrets live in the environment or a managed store, never in the repository or an image. And the single most important security decision on an older system is the PHP version itself: an application on an end-of-life release cannot receive security patches at all, and no amount of careful application code compensates for an unpatchable runtime.
Around all of that we put the operational fundamentals: rate limiting on authentication and API endpoints, sensible session configuration, signed URLs for private files, audit trails where records must be accountable, and encrypted storage for sensitive fields. Under UK and European data protection obligations these are not optional refinements, and we treat them as part of the build rather than as a pre-launch scramble.
Scaling PHP, and the legacy estate question
PHP scales horizontally more easily than most stacks, precisely because of the shared-nothing model that its critics never mention. Each request is independent, so capacity comes from adding PHP-FPM processes or containers behind a load balancer and grows close to linearly. State lives in the database, Redis and a shared session store rather than in the application process, which means any node can serve any request, rolling deploys are straightforward, and there is no cluster coordination in the application tier to go wrong at the worst moment.
The limits that appear at scale are the shared resources: the database, the cache and slow third-party calls. We plan for those with read replicas where reporting competes with transactional load, deliberate indexing and query design, and asynchronous processing through queues so a traffic spike becomes a longer queue rather than a fallen-over site. Where genuine real-time or high-concurrency behaviour is needed we are honest about reaching for Swoole, a dedicated WebSocket service or a different runtime alongside the PHP application, rather than pretending PHP alone is the right tool for every part of the problem.
For inherited estates, the harder scaling question is usually organisational rather than technical: how do you keep a system growing when nobody dares change it. The answer is almost never a rewrite first. It is to make the existing system safe to change, get it onto a supported PHP version, and then grow deliberately. Once there are characterisation tests around the paths that matter and a deployment you can reverse, the codebase stops being a hostage situation and starts being an asset again, and that transition is usually far cheaper than people expect.
When a system genuinely does need to be replaced, we prefer to strangle rather than rewrite. New functionality is built in a modern application beside the old one, traffic is routed path by path, and the legacy system is retired in slices. The business keeps running throughout, each step is individually reversible, and value arrives continuously instead of in one terrifying release eighteen months out. Big-bang rewrites fail often enough, and expensively enough, that we treat proposing one as something requiring justification rather than something to be assumed.
PHP integrations & ecosystem
The technologies we most often pair with it. Each links to how we work with it.
How we build, rescue and hand over
For new systems we start narrow and ship early. One thin slice of the real application, deployed to a real environment behind continuous integration, tells us more in a week than a month of planning documents, because it proves the pipeline, the hosting and the assumptions all at once. From there it is short iterations against a prioritised list, with automated tests and static analysis gating every merge so the codebase stays releasable at all times rather than entering a two-week stabilisation phase before every release.
For inherited systems the order is different and deliberate. First, make it safe: get it into version control properly, build a reproducible local environment in Docker, and stand up a deployment you can reverse. Second, find out what it does: characterisation tests around the paths the business actually depends on, which is a different set from the paths people describe in meetings. Third, close the security holes. Fourth, get onto a supported PHP version, using automated refactoring for the mechanical parts. Only then do we discuss architecture, because every one of those earlier steps reduces risk and cost, and each one is valuable even if the eventual answer is replacement.
The modernise-or-rewrite decision is made with evidence rather than instinct. We look at how much of the code is actually exercised in production, how coupled the domain logic is to the presentation, whether the data model is sound underneath the code, how well the current system fits what the business now needs, and how much institutional knowledge exists. A codebase that is ugly but structurally sound and does the right things is a modernisation candidate. A codebase whose data model no longer matches the business, or whose behaviour nobody can determine, is a different conversation. We give you our reasoning, not just our conclusion, so you can disagree with it.
Handover is a first-class deliverable, not an afterthought. You get typed and documented code, a local environment that a new engineer can run on their first morning, a deployment pipeline anyone on your team can operate, and runbooks for the things that go wrong. The aim is that you are never held hostage by us: whether we stay involved for years or you take it in-house next quarter, the PHP we leave behind is code your own developers, or any competent PHP team, can pick up and extend.
The service behind it
Delivered throughCustom Software DevelopmentWhat we build with PHP
The disciplines this technology most often shows up in, from a first build to taking over and stabilising an existing one.
How we deliver
- 01
Discover
We map the system, the constraints and the business it serves, including the parts nobody documented.
Architecture brief
- 02
Architect
Decisions get made, written down and defended before a line of production code exists.
Decision records
- 03
Build
Short cycles against working software. You see progress in the product, not in a status deck.
Shipping increments
- 04
Operate
Monitoring, incident response and iteration. The system is alive, so the engagement is too.
Runbooks & SLOs
Weighing up PHP?
A short call with engineers who build in it and operate the result. If PHP is the wrong tool for what you are doing, we would rather tell you now than bill you later.
Industries we use PHP in
Domain knowledge changes what gets built. A few of the sectors we know before the first meeting.
Also in Languages
Why teams choose us for PHP
We operate what we build
This is not throw-it-over-the-wall consultancy. We run PHP in production ourselves, so we design for OPcache configuration, worker sizing, queue behaviour, zero-downtime deploys and on-call reality, not for a demo on a laptop with one user and ten rows of data.
We write modern PHP, deliberately
Strict types in every file, static analysis at a high level gating merges, tests around the logic that carries risk, and business rules kept out of framework internals. The result reads like a typed language and can be refactored with confidence, which is the whole point.
Honest about legacy, including when to do nothing
We do the unglamorous rescue work well, and we will tell you plainly whether your old codebase should be modernised in place, strangled gradually, or replaced. A rewrite is the more profitable recommendation for us and usually the wrong one for you, so we require evidence before proposing it.
Senior-led, no juniors learning on your budget
The people writing your PHP have shipped and rescued serious systems. What you are buying is judgement: about when PHP is right, when it is not, and which of the ten things wrong with an inherited codebase actually matter this quarter.
Built to be handed over
A reproducible environment, a pipeline your team can operate, documentation that reflects reality, and code written to be read by whoever comes next. Lock-in through obscurity is a business model we have chosen not to have.
Typical timeline
- 01
Discovery and assessment
One to two weeks. For new work: understanding the domain, agreeing the architecture and shipping one thin end-to-end feature to a real environment to prove the pipeline. For inherited systems: reading the code, the data model, the dependency and version position and the security posture, and producing a written recommendation with reasoning.
- 02
Make it safe
On legacy engagements this comes before anything else: version control, a reproducible Docker environment, a reversible deployment, characterisation tests around the paths the business depends on, and a security pass closing the obvious holes. Every step here is valuable regardless of what is decided about the architecture later.
- 03
Core build or upgrade
The main work. For new systems, features delivered in short iterations, each tested, typed and behind continuous integration, deployed continuously so progress is visible in a running system. For legacy, the move to a supported PHP and framework version, done incrementally with automated refactoring where it applies, so the system keeps earning throughout.
- 04
Hardening
Security review, performance profiling against realistic data volumes rather than seed data, OPcache and worker sizing against real memory use, edge-case handling, and observability tuning, before anyone depends on it in anger.
- 05
Launch, operate and hand over
Go live with monitoring and alerting in place, then documentation, a clean local setup and knowledge transfer so your team can own it. Where you want us to keep operating and extending it, we do that as an ongoing engagement rather than a dependency you cannot escape.
How pricing works
- Most engagements start with a paid discovery phase, and for inherited PHP that is genuinely the most valuable money you will spend. We read the codebase, examine the data model, check the PHP and dependency versions, look at what is actually exercised in production, and assess the security posture. The output is a written assessment and a recommendation with reasoning, including the option of doing very little. That assessment is yours whether or not you engage us further.
- For new build work we quote fixed-scope phases against a defined outcome, which suits a well-understood application, or a monthly senior engagement, which suits evolving products and ongoing platform work. We do not run an open-ended hourly meter, and we do not publish a day rate, because the cost is driven by the complexity of your domain and integrations rather than by the language or the page count.
- Rescue and modernisation work is scoped from the discovery assessment, and it is typically staged so that value arrives early: security remediation and a reversible deployment first, then the supported-version upgrade, then structural work. Each stage stands on its own, so you can stop after any of them and still be better off than when you started, which is deliberate.
- What drives cost is scope and integration complexity, not the runtime. A content-driven site is a very different figure from a transactional platform with billing, third-party integrations and regulatory obligations. On legacy work, the condition of what we inherit is the main variable, and we would rather tell you honestly after two weeks of assessment than guess optimistically before it.
- Third-party costs stay yours and unmarked-up. Hosting, managed databases, content delivery networks, monitoring, commercial plugins, theme or extension licences and any software licence fees are billed to your own accounts at cost. You hold the accounts, you see the real invoices, and nothing about your infrastructure spend depends on our continued involvement.
Hire PHP engineers
Need PHP capacity on your own team? We embed named senior engineers into your existing team (reporting to your leads, working in your rituals), so you add capacity without a hiring cycle.
Hire PHP engineersCommon questions
Is PHP not outdated and slow?
That reputation belongs to PHP 5, which reached end of life years ago. PHP 8 has typed properties, union types, enums, readonly classes, attributes and a just-in-time compiler, and it is dramatically faster than the version that formed the impression. With strict types and a static analyser it offers correctness guarantees close to what people assume only compiled languages provide. The perception gap is real and it may cost you something in recruitment or in a board conversation, so we would rather name it than pretend it does not exist. But technically, the language you may remember and the one we write share little beyond the name.
We have inherited an old PHP system. Should we modernise it or rewrite it?
Usually modernise, and we say that knowing a rewrite is the more profitable answer for us. Rewrites fail often, cost more than estimated, and freeze all business value for the duration while the old system still needs maintaining. Modernisation is a candidate when the data model is fundamentally sound, when the system still broadly does what the business needs, and when the domain logic can be untangled from the presentation, even if the code is ugly. A rewrite becomes the honest answer when the data model no longer matches how the business actually works, when nobody can determine what large parts of the code do and there is no institutional knowledge left, or when the technology is so far out of support that upgrading costs more than replacing. We assess against those criteria and show you our reasoning rather than just our conclusion.
What is the first thing you would do with a neglected PHP codebase?
Make it safe to change, before changing anything. That means proper version control, a reproducible local environment in Docker so any engineer can run it, and a deployment you can reverse. Then characterisation tests around the paths the business genuinely depends on, so you can tell whether a change broke something. Then a security pass, because neglected PHP nearly always has real vulnerabilities sitting in it. Only after all that do we discuss architecture, because every one of those steps reduces risk and cost, and every one of them retains its value even if the eventual decision is to replace the system.
Our application is on an unsupported PHP version. How serious is that?
Serious, and it gets worse the longer it waits. An end-of-life PHP release receives no security patches at all, so no amount of careful application code compensates. It also blocks you from upgrading libraries, which means your dependencies fall out of support too, and the eventual jump grows from a series of small steps into one very large one. It is often a compliance and insurance problem as much as a technical one. The upgrade is usually less painful than people fear, particularly with automated refactoring tools handling the mechanical changes, and it is the single highest-value piece of work available on most neglected estates.
Should we choose Laravel or Symfony?
Laravel favours developer velocity and a strong set of conventions, which suits products, startups and teams that want to move quickly with a well-trodden path. Symfony is more explicit and component-based with a stricter separation of concerns, which pays off in large, long-lived enterprise systems where several teams work in the same codebase and the system will outlive everyone currently on it. Both are excellent and both have long-term-support releases. We choose based on your longevity, team size and integration needs rather than fashion, and if you already have people fluent in one of them, that is a legitimate and often decisive argument.
Is PHP secure enough for a business application?
Yes, when built properly. Modern frameworks prevent SQL injection, cross-site scripting and request forgery by default and hash passwords correctly out of the box. The risk lies in code that reaches around those defences, so we keep raw queries and unescaped output rare and reviewed, validate every input at the boundary, audit Composer dependencies continuously, keep secrets out of the repository, and stay on patched, supported releases. On inherited systems the picture is often genuinely poor at the outset, which is exactly why a security pass is usually the first work we recommend.
Can PHP handle real-time features like chat or live updates?
It can, but the request-per-process model is not its natural home and we will not pretend otherwise. For light real-time needs, polling or a hosted push service is perfectly reasonable and much simpler than the alternatives. For heavier concurrency we reach for Swoole, ReactPHP, or a small dedicated WebSocket service alongside the PHP application, often written in Node. If real-time is the core of your product rather than a feature of it, we would recommend building that part on a runtime designed for it and keeping PHP for the parts it is good at.
How do you keep a PHP codebase from degrading over time?
With discipline enforced by tooling rather than by intention. Strict types declared in every file, a static analyser running at a high level and failing the build when it regresses, tests around the logic that carries real risk, and dependency and PHP version upgrades treated as routine scheduled work rather than emergencies. The reason PHP codebases have a reputation for degrading is that the language permits anything, so the guardrails have to come from your pipeline. Once they are in place they cost almost nothing to keep, and they are what allows anyone to refactor without fear.
Can you work alongside our existing developers?
Yes, and on inherited systems it is often the best arrangement, because your people hold context that no amount of code reading recovers. We will typically pair on the early rescue work so the knowledge transfers in both directions, and we are explicit about not building dependence on us: reproducible environments, documented pipelines and readable code exist precisely so your team can carry the system without us if and when you choose to.
Building on PHP?
Tell us what you are building and where it is stuck. A senior engineer reads it and gives you an honest read on whether PHP is the right fit for the problem, or what we would reach for instead.
- 01A senior engineer reads it. Not a form queue, and not an account manager.
- 02We reply either with questions or with a straight answer that we are not the right fit.
- 03If it looks like a fit, a technical call with the person who would actually run the delivery.
- 04Then scope, effort and risk in writing, before anyone signs anything.