コンテンツにスキップ
BlackOps1.xは試験的なバージョンです。Production Readyは2.xを予定しています。Releases
BlackOps
Esc
navigateopen⌘Jpreview
このページの内容

Application Bootstrap

Public Application BuilderからHTTPとConsoleのProcess Boundaryを構成する。

Installed ApplicationはApplication Rootを起点にPublic Application BuilderからHTTPとConsoleの共通Configuration Snapshotを作ります。

use BlackOps\Application\Application;

$application = Application::configure(dirname(__DIR__))
    ->withEnvironmentFile()
    ->withConfiguration()
    ->create();

configure()は存在するApplication Rootを絶対Pathへ正規化します。不正なRoot、Environment、Config、RegistrationはApplicationBootstrapExceptionで拒否されます。

EnvironmentとConfiguration

既定のInstalled ApplicationはwithEnvironmentFile()でProcess EnvironmentとOptional .envを一度だけSnapshotします。Process Environmentが.envより優先され、.envがない場合も起動できます。Testや外部Secret Loaderなど、解決済みの値を渡す場合だけwithEnvironment(array)を使います。Dotenv実装はFrameworkが所有し、ApplicationはVendor Runtime Classを直接Importしません。

withConfiguration()は既定で<application-root>/configを読みます。認識する設定ファイルはConfigurationの一覧(app.phpdatabase.phpoperations.phpexecution.phpjournal.phpmiddleware.phpretention.phpauth.phplogging.phpdiagnostics.phpfrontend.php)と一致します。存在しない既定Directoryは空Configとして扱い、一覧にないファイルは読みません。

Configは呼出時に一度だけ読み、create()後のFile変更を自動反映しません。各設定のShapeはConfigurationを参照してください。

Operation、Service、Command

config/operations.phpのDiscovery RootはBuild時にOperationを探索します。通常のApplication OperationをProviderへ列挙する必要はありません。PackageやApplication外Sourceを登録する場合だけprovidersを使います。

Typed Self-handled OperationはBuildでHandler Serviceとして自動登録されます。Repository Interface等のApplication固有DependencyをBindingする場合は、Service Providerをconfig/app.phpservicesへ登録します。BuilderのwithOperations()withServices()withCommands()から明示登録を追加することもできます。

Application Maintenance CommandはSymfonyの#[AsCommand]を付け、config/app.phpcommand_discoveryへSource Rootを指定します。build:compileがCommandを探索してCompiled Containerへ登録するため、Required Constructor DependencyをService Providerから注入できます。commandswithCommands()はPackage Command、Instance、明示Override/追加用として維持されます。

QuickstartではOperationをProviderへ列挙せず、Repository Interface、Transactional Command、After Commit Serviceだけを登録します。Default DBAL ConnectionはFrameworkがRuntimeでSynthetic Serviceとして注入するため、ApplicationがCredential付きConnectionをProviderで作る必要はありません。

<?php

declare(strict_types=1);

namespace App;

use App\Feature\Order\CreateOrder\CreateOrderCommand;
use App\Feature\Order\DoctrineOrderRepository;
use App\Feature\Order\OrderRepository;
use App\Feature\Order\RecordOrderCommit;
use App\UserInterface\Http\SampleTokenAuthenticator;
use App\UserInterface\Console\SampleConsoleActorProvider;
use BlackOps\Console\ConsoleActorProvider;
use BlackOps\Core\DependencyInjection\ServiceProvider;
use BlackOps\Core\DependencyInjection\ServiceRegistry;
use BlackOps\Http\Authentication\HttpAuthenticator;

final readonly class ApplicationServiceProvider implements ServiceProvider
{
    public function register(ServiceRegistry $services): void
    {
        $services->autowire(HttpAuthenticator::class, SampleTokenAuthenticator::class);
        $services->autowire(ConsoleActorProvider::class, SampleConsoleActorProvider::class);
        $services->autowire(OrderRepository::class, DoctrineOrderRepository::class);
        $services->autowire(CreateOrderCommand::class);
        $services->autowire(RecordOrderCommit::class);
    }
}

HTTP Process

公式のClassic/Worker EntrypointはBlackOps\Http\SapiRuntimeへApplicationを渡すだけです。

