10000 [Runtime] make GenericRuntime ... generic · symfony/symfony@388c45d · GitHub
[go: up one dir, main page]

Skip to content

Commit 388c45d

Browse files
[Runtime] make GenericRuntime ... generic
1 parent 49d23d4 commit 388c45d

File tree

12 files changed

+245
-29
lines changed

12 files changed

+245
-29
lines changed

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

Lines 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

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ 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 two options:
26+
* - "debug" toggles displaying errors and defaults
27+
* to the "APP_ENV" environment variable
28+
* - "runtimes" maps types to a GenericRuntime implementation
29+
* that knows how to deal with each of them
2730
*
2831
* The app-callable can declare arguments among either:
2932
* - "array $context" to get a local array similar to $_SERVER;
@@ -42,28 +45,31 @@ class_exists(ClosureResolver::class);
4245
*/
4346
class GenericRuntime implements RuntimeInterface
4447
{
45-
private $debug;
48+
protected $options;
4649

4750
/**
4851
* @param array {
4952
* debug?: ?bool,
53+
* runtimes?: ?array
5054
* } $options
5155
*/
5256
public function __construct(array $options = [])
5357
{
54-
$this->debug = $options['debug'] ?? $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? true;
58+
$debug = $options['debug'] ?? $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? true;
5559

56-
if (!\is_bool($this->debug)) {
57-
$this->debug = filter_var($this->debug, \FILTER_VALIDATE_BOOLEAN);
60+
if (!\is_bool($debug)) {
61+
$debug = filter_var($debug, \FILTER_VALIDATE_BOOLEAN);
5862
}
5963

60-
if ($this->debug) {
64+
if ($debug) {
65+
umask(0000);
6166
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '1';
62-
$errorHandler = new BasicErrorHandler($this->debug);
63-
set_error_handler($errorHandler);
67+
set_error_handler(new BasicErrorHandler($debug));
6468
} else {
6569
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0';
6670
}
71+
72+
$this->options = $options;
6773
}
6874

6975
/**
@@ -95,7 +101,7 @@ public function getResolver(callable $callable): ResolverInterface
95101
return $arguments;
96102
};
97103

98-
if ($this->debug) {
104+
if ($_SERVER['APP_DEBUG']) {
99105
return new DebugClosureResolver($callable, $arguments);
100106
}
101107

@@ -115,15 +121,33 @@ public function getRunner(?object $application): RunnerInterface
115121
return $application;
116122
}
117123

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-
122124
if (!$application instanceof \Closure) {
125+
$class = \get_class($application);
126+
127+
if ($runtime = $this->getRuntime($class)) {
128+
return $runtime->getRunner($application);
129+
}
130+
131+
foreach (class_parents($class) as $type) {
132+
if ($runtime = $this->getRuntime($type)) {
133+
return $runtime->getRunner($application);
134+
}
135+
}
136+
137+
foreach (class_implements($class) as $type) {
138+
if ($runtime = $this->getRuntime($type)) {
139+
return $runtime->getRunner($application);
140+
}
141+
}
142+
143+
if (!\is_callable($application)) {
144+
throw new \LogicException(sprintf('"%s" doesn\'t know how to handle apps of type "%s".', get_debug_type($this), get_debug_type($application)));
145+
}
146+
123147
$application = \Closure::fromCallable($application);
124148
}
125149

126-
if ($this->debug && ($r = new \ReflectionFunction($application)) && $r->getNumberOfRequiredParameters()) {
150+
if ($_SERVER['APP_DEBUG'] && ($r = new \ReflectionFunction($application)) && $r->getNumberOfRequiredParameters()) {
127151
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()));
128152
}
129153

@@ -163,8 +187,31 @@ protected function getArgument(\ReflectionParameter $parameter, ?string $type)
163187
return $this;
164188
}
165189

166-
$r = $parameter->getDeclaringFunction();
190+
if (!$runtime = $this->getRuntime($type)) {
191+
$r = $parameter->getDeclaringFunction();
192+
193+
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)));
194+
}
195+
196+
return $runtime->getArgument($parameter, $type);
197+
}
198+
199+
protected static function register(self $runtime): self
200+
{
201+
return $runtime;
202+
}
203+
204+
private function getRuntime(string $type): ?self
205+
{
206+
if (null === $runtime = ($this->options['runtimes'][$type] ?? null)) {
207+
$runtime = 'Symfony\Runtime\\'.$type.'Runtime';
208+
$runtime = class_exists($runtime) ? $runtime : $this->options['runtimes'][$type] = false;
209+
}
210+
211+
if (\is_string($runtime)) {
212+
$runtime = $runtime::register($this);
213+
}
167214

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)));
215+
return $runtime ?: null;
169216
}
170217
}
Lines 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+
}
Lines 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+
}
Lines 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+
}
Lines changed: 21 additions & 0 deletions
< F438 /div>
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+
}
Lines 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+
}
Lines 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+
}
Lines 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