forked from https://github.com/symfony/symfony
c06a76c384
This PR was merged into the 5.3-dev branch.
Discussion
----------
[Runtime] a new component to decouple applications from global state
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | https://github.com/symfony/symfony-docs/pull/15081
Follow up of #36652, see discussion there.
What if we could decouple the bootstrapping logic of our apps from any global state?
This PR makes it possible via a new proposed `symfony/runtime` component.
The immediate benefit this provides is easier maintenance of Symfony apps: code that is currently shipped by recipes will be able to move to `vendor/`. Read the previous sentence twice, this is big :)
Check the following PR to see how far this goes: https://github.com/symfony/recipes/pull/787
The longer-term benefit is being able to run the exact same app under several runtimes: PHP-FPM, CLI, but also PHP-PM and similar. Thanks to the proposed interface, this benefit could span to any PHP apps; not only to apps using the Symfony HttpKernel/HttpFoundation components. This part could be moved to `symfony/contracts` in the future.
Performance-wise, I measured no significant difference with the current way of running apps.
RuntimeInterface
----------------
The core of this component is the `RuntimeInterface` which describes a high-order
runtime logic.
It is designed to be totally generic and able to run any application outside of
the global state in 6 steps:
1. the main entry point returns a callable that wraps the application;
2. this callable is passed to `RuntimeInterface::getResolver()`, which returns a
`ResolverInterface`; this resolver returns an array with the (potentially
decorated) callable at index 0, and all its resolved arguments at index 1;
3. the callable is invoked with its arguments; it returns an object that
represents the application;
4. that object is passed to `RuntimeInterface::getRunner()`, which returns a
`RunnerInterface`: an instance that knows how to "run" the object;
5. that instance is `run()` and returns the exit status code as `int`;
6. the PHP engine is exited with this status code.
This process is extremely flexible as it allows implementations of
`RuntimeInterface` to hook into any critical steps.
Autoloading
-----------
This package registers itself as a Composer plugin to generate a
`vendor/autoload_runtime.php` file. This file shall be required instead of the
usual `vendor/autoload.php` in front-controllers that leverage this component
and return a callable.
Before requiring the `vendor/autoload_runtime.php` file, set the
`$_SERVER['APP_RUNTIME']` variable to a class that implements `RuntimeInterface`
and that should be used to run the returned callable.
Alternatively, the class of the runtime can be defined in the `extra.runtime.class`
entry of the `composer.json` file.
A `SymfonyRuntime` is used by default. It knows the conventions to run
Symfony and native PHP applications.
Examples
--------
This `public/index.php` is a "Hello World" that handles a "name" query parameter:
```php
<?php
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
return function (array $request, array $context): void {
// $request holds keys "query", "body", "files" and "session",
// which map to $_GET, $_POST, $_FILES and &$_SESSION respectively
// $context maps to $_SERVER
$name = $request['query']['name'] ?? 'World';
$time = $context['REQUEST_TIME'];
echo sprintf('Hello %s, the current Unix timestamp is %s.', $name, $time);
};
```
This `bin/console.php` is a single-command "Hello World" application
(run `composer require symfony/console` before launching it):
```php
<?php
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
return function (Command $command) {
$command->addArgument('name', null, 'Who should I greet?', 'World');
return $command->setCode(function (InputInterface $input, OutputInterface $output) {
$name = $input->getArgument('name');
$output->writeln(sprintf('Hello <comment>%s</>', $name));
});
};
```
The `SymfonyRuntime` can resolve and handle many types related to the
`symfony/http-foundation` and `symfony/console` components.
Check its source code for more information.
Commits
-------
|
||
---|---|---|
.github | ||
src/Symfony | ||
.appveyor.yml | ||
.editorconfig | ||
.gitattributes | ||
.gitignore | ||
.php_cs.dist | ||
.travis.yml | ||
CHANGELOG-5.0.md | ||
CHANGELOG-5.1.md | ||
CHANGELOG-5.2.md | ||
CODE_OF_CONDUCT.md | ||
composer.json | ||
CONTRIBUTING.md | ||
CONTRIBUTORS.md | ||
LICENSE | ||
link | ||
phpunit | ||
phpunit.xml.dist | ||
psalm.xml | ||
README.md | ||
UPGRADE-5.0.md | ||
UPGRADE-5.1.md | ||
UPGRADE-5.2.md | ||
UPGRADE-5.3.md | ||
UPGRADE-6.0.md |
Symfony is a PHP framework for web and console applications and a set of reusable PHP components. Symfony is used by thousands of web applications (including BlaBlaCar.com and Spotify.com) and most of the popular PHP projects (including Drupal and Magento).
Installation
- Install Symfony with Composer (see requirements details).
- Symfony follows the semantic versioning strictly, publishes "Long Term Support" (LTS) versions and has a release process that is predictable and business-friendly.
Documentation
- Read the Getting Started guide if you are new to Symfony.
- Try the Symfony Demo application to learn Symfony in practice.
- Master Symfony with the Guides and Tutorials, the Components docs and the Best Practices reference.
Community
- Join the Symfony Community and meet other members at the Symfony events.
- Get Symfony support on Stack Overflow, Slack, IRC, etc.
- Follow us on GitHub, Twitter and Facebook.
- Read our Code of Conduct and meet the CARE Team.
Contributing
Symfony is an Open Source, community-driven project with thousands of contributors. Join them contributing code or contributing documentation.
Security Issues
If you discover a security vulnerability within Symfony, please follow our disclosure procedure.
About Us
Symfony development is sponsored by SensioLabs, led by the Symfony Core Team and supported by Symfony contributors.