Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ export default {
{text: 'Making HTTP Requests', link: '/cookbook/making-http-requests'},
{text: 'Using htmx for Partial Page Reloads', link: '/cookbook/using-htmx-for-partial-reloads'},
{text: 'Disabling CSRF Protection', link: '/cookbook/disabling-csrf-protection'},
{text: 'Sentry Integration', link: '/cookbook/sentry-integration'}
{text: 'Sentry Integration', link: '/cookbook/sentry-integration'},
{text: 'Using Yii in Third-Party Applications', link: '/cookbook/using-yii-in-third-party-apps'}
]
},
{
Expand Down
1 change: 1 addition & 0 deletions src/cookbook/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This book conforms to the [Terms of Yii Documentation](https://www.yiiframework.
- [Using htmx for partial page reloads](using-htmx-for-partial-reloads.md)
- [Disabling CSRF protection](disabling-csrf-protection.md)
- [Sentry integration](sentry-integration.md)
- [Using Yii in third-party applications](using-yii-in-third-party-apps.md)
- [Working on Windows](working-on-windows.md)
- [Opening files directly in PhpStorm](opening-files-in-phpstorm.md)
- [Configuring Xdebug](configuring-xdebug.md)
Expand Down
125 changes: 125 additions & 0 deletions src/cookbook/using-yii-in-third-party-apps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Using Yii in third-party applications

Sometimes a project already has an entry point owned by another framework, CMS, or legacy application, but you still
want to reuse Yii services: configuration, DI definitions, domain services, logging, mailers, database connections, or
console-oriented application code.

Yii3 has no global application singleton. Bootstrap the Yii container explicitly and pass the services you need to the
third-party code.

## Bootstrap the Yii container

Create a small adapter in the host application, for example `bootstrap-yii-services.php`:

```php
<?php

declare(strict_types=1);

use App\Environment;
use Psr\Container\ContainerInterface;
use Yiisoft\Yii\Runner\BootstrapRunner;
use Yiisoft\Yii\Runner\Console\ConsoleApplicationRunner;

function yiiContainer(string $yiiRoot): ContainerInterface
{
require_once $yiiRoot . '/src/bootstrap.php';

$runner = new ConsoleApplicationRunner(
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid using runner if another app already handles the entry point?

Copy link
Copy Markdown
Member Author

@samdark samdark May 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid using runner if another app already handles the entry point? I don't think we need everything that the runner creates as well.

rootPath: $yiiRoot,
debug: Environment::appDebug(),
checkEvents: false,
environment: Environment::appEnv(),
);

$container = $runner->getContainer();
$bootstrap = $runner->getConfig()->get('bootstrap-console');

(new BootstrapRunner($container, $bootstrap))->run();

return $container;
}
```

The console runner is used only as a convenient way to build configuration and DI container groups. The code does not
call `$runner->run()`, so it does not start a Yii console application and does not call `exit()`.

Use `ConsoleApplicationRunner` when you need common services and console-safe services. Use `HttpApplicationRunner`
instead only when you intentionally need web-specific definitions from the `di-web` group, such as PSR-17 HTTP factories
or web middleware dependencies.

## Get Yii services from the host application

Use the adapter from the third-party application:

```php
<?php

declare(strict_types=1);

use App\Shared\ApplicationParams;

require_once __DIR__ . '/path/to/yii-app/vendor/autoload.php';
require_once __DIR__ . '/bootstrap-yii-services.php';

$container = yiiContainer(__DIR__ . '/path/to/yii-app');

/** @var ApplicationParams $params */
$params = $container->get(ApplicationParams::class);

echo $params->name;
```

In real integrations, prefer getting your own application services instead of framework infrastructure. For example,
expose `InvoiceSender`, `ReportBuilder`, or `CatalogImporter` from Yii and call that service from the host application.

## Keep boundaries explicit

Avoid mixing request lifecycles. Let the host application continue to own its HTTP request and response. Let Yii provide
services that do not assume Yii is handling the current request.

Good candidates for reuse:

- domain services;
- repositories and database connections;
- mailers and notification services;
- loggers;
- validators;
- queue producers;
- command-like application services.

Avoid pulling in Yii actions, middleware stacks, sessions, CSRF middleware, or view rendering unless the host application
explicitly delegates that whole responsibility to Yii.

## Configuration groups

The default application template separates configuration by group:

- `di` is shared by web and console entry points;
- `di-console` is console-specific and includes `di` in the template;
- `di-web` is web-specific and includes `di`;
- `params-console` and `params-web` extend common `params`.

Choose the smallest group that contains the services you need. If the host application only needs domain services, keep
those definitions in `config/common/di/*.php` so both Yii and the third-party app can use them without web-only
dependencies.

After changing `config/configuration.php`, rebuild the merge plan:

```shell
composer yii-config-rebuild
```

## Error handling and logging

The host application should remain responsible for top-level error handling. Catch exceptions at the integration
boundary when the host app needs to convert them into its own response or error format.

Yii services can still use `Psr\Log\LoggerInterface`. Configure the Yii logger to write to the same destination as the
host application or bridge both applications to the same PSR-3 logger.

## Long-running host processes

If the third-party application is a worker, daemon, or event-loop server, avoid mutable shared state in services. Yii
services resolved from the container are shared by default, so design them as stateless services or create a fresh
container for each isolated job when stateful dependencies are unavoidable.
Loading