Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 33e371e

Browse filesBrowse files
[Runtime] make GenericRuntime ... generic
1 parent 49d23d4 commit 33e371e
Copy full SHA for 33e371e

19 files changed

+357
-59
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
use Symfony\Component\HttpKernel\KernelEvents;
3939
use Symfony\Component\HttpKernel\KernelInterface;
4040
use Symfony\Component\HttpKernel\UriSigner;
41+
use Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner;
42+
use Symfony\Component\Runtime\Runner\Symfony\ResponseRunner;
4143
use Symfony\Component\Runtime\SymfonyRuntime;
4244
use Symfony\Component\String\LazyString;
4345
use Symfony\Component\String\Slugger\AsciiSlugger;
@@ -79,6 +81,8 @@ class_exists(WorkflowEvents::class) ? WorkflowEvents::ALIASES : []
7981
service('argument_resolver'),
8082
])
8183
->tag('container.hot_path')
84+
->tag('container.preload', ['class' => HttpKernelRunner::class])
85+
->tag('container.preload', ['class' => ResponseRunner::class])
8286
->tag('container.preload', ['class' => SymfonyRuntime::class])
8387
->alias(HttpKernelInterface::class, 'http_kernel')
8488

‎src/Symfony/Component/Runtime/GenericRuntime.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Runtime/GenericRuntime.php
+83-21Lines changed: 83 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ class_exists(ClosureResolver::class);
2222
/**
2323
* A runtime to do bare-metal PHP without using superglobals.
2424
*
25-
* One option named "debug" is supported; it toggles displaying errors
26-
* and defaults to the "APP_ENV" environment variable.
25+
* It supports the following options:
26+
* - "debug" toggles displaying errors and defaults
27+
* to the "APP_DEBUG" environment variable;
28+
* - "runtimes" maps types to a GenericRuntime implementation
29+
* that knows how to deal with each of them;
30+
* - "error_handler" defines the class to use to handle PHP errors.
2731
*
2832
* The app-callable can declare arguments among either:
2933
* - "array $context" to get a local array similar to $_SERVER;
@@ -42,42 +46,48 @@ class_exists(ClosureResolver::class);
4246
*/
4347
class GenericRuntime implements RuntimeInterface
4448
{
45-
private $debug;
49+
protected $options;
4650

4751
/**
4852
* @param array {
4953
* debug?: ?bool,
54+
* runtimes?: ?array,
55+
* error_handler?: string|false,
5056
* } $options
5157
*/
5258
public function __construct(array $options = [])
5359
{
54-
$this->debug = $options['debug'] ?? $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? true;
60+
$debug = $options['debug'] ?? $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? true;
5561

56-
if (!\is_bool($this->debug)) {
57-
$this->debug = filter_var($this->debug, \FILTER_VALIDATE_BOOLEAN);
62+
if (!\is_bool($debug)) {
63+
$debug = filter_var($debug, \FILTER_VALIDATE_BOOLEAN);
5864
}
5965

60-
if ($this->debug) {
66+
if ($debug) {
67+
umask(0000);
6168
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '1';
62-
$errorHandler = new BasicErrorHandler($this->debug);
63-
set_error_handler($errorHandler);
69+
70+
if (false !== $errorHandler = ($options['error_handler'] ?? BasicErrorHandler::class)) {
71+
$errorHandler::register($debug);
72+
$options['error_handler'] = false;
73+
}
6474
} else {
6575
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0';
6676
}
77+
78+
$this->options = $options;
6779
}
6880

6981
/**
7082
* {@inheritdoc}
7183
*/
72-
public function getResolver(callable $callable): ResolverInterface
84+
public function getResolver(callable $callable, \ReflectionFunction $reflector = null): ResolverInterface
7385
{
7486
if (!$callable instanceof \Closure) {
7587
$callable = \Closure::fromCallable($callable);
7688
}
7789

78-
$function = new \ReflectionFunction($callable);
79-
$parameters = $function->getParameters();
80-
90+
$parameters = ($reflector ?? new \ReflectionFunction($callable))->getParameters();
8191
$arguments = function () use ($parameters) {
8292
$arguments = [];
8393

@@ -95,7 +105,7 @@ public function getResolver(callable $callable): ResolverInterface
95105
return $arguments;
96106
};
97107

98-
if ($this->debug) {
108+
if ($_SERVER['APP_DEBUG']) {
99109
return new DebugClosureResolver($callable, $arguments);
100110
}
101111

@@ -115,15 +125,19 @@ public function getRunner(?object $application): RunnerInterface
115125
return $application;
116126
}
117127

118-
if (!\is_callable($application)) {
119-
throw new \LogicException(sprintf('"%s" doesn\'t know how to handle apps of type "%s".', get_debug_type($this), get_debug_type($application)));
120-
}
121-
122128
if (!$application instanceof \Closure) {
129+
if ($runtime = $this->resolveRuntime(\get_class($application))) {
130+
return $runtime->getRunner($application);
131+
}
132+
133+
if (!\is_callable($application)) {
134+
throw new \LogicException(sprintf('"%s" doesn\'t know how to handle apps of type "%s".', get_debug_type($this), get_debug_type($application)));
135+
}
136+
123137
$application = \Closure::fromCallable($application);
124138
}
125139

126-
if ($this->debug && ($r = new \ReflectionFunction($application)) && $r->getNumberOfRequiredParameters()) {
140+
if ($_SERVER['APP_DEBUG'] && ($r = new \ReflectionFunction($application)) && $r->getNumberOfRequiredParameters()) {
127141
throw new \ArgumentCountError(sprintf('Zero argument should be required by the runner callable, but at least one is in "%s" on line "%d.', $r->getFileName(), $r->getStartLine()));
128142
}
129143

@@ -163,8 +177,56 @@ protected function getArgument(\ReflectionParameter $parameter, ?string $type)
163177
return $this;
164178
}
165179

166-
$r = $parameter->getDeclaringFunction();
180+
if (!$runtime = $this->getRuntime($type)) {
181+
$r = $parameter->getDeclaringFunction();
182+
183+
throw new \InvalidArgumentException(sprintf('Cannot resolve argument "%s $%s" in "%s" on line "%d": "%s" supports only arguments "array $context", "array $argv" and "array $request", or a runtime named "Symfony\Runtime\%1$sRuntime".', $type, $parameter->name, $r->getFileName(), $r->getStartLine(), get_debug_type($this)));
184+
}
185+
186+
return $runtime->getArgument($parameter, $type);
187+
}
188+
189+
protected static function register(self $runtime): self
190+
{
191+
return $runtime;
192+
}
193+
194+
private function getRuntime(string $type): ?self
195+
{
196+
if (null === $runtime = ($this->options['runtimes'][$type] ?? null)) {
197+
$runtime = 'Symfony\Runtime\\'.$type.'Runtime';
198+
$runtime = class_exists($runtime) ? $runtime : $this->options['runtimes'][$type] = false;
199+
}
200+
201+
if (\is_string($runtime)) {
202+
$runtime = $runtime::register($this);
203+
}
204+
205+
if ($this === $runtime) {
206+
return null;
207+
}
208+
209+
return $runtime ?: null;
210+
}
211+
212+
private function resolveRuntime(string $class): ?self
213+
{
214+
if ($runtime = $this->getRuntime($class)) {
215+
return $runtime;
216+
}
217+
218+
foreach (class_parents($class) as $type) {
219+
if ($runtime = $this->getRuntime($type)) {
220+
return $runtime;
221+
}
222+
}
223+
224+
foreach (class_implements($class) as $type) {
225+
if ($runtime = $this->getRuntime($type)) {
226+
return $runtime;
227+
}
228+
}
167229

168-
throw new \InvalidArgumentException(sprintf('Cannot resolve argument "%s $%s" in "%s" on line "%d": "%s" supports only arguments "array $context", "array $argv" and "array $request".', $type, $parameter->name, $r->getFileName(), $r->getStartLine(), get_debug_type($this)));
230+
return null;
169231
}
170232
}

‎src/Symfony/Component/Runtime/Internal/BasicErrorHandler.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Runtime/Internal/BasicErrorHandler.php
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*/
1919
class BasicErrorHandler
2020
{
21-
public function __construct(bool $debug)
21+
public static function register(bool $debug): void
2222
{
2323
error_reporting(-1);
2424

@@ -32,10 +32,11 @@ public function __construct(bool $debug)
3232
if (0 <= ini_get('zend.assertions')) {
3333
ini_set('zend.assertions', 1);
3434
ini_set('assert.active', $debug);
35-
ini_set('assert.bail', 0);
3635
ini_set('assert.warning', 0);
3736
ini_set('assert.exception', 1);
3837
}
38+
39+
set_error_handler(new self());
3940
}
4041

4142
public function __invoke(int $type, string $message, string $file, int $line): bool

‎src/Symfony/Component/Runtime/Internal/ComposerPlugin.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Runtime/Internal/ComposerPlugin.php
+2-4Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,12 @@ public function updateAutoloadFile(): void
102102
throw new \InvalidArgumentException(sprintf('Class "%s" listed under "extra.runtime.class" in your composer.json file '.(class_exists($runtimeClass) ? 'should implement "%s".' : 'not found.'), $runtimeClass, RuntimeInterface::class));
103103
}
104104

105-
if (!\is_array($runtimeOptions = $extra['options'] ?? [])) {
106-
throw new \InvalidArgumentException('The "extra.runtime.options" entry in your composer.json file must be an array.');
107-
}
105+
unset($extra['class'], $extra['autoload_template']);
108106

109107
$code = strtr(file_get_contents($autoloadTemplate), [
110108
'%project_dir%' => $projectDir,
111109
'%runtime_class%' => var_export($runtimeClass, true),
112-
'%runtime_options%' => '['.substr(var_export($runtimeOptions, true), 7, -1)." 'project_dir' => {$projectDir},\n]",
110+
'%runtime_options%' => '['.substr(var_export($extra, true), 7, -1)." 'project_dir' => {$projectDir},\n]",
113111
]);
114112

115113
file_put_contents(substr_replace($autoloadFile, '_runtime', -4, 0), $code);
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Runtime\Symfony\Component\Console;
13+
14+
use Symfony\Component\Runtime\SymfonyRuntime;
15+
16+
/**
17+
* @internal
18+
*/
19+
class ApplicationRuntime extends SymfonyRuntime
20+
{
21+
}
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Runtime\Symfony\Component\Console\Command;
13+
14+
use Symfony\Component\Runtime\SymfonyRuntime;
15+
16+
/**
17+
* @internal
18+
*/
19+
class CommandRuntime extends SymfonyRuntime
20+
{
21+
}
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Runtime\Symfony\Component\Console\Input;
13+
14+
use Symfony\Component\Runtime\SymfonyRuntime;
15+
16+
/**
17+
* @internal
18+
*/
19+
class InputInterfaceRuntime extends SymfonyRuntime
20+
{
21+
}
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Runtime\Symfony\Component\Console\Output;
13+
14+
use Symfony\Component\Runtime\SymfonyRuntime;
15+
16+
/**
17+
* @internal
18+
*/
19+
class OutputInterfaceRuntime extends SymfonyRuntime
20+
{
21+
}
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Runtime\Symfony\Component\HttpFoundation;
13+
14+
use Symfony\Component\Runtime\SymfonyRuntime;
15+
16+
/**
17+
* @internal
18+
*/
19+
class RequestRuntime extends SymfonyRuntime
20+
{
21+
}
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Runtime\Symfony\Component\HttpFoundation;
13+
14+
use Symfony\Component\Runtime\SymfonyRuntime;
15+
16+
/**
17+
* @internal
18+
*/
19+
class ResponseRuntime extends SymfonyRuntime
20+
{
21+
}
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Runtime\Symfony\Component\HttKernel;
13+
14+
use Symfony\Component\Runtime\SymfonyRuntime;
15+
16+
/**
17+
* @internal
18+
*/
19+
class HttpKernelInterfaceRuntime extends SymfonyRuntime
20+
{
21+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.