In the previous EvolvePHP post, I wrote about Evolve Audit.
Audit approaches an existing PHP application from the outside.
It asks:
“What can we learn about this codebase without running it?”
That is useful, but static evidence only tells part of the story.
At some point, modernization has to deal with the environment in which the application actually runs.
Which PHP version is active?
Are required extensions available?
Are important paths writable?
Are required environment variables present?
Do the assumptions in the project match the machine running it?
That is where I see Evolve Doctor fitting.
But there is an important distinction:
Doctor is not a button that declares an application “ready for modernization.”
Its job is to produce runtime and project diagnostics that help developers make that decision with better evidence.
Audit and Doctor answer different questions
I think of the two tools like this:
Evolve Audit
↓
"What does the application appear to contain?"
Evolve Doctor
↓
"What does this environment actually provide?"Audit reads source code and metadata without booting the target application.
Doctor performs explicitly configured diagnostic checks against the environment or project.
Together, they begin to give us two different perspectives:
Code evidence
+
Runtime evidence
↓
Better modernization decisionsNeither one should pretend to know more than it actually knows.
Start with the PHP runtime
The most obvious diagnostic is also one of the most useful:
Which PHP version is actually running?A project's composer.json might say one thing.
The server might be running another.
The deployment configuration might contain another assumption entirely.
Evolve Doctor currently includes a PHP version check that can verify the runtime against EvolvePHP's PHP 8.4 minimum.
The result is represented as a structured diagnostic rather than just arbitrary terminal text.
Conceptually:
[PASS] runtime.php.version: ...or:
[FAIL] runtime.php.version: ...
Remediation: ...That distinction matters because I want diagnostics to be understandable both by humans and, eventually, tooling.
Required extensions matter too
A PHP application can satisfy its PHP version requirement and still fail immediately because an extension is missing.
Perhaps the project requires:
{
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-pdo": "*"
}
}The machine running the application needs to match those expectations.
Doctor can inspect top-level Composer ext-* requirements and check whether those extensions are loaded.
This sounds basic.
But basic environmental mismatches are exactly the kind of thing that can waste hours during migrations.
The useful question is not:
“Does Composer mention this extension?”
It is:
“Does the runtime I am standing in actually provide it?”
Doctor findings have meaning
The current Doctor model has three diagnostic states:
PASS
WARNING
FAILA warning is deliberately different from a failure.
Not every unusual condition should block work.
And a failed diagnostic should not necessarily be interpreted as:
“Modernization is impossible.”
It means:
“A check we explicitly configured has found a condition that currently does not satisfy its requirement.”
That is much more precise.
I want EvolvePHP tooling to avoid turning observations into dramatic conclusions.
The command is intentionally simple
The current EvolvePHP Core provides a Doctor CLI entry point:
vendor/bin/evolve doctorThe application skeleton also includes a configured:
php bin/evolve doctorstyle of application CLI composition through its bin/evolve entry point.
Today, the package-owned shell Doctor focuses on two things:
PHP runtime version
Composer-declared runtime extensionsIt is deliberately small.
That matters because I do not want to write this article as though Doctor already performs a complete infrastructure assessment.
It doesn't.
EvolvePHP 2 is still pre-release, and Doctor is an evolving diagnostic foundation.
There are already broader diagnostic primitives
The Doctor foundation also contains checks that applications can configure programmatically.
For example, required environment variables can be checked for presence.
Notice that word: presence.
Doctor should not print this:
DATABASE_PASSWORD=super-secret-passwordjust because it is performing diagnostics.
A diagnostic tool should not become a secret-leaking tool.
So environment-variable diagnostics care about whether the expected value exists, not exposing its contents.
There is also a writable-path diagnostic.
That can be useful for things like:
storage/
cache/
logs/
generated files/A deployment may look correct until the application tries to write somewhere the process cannot access.
Again, Doctor can identify the condition.
It does not automatically run chmod, rewrite permissions, or “fix” the server for you.
I think that separation is important.
Diagnosis should not silently mutate production
This is something Audit and Doctor share philosophically.
Suppose Doctor discovers:
storage/cache is not writableThere are two possible approaches.
One is:
“Don't worry, I fixed the permissions.”
The other is:
“This path failed the configured writability check. Here is the evidence and a remediation hint.”
I strongly prefer the second.
Automatic remediation sounds convenient until the tool changes a production environment incorrectly.
Diagnostics should help humans understand a system before they change it.
Doctor is not a compatibility certificate
This is another boundary worth making explicit.
A passing Doctor report does not currently prove:
Your Laravel application can migrate safely
Your dependencies are mutually compatible
Your application is persistent-worker safe
Your Bridge integration will work
Your database migration is safe
Your cutover will succeedThe current implementation does not run a Composer dependency solver.
It does not inspect every dependency's semantic-version compatibility.
It does not certify Bridge readiness.
It does not inspect routes.
And it does not certify persistent-worker safety.
A green Doctor report means the configured Doctor checks passed.
Nothing more.
That may sound conservative, but I think tooling becomes more trustworthy when its claims stay inside its evidence.
This becomes more interesting in real modernization work
Imagine an older production system.
Audit might tell us:
PHP constraint: legacy
Framework dependencies detected
Direct session coupling
Global state
Static properties
Several abandoned package declarations
Runtime-side-effect patternsThen environment diagnostics might tell us:
Actual PHP runtime
Loaded extensions
Missing runtime requirements
Required environment configuration
Writable deployment pathsNow we have a much stronger starting point than:
“The application looks old. Let's rewrite it.”
We can begin building an evidence report.
That report can inform what comes next.
The broader flow is becoming clearer
This is the modernization flow I keep coming back to with EvolvePHP:
Audit
↓
Understand the codebase
Doctor
↓
Understand runtime conditions
Adoption Plan
↓
Define what will change
Bridge
↓
Let old and new coexist
Modernize
↓
Move capability by capabilityEach step should answer a different question.
That is intentional.
I do not want one command pretending to understand source code, production infrastructure, business boundaries, data ownership, migration risk and cutover safety all at once.
Modernization is more complicated than that.
Doctor should grow through real evidence
There are more useful diagnostics I expect this area to explore over time.
Persistent-runtime requirements.
Bridge prerequisites.
Runtime isolation assumptions.
Environment and filesystem conditions.
Deployment-specific checks.
Potential production-readiness evidence.
But those should be added carefully and with clear definitions of what a passing check actually proves.
This is especially important as EvolvePHP's modernization tooling moves from an open-source foundation toward deeper commercial assessment use cases.
A diagnostic is only useful when we know exactly what was checked.
Modernization should begin with fewer assumptions
That is ultimately what Doctor is about for me.
A lot of modernization work begins with assumptions:
“The server probably supports it.”
“That extension should be installed.”
“The application should be able to write there.”
“The production environment is probably the same as staging.”
Those are cheap assumptions until they become expensive surprises.
I would rather turn them into checks.
Audit helps us understand what the code says.
Doctor helps us verify what the environment says.
Neither one modernizes the application for us.
They do something more fundamental first:
they replace assumptions with evidence.

No comments:
Post a Comment