Перейти до вмісту
PHP Ecosystem
Explore

Configuration reference

Цей контент ще не доступний вашою мовою.

This guide covers all configuration options for the RoadRunner extension, from basic setup to advanced production scenarios.

Register the RoadRunner worker and all four PSR factories in the configuration passed to the bridge application. For HttpSoft:

use HttpSoft\Message\{ResponseFactory, ServerRequestFactory, StreamFactory, UploadedFileFactory};
use Psr\Http\Message\{
ResponseFactoryInterface,
ServerRequestFactoryInterface,
StreamFactoryInterface,
UploadedFileFactoryInterface,
};
use Spiral\RoadRunner\Http\{PSR7Worker, PSR7WorkerInterface};
use Spiral\RoadRunner\Worker;
use yii\di\Instance;
$config['container']['definitions'] = [
PSR7WorkerInterface::class => [
'class' => PSR7Worker::class,
'__construct()' => [
Worker::create(),
Instance::of(ServerRequestFactoryInterface::class),
Instance::of(StreamFactoryInterface::class),
Instance::of(UploadedFileFactoryInterface::class),
],
],
ResponseFactoryInterface::class => ResponseFactory::class,
ServerRequestFactoryInterface::class => ServerRequestFactory::class,
StreamFactoryInterface::class => StreamFactory::class,
UploadedFileFactoryInterface::class => UploadedFileFactory::class,
];

Merge these definitions with any existing application services. The application configures the container during construction; the runner resolves PSR7WorkerInterface once when run() starts.

RoadRunner class accepts an Application instance.

<?php
declare(strict_types=1);
use yii2\extensions\psrbridge\http\Application;
use yii2\extensions\roadrunner\RoadRunner;
$app = new Application($config);
$runner = new RoadRunner($app);

Configure automatic worker restart based on memory usage.

$app = new Application($config);
// set the recycling threshold in bytes (otherwise read from PHP memory_limit)
$app->setMemoryLimit(256 * 1024 * 1024); // 256MB
$runner = new RoadRunner($app);

For each request the runner calls Application::handle(), passes the returned PSR response to respond(), and calls finalize() exactly once in finally. Successful emission triggers Yii after-send processing; failed processing or emission finalizes with false and reports the error to RoadRunner. A failure from finalization is retained while the worker shuts down, then propagates without reporting a second request outcome. If shutdown also fails, its exception remains available through getPrevious().

After success or a reported request failure, clean() checks whether allocated memory reached 90% of the configured threshold. When recycling is needed, the runner declines the next pending dispatch with stop() before application handling, so RoadRunner can retry it in a fresh worker. The loop then waits for RoadRunner’s stop command. clean() is a memory check, not a general test of request isolation.

Keep response streams open until respond() finishes. For large seekable downloads, configure PSR7Worker::$chunkSize instead of casting the entire response body to a string. Keep the default buffered output for non-seekable bodies such as pipes, because the HTTP worker rewinds bodies before streaming.

If the streaming emitter consumes a body-read failure, the runner still finalizes with false, skips after-send, and recycles the worker before propagating the original exception. A partial response cannot be replaced with a second outcome. If closing the failed stream also throws, the runner finalizes with false and propagates the read and transport failures immediately; it does not submit another outcome or reuse the failed transport.

The loop releases its local response and body references before waiting for the next dispatch. A pending exception can still retain a body through captured arguments when zend.exception_ignore_args is disabled. Those references remain until the exception is released; the runner preserves the original exception and its trace instead of changing PHP configuration or discarding diagnostic information.

Cookies, lazy sessions, and persistent components

Section titled “Cookies, lazy sessions, and persistent components”

Preserve request cookie validation and provide its secret key through the application’s secret configuration. Disable PHP’s automatic session cookies before opening a session so the bridge can emit them through the PSR response. For example, after configuring the request key:

$config['components']['session']['useCookies'] = false;
$config['components']['session']['useStrictMode'] = true;
$config['useSession'] = false; // optional: open sessions lazily in application code
$config['persistentComponents'] = ['db', 'cache'];

useSession=false skips eager opening around bootstrap. The bridge still closes a previous active session and synchronizes the current validated cookie ID, or clears it when missing, malformed, or tampered with. It does not turn off session support, CSRF protection, or cookie validation. Keep request, response, errorHandler, session, and user out of persistentComponents.

Use the bridge’s http\UploadedFile for model uploads. Upload state resets before each request, including when resetUploadedFiles=false. Validate uploaded content and choose storage names in application code.

Organize your project for RoadRunner:

app-basic/
├── config/
│ ├── console.php # Console application configuration
│ ├── db.php # Database configuration
│ ├── params.php # Application parameters
│ ├── test_db.php # Test database configuration
│ └── web.php # Web application configuration
├── .rr.yaml # RoadRunner configuration
└── rr # RoadRunner binary

console.php

<?php
declare(strict_types=1);
use yii\caching\FileCache;
use yii\log\FileTarget;
/** @var array<string,mixed> $params */
$params = require __DIR__ . '/params.php';
/** @var array<string,mixed> $db */
$db = require __DIR__ . '/db.php';
$config = [
'id' => 'basic-console',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'controllerNamespace' => 'app\commands',
'aliases' => [
'@bower' => '@vendor/bower-asset',
'@npm' => '@vendor/npm-asset',
'@tests' => '@app/tests',
],
'components' => [
'cache' => [
'class' => FileCache::class,
],
'log' => [
'targets' => [
[
'class' => FileTarget::class,
'levels' => ['error', 'warning'],
],
],
],
'db' => $db,
],
'params' => $params,
/*
'controllerMap' => [
'fixture' => [ // Fixture generation command line.
'class' => 'yii\faker\FixtureController',
],
],
*/
];
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
];
// configuration adjustments for 'dev' environment
// requires version `2.1.21` of yii2-debug module
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
}
return $config;

