Upgrading to Maravelith 20.0.0

Maravelith 20.0.0 brings massive architectural optimizations, a custom high-performance Request hydration engine, deep dependency injection cache improvements, and an upgraded underlying ecosystem. Because we decoupled several heavy dependencies to reduce the baseline memory footprint and strictly aligned with modern PHP standards, there are manual updates required for existing applications.

Minimum Requirements

  • PHP: 8.2.0 or higher (PHP 8.3/8.4 recommended for maximum performance)
  • Symfony Components: Upgraded from 6.x to 7.4
  • Carbon: Upgraded from 2.x to 3.x
  • egulias/email-validator Updated to min 4.0
  • mockery/mockery Updated to min 1.6.12
  • phpunit/phpunit Updated to min 11.5   12.0
  • ext-bcmath Is now required

1. Updating Dependencies (composer.json)

To keep the core framework extremely lean, several packages were removed from the Maravelith kernel or strictly bumped to modern versions. You must now explicitly require them in your application’s composer.json to utilize routing, mailing, dates, and markdown features.

Add the following to your require block:

"league/commonmark": "^2.6",
"symfony/mailer": "^7.4",
"symfony/routing": "^7.4",
"tijsverkoyen/css-to-inline-styles": "^2.2.5"

brick/math was removed so add it ONLY if you need it.

After updating your composer.json, run:

composer update

2. Carbon 3 Migration (Action Required)

Maravelith 20 explicitly requires nesbot/carbon v3.11+. This is a major breaking change from Carbon 2 and will affect how your application calculates and returns dates:

Please review the Official Carbon 3 Migration Guide to audit your date logic.


3. Container & Architecture Breaking Changes

The underlying Service Container received a massive rewrite to support Two-Tier DI Caching, encapsulated cache loading, and OPcache protection.

  • The $with Property (Breaking Change): The Container’s protected $with property is now a flat array instead of a stack (list of arrays). If you have third-party packages or custom service providers that extend the container and use array_push($this->with, ...) or array_pop($this->with), you must refactor them to use the new stateless relay logic.
  • Removed Methods: Container::getCallbacksForType() has been removed entirely as dead code.
  • New Utility Methods: Container::isInInstances() and Container::isDevEnv() have been introduced to power framework runtime environment state checks.
  • Removed Properties & Unified Payload: The Request::$json property has been removed completely and fused directly into the primary Request::$request InputBag to eliminate boot-cycle assignment overhead and minimize memory footprint.
    • Breaking Change: Direct property access via $request->json is no longer supported from within macros. You must update your code to call the $request->json() method or access the $request->request bag directly.
    • Updated Methods: The setJson() method has been upgraded to set $this->request parameter bag only when isJson().
  • Deprecations: The following properties and methods are explicitly marked as @deprecated and their logic has been intrinsically shifted to the lazy-loaded Container memory cache:
    • Container::$abstractToTypeOfResolvingCallbacksEventsAsKeys (Use Container::getCachedFileContentsFromMemory() instead).
    • Container::setPrecompiledAutoWiringClassMethodParametersMap()
    • BoundMethod::setPrecompiledAutoWiringClassMethodParametersMap()
  • Unaliased Resolution Baseline (makeWithoutAlias): The container contract Illuminate\Contracts\Container\Container and concrete Container class both feature the makeWithoutAlias(string $abstract, array $parameters = []): mixed method. While originally partially backported in v10.73.3 to solve core boot loops, this is now an immutable architectural baseline in v20.0.0. ** Removed Internal Method (Container::resolveFinalAbstract): As signaled in v10.73.3, the internal bridge method final protected function resolveFinalAbstract() has been completely removed in v20.0.0. The container resolution layers now route cleanly and directly into resolveFinalString(), eliminating a redundant method stack frame..

4. High-Speed Request Hydration

Maravelith 20.x implements a custom Request capture engine, completely bypassing the legacy SymfonyRequest::createFromGlobals() to achieve Symfony 7.4 parity with maximum speed.

  • JSON Fast-Path: The framework reads early stream parsing for application/json payloads directly from php://input and includes native support for PHP 8.4’s \request_parse_body(). Action Required: If your application relied on intercepting or mutating $_POST, $_GET, or $_SERVER globals deep inside the bootstrap phase before the request was captured, ensure your logic is compatible with the new direct-read engine.
  • Request::duplicate() Removal: The custom overridden duplicate() method has been removed from the Request class. The framework now relies purely on Symfony’s native duplicate logic.
  • FileBag Scrubbing: Instance-based $this->filterFiles() logic was removed. File scrubbing is now handled by a strictly typed Request::cleanFiles() static method designed to scrub empty values directly during the initialize() phase.

5. HTTP Kernel & Middleware Lifecycle (Breaking Changes)

  • Identity-Gated Rebinding: The HTTP Kernel dispatcher loop now utilizes Container::isInInstances() to check object identity before performing an inline request re-registration, saving execution cycles unless a middleware layer has explicitly replaced the request reference.
  • Environment-Gated Middleware Disabling (Breaking Change): The framework’s ability to skip middleware execution via the middleware.disable container binding is now strictly restricted to development environments where maravel-framework-dev is active. This binding will be completely ignored in production environments.
  • Pipeline Allocation Short-Circuit: The HTTP Kernel (Kernel.php) and the Router (Router.php) now short-circuit execution pathways, completely bypassing the instantiation of the Pipeline component if the middleware stack is empty or disabled, allowing the request to drop straight into the router dispatch handler.

6. Console Commands Return Types (Symfony 7.4)

Because the underlying Symfony Console components were upgraded to 7.4, strict PHP return types are now enforced on console commands.

If you have custom Artisan commands extending Illuminate\Console\Command, you must update the execute method signature to return an int. Failure to do so will result in a PHP Fatal Error.

Old:

protected function execute(InputInterface $input, OutputInterface $output)
{
    // ...
    return 0;
}

New:

protected function execute(InputInterface $input, OutputInterface $output): int
{
    // ...
    return 0;
}

7. Immutable Route Action (Breaking Change)

Maravelith 20.x enforces strict route immutability during the execution of route-specific middleware stacks. This architecture completely closes the “Pipeline Bypass” security vulnerability, where a mid-flight middleware could dynamically rewrite a route’s target controller to an unauthorized endpoint after the initial security gates were compiled.

The Structural Change: Inside Router.php, the router now captures a Just-In-Time (JIT) snapshot of the resolved route action array ($lockedAction = $route->action) inside the active pipeline block. Right before invocation, the initial, validated action map is strictly restored via $route->setAction($lockedAction)->run().

Impact on Custom Middleware: Any route-level middleware that attempts to hot-swap or mutate the route target (uses, controller) mid-flight will have its mutations silently discarded right before execution.

Action Required (Routing & Header Versioning): If your application relies on custom headers (e.g., X-API-Version) or URL parameters to dynamically shift controllers or route destinations, this logic must now live exclusively in Global Middleware.

The Lifecycle Rule: Global middleware modifies the incoming Request object before the Router evaluates it. This allows the routing engine to inspect the finalized request criteria, match the correct endpoint, and compile the true, secure route-level middleware stack.


Deep Dive / Folder Comparison

For a detailed view of all changes, you can use a diff tool like Meld to compare your application folders directly against the source tree:


This site uses Just the Docs, a documentation theme for Jekyll.