Upgrading to Maravel 20.0.0

Maravel 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 heavily decoupled the kernel to achieve sub-millisecond boot times and strictly aligned with modern PHP standards, there are a few 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 achieve a 0.37 MB memory footprint, several heavy dependencies were removed from the core Maravel Kernel or strictly bumped to modern versions. You must now explicitly require them in your application’s composer.json if you use those features.

Add the following to your require block:

"league/commonmark": "^2.6",
"nikic/fast-route": "^1.3",
"symfony/mailer": "^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)

Maravel 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 added to assist with fast-path runtime identity verification.
  • 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()

4. High-Speed Request Hydration

Maravel 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. Request Lifecycle & Pipeline (Breaking Changes)

  • Strict Request Injection: The core $app->run(), $app->handle(), $app->dispatch(), and $app->parseIncomingRequest() methods now enforce a strict LumenRequest parameter signature and typed returns.
  • $app->prepareRequest() Eliminated: The intermediate prepareRequest method has been entirely removed from the core application source to reduce call-stack overhead.
  • Identity-Gated Rebinding: Implemented an inline object reference identity check (!==) inside the request dispatcher closure. The framework completely bypasses redundant $this->instance(Request::class) re-bindings unless a middleware has explicitly replaced or duplicated the request pointer.
  • Environment-Gated Middleware Disabling (Breaking Change): The programmatic ability to skip middleware via the middleware.disable container binding is now strictly restricted to development environments where maravel-framework-dev is active. This binding is ignored in production configurations.
  • Pipeline Short-Circuiting: Introduced sendRequestThroughPipeline(). If the middleware array is empty or disabled, the application executes the target route closure directly—skipping the instantiation of the Pipeline component entirely to eliminate allocation overhead.
  • 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.

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;
}

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.