use BlackOps\Http\SapiRuntime;

require dirname(__DIR__) . '/vendor/autoload.php';
$application = require dirname(__DIR__) . '/bootstrap/app.php';
SapiRuntime::run($application); // WorkerはrunWorker($application)

Request生成、Response Emit、Safe 500、Worker LoopはFrameworkが所有します。Application::http()はCustom PSR-15 AdapterやTest向けのEscape Hatchです。

$handler = $application->http();
$response = $handler->handle($serverRequest);

http()は初回呼出時にCompile済みArtifactとDatabase設定を検証し、PSR-15 Handlerを遅延構成します。同じApplicationから繰り返し取得すると同じHandler Instanceを返します。

HTTP構成はSource Discovery、Artifact Compile、Database Migration、DDLを行いません。Artifact不足、Format不正、Build ID不一致時はFallbackせず失敗します。

Console Process

Project Rootのblackopsは同じApplicationからPublic Console Kernelを起動します。

use BlackOps\Application\Application;

require __DIR__ . '/vendor/autoload.php';

/** @var Application $application */
$application = require __DIR__ . '/bootstrap/app.php';

exit($application->console()->run());

listはCommand Manifestの名前/説明/Alias/Hiddenだけを読み、Command Constructor、Compiled Container、Database、PCNTL、Retention Serviceを構成しません。Command固有のhelpまたは実行時だけCompiled ContainerからCommandを解決します。Command ManifestがMissing/Invalid/StaleでもFramework Commandは残るため、php blackops build:compileで復旧できます。

#[ConsoleCommand]で公開したOperationも同じManifestから登録します。認可主体が必要なApplicationはConsoleActorProviderをService ProviderでBindingしてください。未Bindingまたはactor() === nullではOrigin/Authorization Actorを持たず、#[Authorize]付きOperationは既存Policyで拒否されます。FrameworkはExecution Actorをconsole-runtimeに固定し、CLI OptionからActor IDやCredentialを受け取りません。

Application ObjectやContainerをOperation、Value、Domain Serviceへ渡しません。業務DependencyはConstructor Injectionします。

Session AuthenticationをOpt-in登録する

Framework同梱のSession Coreは、SessionServiceProviderを追加したApplicationだけで有効になります。BearerとCookieは同時に解釈せず、Applicationが一方を選びます。

use App\Infrastructure\Identity\ApplicationSessionIdentityProvider;
use BlackOps\Auth\Session\SessionConfiguration;
use BlackOps\Auth\Session\SessionServiceProvider;

return [
    'services' => [
        SessionServiceProvider::bearer(
            ApplicationSessionIdentityProvider::class,
            new SessionConfiguration(ttlSeconds: 28_800, touchIntervalSeconds: 300),
        ),
    ],
];

make:authconfig/auth.phpは同じSession登録を環境変数から構成する書き方です。app.phpauth.phpの両方で同じService IDを登録すると、後からMergeされるauth.php側が有効になります。登録はどちらか一方だけにしてください。

CookieをCredential Sourceにする場合はSessionServiceProvider::cookie(ApplicationSessionIdentityProvider::class, 'application_session')を使います。Cookieの発行、SecureHttpOnlySameSite、Path/Domain、CSRFはApplicationが所有します。どちらもAuthenticationMiddlewareのGlobal登録は別途必要です。

SessionManagerはLogin/Logout Application ServiceへConstructor Injectionします。issue()が返すRaw Tokenは発行直後にBearer Responseまたは安全なCookieへ変換し、Operation Value、Outcome、Journal、Logへ渡さないでください。rotate()は旧Sessionの失効とSuccessorの発行を一つのTransactionで行い、revoke()はnull/Malformed/Unknown/Expired/Revokedでも安全に完了します。

Session CoreはDefault 8時間のAbsolute TTLとDefault 5分間隔のlast_used_at更新を持ちます。cleanup($cutoff)はCutoffより古いExpired/Revoked Rowだけを削除します。SchemaはRuntimeが自動作成しません。新規Applicationではphp blackops make:authがUser/Session MigrationのImmutable Snapshotを一度だけ生成します。既存Applicationは同じSchema ContractをForward Migrationへ取り込み、Migrationを明示実行してください。