検索
ホームページバックエンド開発PHPチュートリアルPHP Lazy オブジェクトを使用した PSR 互換の依存関係注入コンテナーの構築

Building a PSR-Compatible Dependency Injection Container with PHP  Lazy Objects

PHP 8.4 での Lazy オブジェクトによる依存関係の注入の探索

最新の PHP の領域では、バージョン 8.4 のリリースで画期的な機能である Lazy Objects が導入されました。これらのオブジェクトにより、絶対に必要になるまで初期化を延期する新しい方法が可能になり、パフォーマンスが向上し、リソースの使用量が削減されます。この機能は、Lazy Objects の Lazy Initialization RFC で概要が説明されているように、ReflectionClass API の機能強化を通じて言語に深く統合されています。

RFC の例
Lazy Objects の可能性を説明するために、RFC を直接考慮した次の例を考えてみましょう:

class MyClass
{
    public function __construct(private int $foo)
    {
        // Heavy initialization logic here.
    }

    // ...
}

$initializer = static function (MyClass $ghost): void {
    $ghost->__construct(123);
};

$reflector = new ReflectionClass(MyClass::class);
$object = $reflector->newLazyGhost($initializer);

// At this point, $object is a lazy ghost object.

このメカニズムにより、開発者は初期化プロセスを細かく制御し、アクセスされたときにのみリソースが読み込まれるようにすることができます。

この RFC に触発されて、私は最適なパフォーマンスを実現するために Lazy Objects API を活用して、PSR-11 互換の依存関係注入コンテナーの構築に着手しました。

ContainerLazyObject の基礎

コンテナの中核は ContainerLazyObject クラスにあります。これを使用すると、依存関係を登録して遅延初期化することができます。つまり、依存関係は実際に必要な場合にのみインスタンス化されます。このタスクを実行する主なメソッドは次のとおりです:

public function set(string $id, object|string $concrete): void
{
    $reflector = new ReflectionClass($id);
    $initializer = $concrete;

    if (is_string($concrete)) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete($this);
        };
    }

    if (is_object($concrete) && !$concrete instanceof Closure) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete;
        };
    }

    $this->instances[$id] = $reflector->newLazyGhost($initializer);
}

コンテナへのサービスの登録

私たちのコンテナはサービスを登録するさまざまな方法をサポートしており、開発者に柔軟性を提供します。以下にいくつかの例を示します:

$container = new ContainerLazyObject();
$containerer->set(DatabaseService::class, fn() => new DatabaseService(new LoggerService()));
$container->set(LoggerService::class, fn() => new LoggerService());

// Alternative approach with class names
$container->set(DatabaseService::class, DatabaseService::class);
$containerr->set(LoggerService::class, LoggerService::class);

// Using already instantiated objects
$container->set(DatabaseService::class, new DatabaseService(new LoggerService()));
$container->set(LoggerService::class, new LoggerService());

この柔軟性により、ContainerLazyObject は、依存関係を動的に構築するか、事前構成されたオブジェクトを再利用するかにかかわらず、さまざまなシナリオに適応できます。

コンテナからサービスを取得しています
サービスがコンテナに登録されると、必要なときにいつでもサービスを取得できます。コンテナーはサービスが遅延インスタンス化されるようにするため、サービスは実際に要求されるまで作成されません。登録されたサービスを取得する方法の例を次に示します:

// Retrieving the services from the container
$loggerService = $container->get(LoggerService::class);
$databaseService = $container->get(DatabaseService::class);

ContainerLazyObject の核心 コンテナの核心は ContainerLazyObject クラスにあります。これを使用すると、依存関係を登録して遅延初期化することができます。つまり、依存関係は実際に使用されるときにのみ作成されます。このタスクを実行する主なメソッドは次のとおりです:

public function set(string $id, object|string $concrete): void
{
    $reflector = new ReflectionClass($id);
    $initializer = $concrete;

    if (is_string($concrete)) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete($this);
        };
    }

    if (is_object($concrete) && !$concrete instanceof Closure) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete;
        };
    }

    $this->instances[$id] = $reflector->newLazyGhost($initializer);
}

PSR-11の互換性

ContainerLazyObject の追加の利点は、依存関係注入コンテナーの PHP 標準である PSR-11 との互換性です。これにより、仕様に準拠したライブラリやフレームワークとの相互運用性が保証され、軽量で汎用的なソリューションになります。

他のコンテナとの性能比較

コンテナのパフォーマンスを測定するために、制御された環境で PhpBench を使用し、一般的な代替手段である Pimple、Illuminate、PHP-DI と比較しました。結果は有望なものでした:

class MyClass
{
    public function __construct(private int $foo)
    {
        // Heavy initialization logic here.
    }

    // ...
}

$initializer = static function (MyClass $ghost): void {
    $ghost->__construct(123);
};

