DEV Community

Filipe Silva
Filipe Silva

Posted on

The PHP Criticism You've Never Actually Thought Through

TL;DR — I've been writing PHP for 15 years. I've tried Ruby, Groovy, and Java. I came back each time. This article goes through the serious criticisms of PHP — stdlib inconsistency, the stateless model, no real async — and where each one actually holds up, and where it doesn't.

I've been writing PHP for over 15 years. I've tried Ruby, Groovy, and Java — not out of curiosity, but because I genuinely questioned whether PHP was the right tool. I came back each time. Not out of habit, but because the arguments against PHP rarely survive contact with reality.

Let me go through the serious ones. And where PHP genuinely falls short, I'll say so.


First, some context most critics skip

The people who say PHP can't evolve stopped paying attention around 2005. The language kept moving without them.

PHP was created in 1994 by Rasmus Lerdorf. It didn't start as a programming language — it was a set of scripts to monitor visits to his online résumé. Built to solve a real problem, not designed by a committee with an architectural vision.

Critics use this against it: "No coherent design from the start." Fair. Growing organically has costs. But what followed was not stagnation — it was sustained evolution over three decades.

PHP 3.0 gave the language a proper modular foundation. PHP 4 brought the Zend Engine and the first real object-oriented support. PHP 5 made OOP actually usable — abstract classes, interfaces, exceptions, PDO. These weren't small updates. They were the language growing up.

PHP 7 was the version that changed things for me personally. Performance roughly doubled over 5.6. Memory consumption dropped. Scalar type declarations arrived. For the first time I could apply design patterns and architectural concepts — DDD, hexagonal architecture, proper interfaces — without fighting the language to do it. PHP 7.4 in particular felt like a turning point: typed properties, arrow functions, a language that finally matched the way I wanted to think about code.

PHP 8 continued from there — JIT compilation, union types, match expressions, attributes, named arguments. PHP 8.3 and 8.4 added typed class constants, readonly improvements, property hooks. The people who say PHP can't evolve stopped paying attention around 2005. The language kept moving without them.

The stdlib is inconsistent. Yes. But that's not the argument you think it is.

The inconsistencies are being removed, version by version. That's the cost of scale, and PHP pays it responsibly.

The standard library grew alongside the language — functions added at different times, by different contributors, with different conventions. The result is real: inconsistent naming, parameter ordering that flips between functions. needle before haystack in some, the reverse in others.

Some defend this by pointing to IDEs. I won't — that's pointing to a workaround, not answering the criticism. The real argument is simpler: the inconsistencies are being removed, version by version. Slowly — because PHP takes backwards compatibility seriously. A significant portion of the web runs on PHP. Breaking it carelessly is not an option. That's the cost of scale, and PHP pays it responsibly.

The share-nothing model is a limitation. It's also a structural guarantee.

The stateless model doesn't make you a better developer. It removes one category of mistake from the table by design.

PHP's execution model is stateless by default — each request starts fresh, no shared memory between them. The performance cost is real. JIT and caching address most of it in practice. But the cost exists.

What rarely gets mentioned is what you get in return. Stateless execution makes an entire class of memory problems structurally harder to produce. I've had a Groovy application stop completely because the JVM held on to state it should have released. Managing long-lived state is genuinely hard. The stateless model removes one category of mistake from the table by design.

A PHP setup is also notably lighter than a JVM or Node runtime. In environments where infrastructure costs matter — and they usually do — that's not a small detail.

No threads, no real async. Here's where I'll be honest.

Knowing where your tool's boundaries are is part of using it well.

PHP doesn't have native threads or true async execution. Fibers, added in PHP 8.1, are cooperative — not parallel. This is a real limitation.

If you're building long-running workers that need shared state and true parallelism — background processors, event-driven services, persistent connections — PHP is not the right tool. I'd use Java. Threads, shared state, long-lived processes: that's Java's territory.

But that's a specific problem. For web applications — APIs, sites, request-response cycles — native threads rarely come up. Apache manages concurrent connections. Queues handle background work. Most applications that think they need threads are actually describing an infrastructure problem. PHP delegates concurrency to the layer better suited to handle it. That's not a gap — that's a boundary. Knowing where your tool's boundaries are is part of using it well.

Java doesn't dominate the web. Nobody calls it dead.

PHP outlasted languages that came specifically to replace it.

Java is mature, strongly typed, has a massive ecosystem. By most objective measures it's an excellent language for web development. It never dominated the web the way PHP has. Nobody eulogises it for that.

PHP outlasted languages that came specifically to replace it. Ruby on Rails had its moment — around 2005 to 2010 — when it felt like it might displace PHP entirely. It didn't. PHP is still here, still powering a significant share of the web, still getting faster with each major version.

I tried to leave

The language that gets mocked is not the language I use.

Ruby taught me that convention over configuration is a real productivity gain. Groovy showed me a more expressive JVM. Java gave me appreciation for strict typing in complex systems — and it's still my choice for long-running processes with shared state.

What brought me back wasn't sentiment. PHP kept getting better at what it's actually for. What I write today in PHP 8+ — strict types, PHPStan at maximum level, DDD with hexagonal architecture — looks nothing like what people picture when they say "PHP is bad." The language that gets mocked is not the language I use.

The actual problem

No compiler catches logic errors. You catch them by understanding the problem deeply.

Most PHP criticism conflates three things: the language, the infrastructure around it, and the code people write with it. A poorly written WordPress plugin is not evidence that PHP is bad. It's evidence that accessible languages attract developers at every level. That's not a flaw — that's what happens when a language is approachable.

The hardest bugs aren't type errors or concurrency issues. They're logic errors — misunderstood requirements, wrong abstractions, bad domain models. No compiler catches those. You catch them by understanding the problem deeply, regardless of what's on the left side of your shebang line.


Dead or not, PHP is the language I choose for my projects and teach with conviction. Thirty years in, it's still shipping. So am I.

Top comments (0)