db.php

<?php
declare(strict_types=1);
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yii2basic',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
// Schema cache options (for production environment)
//'enableSchemaCache' => true,
//'schemaCacheDuration' => 60,
//'schemaCache' => 'cache',
];

params.php

<?php
declare(strict_types=1);
return [
'adminEmail' => 'admin@example.com',
'senderEmail' => 'noreply@example.com',
'senderName' => 'Example.com mailer',
];

test_db.php

<?php
declare(strict_types=1);
/** @var array<string,mixed> $db */
$db = require __DIR__ . '/db.php';
// test database! Important not to run tests on production or development databases
$db['dsn'] = 'mysql:host=localhost;dbname=yii2basic_test';
return $db;

test.php

<?php
declare(strict_types=1);
use app\models\User;
use yii\symfonymailer\{Mailer, Message};
/** @var array<string,mixed> $params */
$params = require __DIR__ . '/params.php';
/** @var array<string,mixed> $db */
$db = require __DIR__ . '/test_db.php';
/**
* Application configuration shared by all test types
*/
return [
'id' => 'basic-tests',
'basePath' => dirname(__DIR__),
'aliases' => [
'@bower' => '@vendor/bower-asset',
'@npm' => '@vendor/npm-asset',
],
'language' => 'en-US',
'components' => [
'db' => $db,
'mailer' => [
'class' => Mailer::class,
'viewPath' => '@app/mail',
// send all mails to a file by default.
'useFileTransport' => true,
'messageClass' => Message::class,
],
'assetManager' => [
'basePath' => __DIR__ . '/../web/assets',
],
'urlManager' => [
'showScriptName' => true,
],
'user' => [
'identityClass' => User::class,
],
'request' => [
// note: this key is for testing only. Replace with a secure, random string in production!
'cookieValidationKey' => 'your-cookie-validation-key',
'enableCsrfValidation' => false,
// but if you absolutely need it set cookie domain to localhost
/*
'csrfCookie' => [
'domain' => 'localhost',
],
*/
],
],
'params' => $params,
];

web.php

<?php
declare(strict_types=1);
use app\models\User;
use HttpSoft\Message\{
ResponseFactory,
ServerRequestFactory,
StreamFactory,
UploadedFileFactory,
};
use Psr\Http\Message\{
ResponseFactoryInterface,
ServerRequestFactoryInterface,
StreamFactoryInterface,
UploadedFileFactoryInterface,
};
use Spiral\RoadRunner\Http\{PSR7Worker, PSR7WorkerInterface};
use Spiral\RoadRunner\Worker;
use yii\caching\FileCache;
use yii\di\Instance;
use yii\gii\Module;
use yii\symfonymailer\Mailer;
use yii2\extensions\debug\WorkerDebugModule;
/** @var array<string,mixed> $params */
$params = require __DIR__ . '/params.php';
/** @var array<string,mixed> $db */
$db = require __DIR__ . '/db.php';
$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'aliases' => [
'@bower' => '@vendor/bower-asset',
'@npm' => '@vendor/npm-asset',
],
'components' => [
'request' => [
// note: this key is for testing only. Replace with a secure, random string in production!
'cookieValidationKey' => 'your-cookie-validation-key',
],
'cache' => [
'class' => FileCache::class,
],
'session' => [
'useCookies' => false,
'useStrictMode' => true,
],
'user' => [
'identityClass' => User::class,
'enableAutoLogin' => false,
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'mailer' => [
'class' => Mailer::class,
'viewPath' => '@app/mail',
// send all mails to a file by default.
'useFileTransport' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'db' => $db,
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
],
],
'container' => [
'definitions' => [
PSR7WorkerInterface::class => [
'class' => PSR7Worker::class,
'__construct()' => [
Worker::create(),
Instance::of(ServerRequestFactoryInterface::class),
Instance::of(StreamFactoryInterface::class),
Instance::of(UploadedFileFactoryInterface::class),
],
],
ResponseFactoryInterface::class => ResponseFactory::class,
ServerRequestFactoryInterface::class => ServerRequestFactory::class,
StreamFactoryInterface::class => StreamFactory::class,
UploadedFileFactoryInterface::class => UploadedFileFactory::class,
],
],
'params' => $params,
];
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => WorkerDebugModule::class,
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => Module::class,
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
}
return $config;

RoadRunner 2025.1.15 with HTTP plugin v5.3.0 drops URL-encoded DELETE fields before sending the request to PHP. The PHP adapter cannot recover those fields. JSON DELETE bodies work with a configured JSON parser; applications that explicitly support method override can accept POST with _method=DELETE or X-Http-Method-Override: DELETE. Method override changes the wire method and must be part of the endpoint and proxy policy.

Keep native body processing enabled when using multipart uploads. In this runtime version, enabling raw_body also bypasses multipart form and upload processing. Native DELETE URL-encoded clients require a runtime whose form handling has been verified to preserve their fields.