Wednesday, 30 September 2026

The Hidden Cost of Global State in PHP

The Hidden Cost of Global State in PHP

Global state is convenient.

That is why it survives.

A static singleton is easy to reach.

A global helper saves a few lines.

A shared container gives you access to almost anything.

Observability Is Not Logging

Observability Is Not Logging

A lot of systems say they have observability because they have logs.

They do not.

Logs are useful, sometimes essential, but they are only one part of understanding what a system is actually doing.

A system can produce thousands of log lines every minute and still be nearly impossible to diagnose when something goes wrong.

Thursday, 24 September 2026

Why Frameworks Should Help You Leave Them

Why Frameworks Should Help You Leave Them

A framework is supposed to help you build faster.

Routing, dependency injection, database access, queues, validation, authentication, caching, testing support—good frameworks remove huge amounts of repetitive work.

But there is another question I think framework design should take seriously:

What happens when the application eventually needs to move beyond the framework?

That might sound strange.

Wednesday, 23 September 2026

Can a PHP Application Be Designed for 10–20 Years of Change?

Can a PHP Application Be Designed for 10–20 Years of Change?

Most applications are not designed with a ten-year lifespan in mind.

They are built to solve the immediate problem.

Ship the product.

Get users.

Add features.

Then, somewhere along the way, the application becomes important enough that replacing it is no longer simple.

When Should a Modular Monolith Become Microservices?


A modular monolith can take you surprisingly far.

You can have clear business boundaries, independent modules, explicit contracts, good tests, background workers, queues, caching, horizontal scaling and strong deployment automation without splitting the application into separate services.

So at what point should one of those modules actually become a microservice?

Tuesday, 15 September 2026

EvolvePHP 2 Reaches Its First Alpha — The Framework Is Becoming Real

EvolvePHP 2 Reaches Its First Alpha — The Framework Is Becoming Real

This is a milestone I have been looking forward to for a while.

EvolvePHP 2.0.0-alpha.1 is officially out.

Until now, most of what I have written about EvolvePHP has focused on architecture: modular applications, execution isolation, long-running PHP, modernization, Bridge, service lifetimes and designing software for change.

With this release, those ideas are no longer only plans.

There is now a tagged, testable EvolvePHP 2 Alpha.

Microservices Are Not the Goal — Architectural Optionality Is

Microservices Are Not the Goal — Architectural Optionality Is

Microservices are often treated like the destination of a successful application.

Start with a monolith.

Grow.

Split into services.

Become “modern.”

I think that framing is backwards.

Microservices are not the goal.

Thursday, 10 September 2026

Long-Running PHP with EvolvePHP: Designing for Safe Reuse

Long-Running PHP with EvolvePHP: Designing for Safe Reuse

Long-running PHP is usually introduced as a performance story.

Boot the application once.

Keep the process alive.

Handle many requests or jobs.

Avoid repeating expensive initialization.

That can absolutely improve performance.

Wednesday, 9 September 2026

Evolving PHP: The Language Is Changing, and So Is the Way We Build With It

 

Evolving PHP: The Language Is Changing, and So Is the Way We Build With It  For a long time, PHP had a very clear operating model.  A request comes in.  PHP starts.  The application runs.  A response goes out.  The process ends.  That model shaped a lot of how PHP applications were designed.  State could live in convenient places because the process was short-lived.  Global variables were less dangerous than they would be in a long-running process.  Memory leaks were often masked by process termination.  Cleanup was less visible because the runtime effectively cleaned everything up for you.  That model worked very well.  But PHP is evolving.  And the way we design PHP applications needs to evolve with it.  PHP is no longer only a request-per-process language  The traditional PHP-FPM model is still valid and useful.  But it is no longer the only serious way to run PHP.  Today, PHP can also run in long-lived workers, application servers, queue consumers, schedulers, event-driven processes, and persistent runtimes.  That changes something fundamental.  The application may now live for:  1 request 100 requests 10,000 requests or hours of continuous work  That means old assumptions become more important.  What happens to request-specific state after the request finishes?  What happens to the current user?  The current tenant?  The database transaction?  Listeners?  Caches?  Telemetry context?  Temporary services?  A process that does not terminate forces us to answer questions that the traditional runtime often answered for us.  Performance is only part of the story  Persistent PHP is often discussed as a performance topic.  And performance does matter.  Booting the application once and reusing it can reduce repeated initialization work.  But I think the more interesting question is not:  “How much faster can PHP become?”  It is:  “What architectural assumptions change when the process survives?”  That is a much bigger question.

For a long time, PHP had a very clear operating model.

A request comes in.

PHP starts.

The application runs.

A response goes out.

The process ends.

That model shaped a lot of how PHP applications were designed.

Tuesday, 8 September 2026

Migrating Legacy PHP Applications to Modern Frameworks: What Actually Changes?

Migrating Legacy PHP Applications to Modern Frameworks: What Actually Changes?

Migrating a legacy PHP application to a modern framework can look deceptively simple from the outside.

You have an old application.

You choose Laravel, Symfony, or another modern framework.

You move the routes, controllers, models, and views.

Done.

Except that is rarely what really happens.

The difficult part of framework migration is not translating syntax.

Monday, 7 September 2026

Modernizing Legacy PHP Applications Using EvolvePHP

Modernizing Legacy PHP Applications Using EvolvePHP

Modernizing an old PHP application sounds straightforward until you actually open the codebase.

You may find an old framework, unsupported PHP version, direct SQL everywhere, global state, fragile authentication, outdated packages, and years of business logic spread across controllers, cron jobs, helpers, templates and database procedures.

At that point, the usual instinct is:

“We need to move this to something modern.”

But that still leaves the hardest question unanswered:

How do we modernize without breaking the business that already depends on it?

Friday, 4 September 2026

Modernizing Legacy PHP Applications: Pros and Cons

Modernizing Legacy PHP Applications: Pros and Cons

Modernizing a legacy PHP application usually sounds like an obvious win.

Newer PHP version.

Supported dependencies.

Better architecture.

Cleaner code.

Improved security.

Easier deployment.

All of that sounds good.

But modernization is not free.

Every improvement comes with cost, risk, and disruption.

Modernizing Legacy Applications in PHP: Considerations and Approaches

 

Modernizing Legacy Applications in PHP: Considerations and Approaches

Legacy PHP applications are everywhere.

Some are ten or fifteen years old. Some are running on unsupported PHP versions. Some use frameworks that are no longer maintained. Others were built without a framework at all.

And many of them are still doing real work every day.

That creates an uncomfortable situation.

The application needs to change, but changing it may be risky.

Thursday, 3 September 2026

Secure by Default Is Not Enough — Frameworks Need Security Evidence

Secure by Default Is Not Enough — Frameworks Need Security Evidence

“Secure by default” sounds reassuring.

It is also something almost every serious framework wants to say.

Use parameterized queries. Set sensible cookie defaults. Escape output. Protect forms from CSRF. Make unsafe configuration harder.

All of that matters.