$reflector = new ReflectionClass(MyClass::class);
$object = $reflector->newLazyGhost($initializer);

// At this point, $object is a lazy ghost object.

私たちのコンテナは優れたパフォーマンスを実証し、単純な依存関係解決シナリオでは Illuminate Container や PHP-DI などのより堅牢な代替手段よりも大幅に高速でした。

完全なクラス

public function set(string $id, object|string $concrete): void
{
    $reflector = new ReflectionClass($id);
    $initializer = $concrete;

    if (is_string($concrete)) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete($this);
        };
    }

    if (is_object($concrete) && !$concrete instanceof Closure) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete;
        };
    }

    $this->instances[$id] = $reflector->newLazyGhost($initializer);
}

結論

PHP 8.4 とその Lazy オブジェクトは、依存関係の注入を簡素化し、最適化する新しい可能性を開きました。私たちの ContainerLazyObject は、軽量、効率的、柔軟であることに加えて、PSR-11 に準拠しており、他のライブラリやフレームワークとの相互運用性を保証しています。

このアプローチを試して、次のプロジェクトで依存関係の管理がどのように簡素化されるかを確認してください。

以上がPHP Lazy オブジェクトを使用した PSR 互換の依存関係注入コンテナーの構築の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
PHPを使用して電子メールを送信する最良の方法は何ですか?PHPを使用して電子メールを送信する最良の方法は何ですか?May 08, 2025 am 12:21 AM

BestappRoachforseminginphpisusingthephpmailerlibrarydueToitsReliability、featurrichness、andeaseofuse.phpmailerSupportssmtpは、detairederorhandlingを提供します

PHPでの依存関係注射のベストプラクティスPHPでの依存関係注射のベストプラクティスMay 08, 2025 am 12:21 AM

依存関係注射(DI)を使用する理由は、コードのゆるい結合、テスト可能性、および保守性を促進するためです。 1)コンストラクターを使用して依存関係を注入します。2)サービスロケーターの使用を避け、3)依存関係噴射コンテナを使用して依存関係を管理する、4)依存関係を注入することでテスト可能性を向上させる、5)注入依存性を回避、6)パフォーマンスに対するDIの影響を考慮します。

PHPパフォーマンスのチューニングのヒントとコツPHPパフォーマンスのチューニングのヒントとコツMay 08, 2025 am 12:20 AM

phpperformancetuningisucial cuseenhancess andandandadsand。

PHP電子メールセキュリティ:電子メールを送信するためのベストプラクティスPHP電子メールセキュリティ:電子メールを送信するためのベストプラクティスMay 08, 2025 am 12:16 AM

bestpracticesforsendingemails securlyinphpinclude:1)sutureconsmttarttlsencryptionとの使用の使用、2)検証およびサンシジン化のinputStopReventinjectuctacks、3)adinitivedinitivedInemailsopenslsl、4)adlinglinglingemailoaに

パフォーマンスのためにPHPアプリケーションをどのように最適化しますか?パフォーマンスのためにPHPアプリケーションをどのように最適化しますか?May 08, 2025 am 12:08 AM

tooptimizephpapplicationsforporformance、usecaching、databaseoptimization、opcodecaching、andserverconfiguration.1)cachingwithedatedatedatafethtimes.2)最適化バイズビーインデキシング、readedandandandwriteoperations.3)

PHPの依存噴射とは何ですか?PHPの依存噴射とは何ですか?May 07, 2025 pm 03:09 PM

依存関係の依存性、テスト可能性、および維持可能性の依存性の依存性の依存性、および維持可能性は、エクステルンド依存性を維持する可能性があります

最高のPHPパフォーマンス最適化手法最高のPHPパフォーマンス最適化手法May 07, 2025 pm 03:05 PM

PHPパフォーマンスの最適化は、次の手順を通じて実現できます。1)スクリプトの上部にrequire_onceまたはinclude_onceを使用して、ファイルの負荷数を減らすことができます。 2)プリプロセシングステートメントとバッチ処理を使用して、データベースクエリの数を減らします。 3)OpCodeキャッシュのOpCacheを構成します。 4)PHP-FPM最適化プロセス管理を有効にして構成します。 5)CDNを使用して静的リソースを配布します。 6)コードパフォーマンス分析には、XdebugまたはBlackfireを使用します。 7)配列などの効率的なデータ構造を選択します。 8)最適化実行のためのモジュラーコードを記述します。

PHPパフォーマンスの最適化:OpCodeキャッシングの使用PHPパフォーマンスの最適化:OpCodeキャッシングの使用May 07, 2025 pm 02:49 PM

opcodeCachingsificlyprovesppherformanceBycachingCompiledCode、reducingServerloadandResponsetimes.1)itStoresPhpCodeInMemory、バイパス補助補強団体

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター