This is probably the most obvious question anyone can ask about EvolvePHP 2.
Why build another PHP framework?
Laravel already exists.
Symfony already exists.
Both are mature, actively developed, widely used, and capable of building serious applications.
Laravel gives developers an enormous amount out of the box: dependency injection, routing, queues, testing, authentication packages, Artisan, Octane, monitoring tools and a large ecosystem around the framework. Its current documentation describes it as a progressive framework that can grow from beginner projects to applications using dependency injection, queues, real-time events and other advanced capabilities.
Symfony approaches things differently. It provides both a full framework and a large collection of independent PHP components. Its Runtime component can decouple application bootstrapping from global state and support different runtime environments, while its wider component ecosystem covers HTTP, messaging, caching, configuration, validation, processes and much more.
So if the goal of EvolvePHP 2 was simply:
Build routing, controllers, dependency injection, database access and authentication.
Then I would probably tell myself to stop.
Those problems have already been solved.
And they have been solved very well.
I am not trying to build a Laravel replacement
This is an important distinction for me.
I don't want the motivation behind EvolvePHP to become:
Laravel does X, so EvolvePHP must have X.
Or:
Symfony has Y, so EvolvePHP needs a better Y.
That becomes an endless race that a small open-source framework is unlikely to win.
Laravel has years of development behind it, a huge ecosystem and a developer experience that has been refined over a long period.
Symfony has an extremely mature component architecture and is used directly and indirectly across a large part of the PHP ecosystem.
Trying to compete with either framework simply by having more features would not make much sense.
Instead, I started asking a different question:
What problems do I want EvolvePHP to care about more deeply?
That question changed the direction of the project.
Framework choice is rarely the biggest problem years later
When starting a new application, choosing a framework feels like one of the biggest technical decisions.
A few years later, that may no longer be the biggest problem.
The bigger problems become things like:
How do we upgrade this application safely?
Why is everything coupled together?
Can one part of the application scale separately?
Can we introduce a new architecture without rewriting everything?
Can we move to a persistent runtime safely?
What happens to request-specific state when the same worker handles another request?
How do we understand what is happening across the application?
How do we modernize an old system without stopping business for a year?
Those questions interest me more.
EvolvePHP 2 is being designed around the idea that software will change, and the framework should help the application survive that change.
That is the space I want EvolvePHP to explore.
A framework built around architectural evolution
A typical business application may begin very simply.
Imagine this:
Application
├── Users
├── Billing
├── Orders
├── Notifications
└── Reporting
There is nothing wrong with deploying this as one application.
In fact, for many projects, that is exactly what I would prefer.
I don't think every new application needs to start with microservices, message brokers and complicated infrastructure.
But I would like those five areas to have meaningful boundaries.
If Reporting becomes expensive three years later, maybe it should run separately.
If Notifications grows dramatically, perhaps it eventually belongs in a worker.
If Orders becomes a capability maintained by another team, perhaps it eventually becomes independently deployable.
The important question is:
How much of the original application do we have to destroy to make that change?
I want EvolvePHP to make the answer:
As little as reasonably possible.
That is why modularity is not just a folder structure in the EvolvePHP 2 architecture.
Modules are intended to represent actual application capabilities with explicit dependencies and lifecycle rules.
The application can remain a modular monolith for as long as that architecture continues to make sense.
Only when there is a real reason to distribute something should the deployment architecture become more complicated.
I don't want developers choosing microservices because they are afraid of the future
Sometimes teams over-engineer a new system because they don't trust themselves to change it later.
They think:
We might need independent scaling in three years, so let us build ten services now.
That can introduce problems long before the benefits appear.
Now there are network calls.
Service discovery.
More deployments.
Distributed tracing.
Retries.
Timeouts.
Partial failures.
Data ownership questions.
More infrastructure.
More operational complexity.
All for an application that may currently have a few hundred users.
I would rather have an architecture where developers can say:
We can keep this simple today because we have a reasonable path to change it tomorrow.
That is one of the long-term ideas behind EvolvePHP 2.
Start modular.
Stay together while staying together makes sense.
Extract selectively when there is evidence that separation is useful.
But new applications are only half the story
There is another problem that matters to me because I have seen it repeatedly in real software projects.
Existing systems.
Some business applications have been running for ten or fifteen years.
They may not be beautiful.
They may contain outdated dependencies.
They may have architecture decisions nobody would make today.
But they work.
Customers depend on them.
Employees depend on them.
Money moves through them.
And somewhere inside those applications are thousands of lines of business rules that took years to discover.
The usual technical answer is easy:
Rewrite it.
The business answer is much harder.
A rewrite means rebuilding not only the code developers understand, but also all the strange business behavior that nobody remembered to document.
Then while the rewrite is happening, the business does not stop changing.
New requirements continue arriving.
New integrations are needed.
Regulations change.
Customers continue reporting problems.
The old system keeps moving while the new system tries to catch it.
That can become dangerous.
What if modernization didn't require adoption on day one?
This is where EvolvePHP's direction becomes more interesting to me.
I want developers to eventually be able to get value from EvolvePHP without first deciding to rebuild their application using EvolvePHP.
That is a very different adoption model.
Imagine a Laravel application.
Or Symfony.
Or CakePHP.
Or Yii.
Or CodeIgniter.
Or even a completely custom PHP system built ten years ago.
Instead of saying:
Move the application to EvolvePHP.
the first question could be:
What part of this application actually needs to change?
That thinking led to the architecture behind Evolve Bridge.
Conceptually:
Existing Application
|
|
Evolve Bridge
|
|
New Capability
The existing system remains responsible for what it already owns.
A new capability can begin on the modern side.
Over time, additional capabilities can move if there is a reason to move them.
There is no rule saying the original framework must disappear.
In fact, if Laravel continues doing something well, there may be no reason to replace that part at all.
That is important.
Coexistence instead of framework wars
Framework discussions sometimes become strangely competitive.
Laravel versus Symfony.
Symfony versus something else.
PHP versus Python.
Monolith versus microservices.
I don't think software architecture works that cleanly.
Real systems are messy.
A company might have:
Laravel application
+
old PHP reporting system
+
WordPress customer portal
+
Python data service
+
Node.js notification service
That isn't unusual.
The question becomes how those systems can evolve without creating unnecessary risk.
So I want EvolvePHP to be comfortable existing beside other frameworks.
A Bridge adapter should not mean:
Laravel is bad. Replace it.
It should mean:
Here is a defined boundary where Laravel and EvolvePHP can cooperate.
Symfony itself demonstrates the value of interoperability through its component model. Many Symfony components can be installed independently instead of requiring developers to adopt the complete Symfony framework.
I think PHP benefits when tools cooperate rather than expecting every project to become an all-or-nothing framework decision.
Persistent runtimes changed one of my assumptions
Another area where I want EvolvePHP to think differently is runtime safety.
Traditional PHP gives developers something very convenient.
A request starts.
PHP runs.
The response finishes.
The request state disappears.
That lifecycle protects developers from many mistakes.
But long-running PHP runtimes change the situation.
Laravel has Octane, which keeps an application in memory and serves requests through application servers such as FrankenPHP, Swoole and RoadRunner. Laravel also provides scoped service bindings specifically for cases such as Octane requests and queue-worker jobs.
Symfony's Runtime component similarly exists to separate application bootstrapping from global state and allow applications to work with different runtime environments.
So persistent PHP itself is certainly not something unique to EvolvePHP.
The difference is that I want EvolvePHP's architecture to assume from the foundation that process reuse is dangerous unless isolation can be demonstrated.
That has led to the idea of an execution.
An execution could eventually be:
HTTP request
Queue message
Scheduled job
CLI command
Worker task
Each one gets isolated execution state.
When the execution finishes, cleanup must happen.
If cleanup succeeds, the process may be safe to reuse.
If cleanup fails and EvolvePHP cannot prove that state from the previous execution has been removed, then the framework should fail closed.
The process should be marked for quarantine rather than quietly accepting the next execution and hoping everything is fine.
For me, this is not primarily a performance feature.
It is an isolation feature.
Why does that matter?
Imagine a worker accidentally retains:
currentUser = Customer A
Then Customer B's request arrives.
Or imagine:
currentTenant = Company A
surviving into work being performed for Company B.
Now a small state-management mistake has become a security problem.
The framework cannot prevent every application bug.
But it can make certain dangerous patterns more difficult and give itself explicit cleanup responsibilities.
That is the type of framework behavior I want EvolvePHP 2 to take seriously.
Observability should not be something we remember later
There is another problem I have seen in applications.
Everything works until it doesn't.
Then somebody asks:
Why is this request slow?
And suddenly nobody really knows.
Was it the database?
An external API?
A specific module?
A queue?
A cache miss?
Authentication?
Some unexpected event listener?
The information might exist somewhere, but the application was never designed to expose it cleanly.
EvolvePHP is therefore being designed with an instrumentation boundary from the beginning.
The direction currently separates two ideas:
Evolve Insight for developer-focused local diagnostics.
Evolve Observe for production telemetry and OpenTelemetry integration.
I don't want Evolve Observe to become another Datadog or Grafana.
Those systems already exist.
The framework's responsibility should be to produce meaningful, vendor-neutral telemetry that developers can send to the tools they choose.
Again, the difference is not that Laravel or Symfony cannot be observed.
They absolutely can.
The difference is that I want observability to be part of EvolvePHP's architectural contracts rather than something we discover we need after the framework is already designed.
Another framework doesn't need another ORM to justify itself
This is probably one of the biggest changes in how I think about the project.
Years ago, if you asked me what made a PHP framework different, I might have compared:
routers,
ORM features,
templating,
helpers,
authentication,
session management.
Those things still matter.
Developers need a productive experience.
EvolvePHP eventually needs good routing, commands, testing utilities, database integrations and all the normal things expected from a modern framework.
But I don't think those should be its identity.
The identity should be closer to:
How safely can this application change over the next ten years?
Can I understand it?
Can I modularize it?
Can I upgrade it?
Can I run it differently?
Can I observe it?
Can I modernize only part of it?
Can I replace one capability without replacing everything?
Can I keep useful parts of an existing framework?
Can I discover when my runtime is unsafe?
Those are the questions I want EvolvePHP to answer.
There will still be cases where Laravel is the better choice
I want to be clear about this too.
If someone wants to build a standard SaaS application quickly, Laravel may be the obvious choice.
Its ecosystem is huge.
Its developer experience is excellent.
It has solutions for authentication, queues, billing, search, broadcasting, monitoring, testing, deployment and many other common requirements. The current Laravel documentation reflects how broad that ecosystem has become.
Likewise, if a project needs mature reusable PHP components, deep enterprise architecture and an established component ecosystem, Symfony is extremely difficult to ignore.
EvolvePHP does not become more credible by pretending those strengths don't exist.
In fact, I think acknowledging them makes the purpose of EvolvePHP clearer.
The goal isn't:
Choose EvolvePHP because Laravel and Symfony failed.
The goal is:
Choose EvolvePHP when the problems EvolvePHP prioritizes match the problems you expect your system to face.
So why another PHP framework?
Because I think there is still room to explore a framework where change itself is one of the main design constraints.
A framework where a new project can begin as a modular monolith without committing to permanent monolithic deployment.
A framework where existing applications can adopt new capabilities incrementally.
A framework that is comfortable cooperating with Laravel, Symfony and legacy PHP instead of demanding immediate replacement.
A framework where request, job and worker isolation are designed into the execution model.
A framework where failed cleanup means something.
A framework where observability is considered while the architecture is being created.
And eventually, a framework that can help developers answer:
What will break if I modernize this application?
That is enough reason for me to explore the idea.
It may not be the framework everyone needs.
It shouldn't try to be.
If EvolvePHP becomes useful to developers building long-lived modular applications, or to businesses trying to modernize systems they cannot afford to rewrite, then it has a reason to exist.
Laravel does not need to lose for EvolvePHP to succeed.
Symfony does not need to lose either.
PHP gets stronger when developers have more good ideas to choose from.
And EvolvePHP 2 is my attempt to contribute another one:
Build for change. Modernize without rewriting everything.

No comments:
Post a Comment