検索
ホームページバックエンド開発PHPチュートリアル最新の PHP フレームワークで IOC コンテナを理解して実装するための 1 つの記事

この記事では、PHP に関する関連知識をお届けします。主に IOC コンテナに関する関連コンテンツを紹介します。IOC の正式名称は、Inversion Of Control、反転制御です。一緒に話しましょう。見てください、それが皆さんのお役に立てば幸いです。

最新の PHP フレームワークで IOC コンテナを理解して実装するための 1 つの記事

#コンテナとは何ですか?

依存関係注入について聞いたことがある人は多いと思います。依存関係注入の実装の基本条件はコンテナと切り離せません。コンテナはクラスの依存関係と注入を管理するために使用され、サービス管理とコンポーネントの分離を担当します。最も単純なものは、コンテナとは、オブジェクトを格納するための専用の超大規模な配列として理解できます。

最新の PHP フレームワークで IOC コンテナを理解して実装するための 1 つの記事

図に示すように、呼び出し元はコンテナのラベルを通じてオブジェクト インスタンスを取得します。図からわかるように、::class を通じて取得できます。またはオブジェクトを介して直接インスタンス オブジェクトを取得することを示します。

IOCとは何ですか?

IOC コンテナについて聞いたことがあるかもしれませんが、IOC の正式名は (Inversion Of Control、反転制御) です。

制御の反転とは何かを理解しましょう。従来のコーディングでは、通常、クラス間の依存関係はコーディングを通じて新しいオブジェクトによって渡されますが、制御の反転を使用すると、オブジェクトの制御をコンテナーまたはフレームワークに渡すことができます。実装のために。その目的は、ハードコーディングなしでオブジェクトを作成できるようにすることであり、図 1 からわかるように、コンテナーには多数のオブジェクトが格納されており、使用したいときにそれらを直接使用できます。コンテナ内のオブジェクトをコードで作成する必要はありません。あるクラスのオブジェクトが必要な場合はコンテナからオブジェクトを取得し、オブジェクトが存在しない場合は自動的に作成されます。これは、コード内でオブジェクトを作成するプロセスを省略し、その作成プロセスをコンテナによって実現することを意味しており、これを反転制御と呼びます。 IOC を一言で要約すると、オブジェクト作成の制御をコンテナ実装クラスのインスタンス化に移します。

例: IOC を使用せずにクラスを作成したい場合

<?php
class Sunny{
}
$sunny = new Sunny();

新しいクラスを手動で作成する必要がありますが、この場合、コード内にハードコーディングされています。

IOC コンテナを使用するコードは次のように記述できます。

<?php
class Sunny{
}
$sunny = Container::getBean(Sunny::class);

このクラスをコンテナ内に実装するのを手伝ってください。これを見て質問する生徒もいるかもしれません。新しい Sunny を使用すれば、コードはより短くて簡単になるのではないでしょうか?依存関係の注入を見た後で例を見てみましょう。

Dependency Injection

IOC とは何かを理解したところで、新しい疑問が生じます。クラスを作成するときに、一部のクラスのコンストラクターがパラメーターを渡す必要がある場合はどうすればよいでしょうか? IOC の研究を通じて、IOC コンテナがオブジェクト インスタンスの作成の問題を解決するのに役立つことがわかりました。コンテナ内でオブジェクトを作成するときに、クラスに他の依存関係があることが判明した場合、依存関係の検索が実行されます。コンテナが必要なオブジェクトを見つけるプロセスは DL (Dependency Lookup、依存関係ルックアップ) と呼ばれます。必要な依存関係をコードフラグメントに注入することを DI (Dependency Injection、依存性注入) と呼びます。

たとえば、IOC で言及された新しい Sunny の例です。クラス間に複数の依存関係がある場合。

<?php
class Computer{
    public function run(){
        echo "编程中....\n";
    }
}
class Sunny{
    private $computer;
    public function __construct(Computer $computer){
        $this->computer = $computer;
    }
    public function program(){
        $this->computer->run();
    }
}
$sunny = new Sunny(new Computer());
$sunny->program();

ここでは、Sunny クラスがプログラミングのために Computer クラスに依存していることがわかります。IOC コンテナを使用して依存関係注入を実装すると、コードは単純になります。

<?php
class Computer{
    public function run(){
        echo "编程中....\n";
    }
}
class Sunny{
    private $computer;
    public function __construct(Computer $computer){
        $this->computer = $computer;
    }
    public function program(){
        $this->computer->run();
    }
}
$sunny = Container::getBean(Sunny::class);
$sunny->program();

一文の要約: クラス インスタンスの作成時に他のクラスへの依存を解決し、必要な他のオブジェクトをオブジェクトに動的に提供します。

依存関係の反転

依存関係の反転によって解決される問題は、モジュール間の重い依存関係を疎結合することです。上位モジュールは基礎となるモジュールに依存すべきではなく、すべて抽象化に依存する必要があります。通常、依存関係の反転を単純に理解すると、インターフェイスまたは抽象化に向けたプログラミングが行われます。次の例を通してインターフェイス指向プログラミングを見てみましょう。

class Cache{
    public function set($key,$value){
        $redis = new CFile();
        $redis->set($key,$value);
    }
}
class CFile{
    public function set($key,$value){
        echo "file:{$key}->{$value}\n";
    }
}
$cache = new Cache();
$cache->set("name","sunny");

上記のコードには大きな問題はないようですが、ある日ファイル キャッシュが Redis キャッシュに変更されたらどうなるでしょうか?

class Cache{
    public function set($key,$value){
        $redis = new CRedis();
        $redis->set($key,$value);
    }
}
class CRedis{
    public function set($key,$value){
        echo "redis:{$key}->{$value}\n";
    }
}
$cache = new Cache();
$cache->set("name","sunny");

このコードから、キャッシュで使用されるドライバーが変更されると、コードは呼び出し側で記述され、結合度が高くなるため、キャッシュ コードも対応する変更を行う必要があることがわかります。これはコードを変更するのと同じで、プログラマがインターフェイスに合わせてプログラミングできるようになり、コードの汎用性と標準化が向上します。

interface ICache{
    public function set($key,$value);
}
class CRedis implements ICache {
    public function set($key,$value)
{
        echo "redis:{$key}->{$value}\n";
    }
}
class CFile implements ICache{
    public function set($key,$value)
{
        echo "file:{$key}->{$value}\n";
    }
}
class Cache{
    private $drive;
    public function __construct(ICache $drive)
{
        $this->drive = $drive;
    }
    public function set($key,$value){
        $this->drive->set($key,$value);
    }
}
$cache = new Cache(new CFile());
$cache->set("name","sunny");

多くの人は、このコードを見て、目的のオブジェクトをコンストラクターに直接渡すべきではないかと考えます。なぜインターフェースを定義する必要があるのでしょうか?実際、インターフェースはコードを標準化するために定義されています。どのドライバーを使用しても、私のインターフェースを実装している限り、それを使用できます。インターフェースがないと、開発者は開発時にドライバーにどのようなメソッドを含めるべきかわかりません。ドライバ。インターフェースを使用する場合、インターフェースをプログラミングするだけでよく、キャッシュはクラスの実装方法には関係なく、インターフェースのメソッドに従って動作するだけです。

一文で要約: 疎結合を実現するための依存関係の反転

実践的な戦闘: コンテナーの原則に基づいたコンテナーの実装

<?php
class Container
{
    // 当前容器对象
    private static $instance;
    // 存放在容器里面到实例
    protected $instances = [];
    private function __construct()
{
    }
    public static function getInstance()
{
        if (!self::$instance) {
            self::$instance = new static();
        }
        return self::$instance;
    }
    /**
     * 获取对象实例
     * @param $key
     * @return mixed
     */
    public function get($key)
{
        if (isset($this->instances[$key])) {
            return $this->instances[$key];
        }
    }
    /**
     * 绑定对象、闭包、类到容器
     * @param $key
     * @param null $concrete
     * @return Container
     */
    public function bind($key, $concrete = null)
{
        if ($concrete instanceof Closure) {
            $this->instances[$key] = $concrete;
        } elseif (is_object($concrete)) {
            $this->instances[$key] = $concrete;
        }
        return $this;
    }
}
class Sunny
{
    public function getName()
{
        echo time() . "\n";
    }
}
$app = Container::getInstance();
$sunny = $app->bind(Sunny::class,new Sunny());
$sunny = $app->get(Sunny::class);
$sunny->getName();

実践的な戦闘: 依存性の注入の実装

Container.php
<?php
class Container
{
    // 当前容器对象
    private static $instance;
    // 存放在容器里面到实例
    protected $instances = [];
    private function __construct()
{
    }
    public static function getInstance()
{
        if (!self::$instance) {
            self::$instance = new static();
        }
        return self::$instance;
    }
    /**
     * 获取对象实例
     * @param $key
     * @return mixed
     * @throws ReflectionException
     */
    public function get($key)
{
        if (isset($this->instances[$key])) {
            return $this->instances[$key];
        }
        return $this->make($key);
    }
    /**
     * 绑定对象、闭包、类到容器
     * @param $key
     * @param null $concrete
     * @return Container
     * @throws ReflectionException
     */
    public function bind($key, $concrete = null)
{
        if ($concrete instanceof Closure) {
            $this->instances[$key] = $concrete;
        } elseif (is_object($concrete)) {
            $this->instances[$key] = $concrete;
        } else {
            $this->make($key, $concrete);
        }
        return $this;
    }
    /**
     * 创建类绑定到类实例
     * @param $abstract
     * @param null $atgs
     * @return mixed
     * @throws ReflectionException
     */
    public function make($abstract, $atgs = null)
{
        if (isset($this->instances[$abstract])) {
            return $this->instances[$abstract];
        }
        $object = $this->invokeClass($abstract);
        $this->instances[$abstract] = $object;
        return $object;
    }
    /**
     * 反射解析类
     * @param $abstract
     * @return object
     * @throws ReflectionException
     */
    public function invokeClass($abstract)
{
        $reflectionClass = new \ReflectionClass($abstract);
        // 获取构造方法
        $construct = $reflectionClass->getConstructor();
        // 获取参数得到实例
        $params = $construct ? $this->parserParams($construct) : [];
        $object = $reflectionClass->newInstanceArgs($params);
        return $object;
    }
    /**
     * 解析构造方法参数
     * @param $reflect
     * @return array
     * @throws ReflectionException
     */
    public function parserParams(ReflectionMethod $reflect)
{
        $args = [];
        $params = $reflect->getParameters();
        if (!$params) {
            return $args;
        }
        if (count($params) > 0) {
            foreach ($params as $param) {
                $class = $param->getClass();
                if ($class) {
                    $args[] = $this->make($class->getName());
                    continue;
                }
                // 获取变量的名称
                $name = $param->getName();
                // 默认值
                $def = null;
                // 如果有默认值,从默认值获取类型
                if ($param->isOptional()) {
                    $def = $param->getDefaultValue();
                }
                $args[] = $_REQUEST[$name] ?? $def;
            }
        }
        return $args;
    }
}
Test.php
<?php
class Test
{
    public $name;
    private $test1;
    public function __construct(Test1 $test1)
{
        $this->test1 = $test1;
        $this->name = $this->test1->getName();
    }
}
Test1.php
<?php
class Test1
{
    public function getName(){
        return "test1返回的名字";
    }
}
Sunny.php
<?php
require_once "./Container.php";
require_once "./Test.php";
require_once "./Test1.php";
class Sunny
{
    private $test;
    public function __construct(Test $test)
{
        $this->test = $test;
    }
    public function getName()
{
        echo "获取test里面的name:{$this->test->name}\n";
    }
}
$app = Container::getInstance();
$sunny = $app->get(Sunny::class);
$sunny->getName();

推奨学習: 「

PHP ビデオ チュートリアル

以上が最新の PHP フレームワークで IOC コンテナを理解して実装するための 1 つの記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はIT不是挨踢微信公众号で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
PHPの継続的な使用:その持久力の理由PHPの継続的な使用:その持久力の理由Apr 19, 2025 am 12:23 AM

まだ人気があるのは、使いやすさ、柔軟性、強力なエコシステムです。 1)使いやすさとシンプルな構文により、初心者にとって最初の選択肢になります。 2)Web開発、HTTP要求とデータベースとの優れた相互作用と密接に統合されています。 3)巨大なエコシステムは、豊富なツールとライブラリを提供します。 4)アクティブなコミュニティとオープンソースの性質は、それらを新しいニーズとテクノロジーの傾向に適応させます。

PHPおよびPython:類似点と相違点を調査しますPHPおよびPython:類似点と相違点を調査しますApr 19, 2025 am 12:21 AM

PHPとPythonはどちらも、Web開発、データ処理、自動化タスクで広く使用されている高レベルのプログラミング言語です。 1.PHPは、ダイナミックウェブサイトとコンテンツ管理システムの構築によく使用されますが、PythonはWebフレームワークとデータサイエンスの構築に使用されることがよくあります。 2.PHPはエコーを使用してコンテンツを出力し、Pythonは印刷を使用します。 3.両方ともオブジェクト指向プログラミングをサポートしますが、構文とキーワードは異なります。 4。PHPは弱いタイプの変換をサポートしますが、Pythonはより厳しくなります。 5. PHPパフォーマンスの最適化には、Opcacheおよび非同期プログラミングの使用が含まれますが、PythonはCprofileおよび非同期プログラミングを使用します。

PHPおよびPython:さまざまなパラダイムが説明されていますPHPおよびPython:さまざまなパラダイムが説明されていますApr 18, 2025 am 12:26 AM

PHPは主に手順プログラミングですが、オブジェクト指向プログラミング(OOP)もサポートしています。 Pythonは、OOP、機能、手続き上のプログラミングなど、さまざまなパラダイムをサポートしています。 PHPはWeb開発に適しており、Pythonはデータ分析や機械学習などのさまざまなアプリケーションに適しています。

PHPとPython:彼らの歴史を深く掘り下げますPHPとPython:彼らの歴史を深く掘り下げますApr 18, 2025 am 12:25 AM

PHPは1994年に発信され、Rasmuslerdorfによって開発されました。もともとはウェブサイトの訪問者を追跡するために使用され、サーバー側のスクリプト言語に徐々に進化し、Web開発で広く使用されていました。 Pythonは、1980年代後半にGuidovan Rossumによって開発され、1991年に最初にリリースされました。コードの読みやすさとシンプルさを強調し、科学的コンピューティング、データ分析、その他の分野に適しています。

PHPとPythonの選択:ガイドPHPとPythonの選択:ガイドApr 18, 2025 am 12:24 AM

PHPはWeb開発と迅速なプロトタイピングに適しており、Pythonはデータサイエンスと機械学習に適しています。 1.PHPは、単純な構文と迅速な開発に適した動的なWeb開発に使用されます。 2。Pythonには簡潔な構文があり、複数のフィールドに適しており、強力なライブラリエコシステムがあります。

PHPとフレームワーク:言語の近代化PHPとフレームワーク:言語の近代化Apr 18, 2025 am 12:14 AM

PHPは、多数のWebサイトとアプリケーションをサポートし、フレームワークを通じて開発ニーズに適応するため、近代化プロセスで依然として重要です。 1.PHP7はパフォーマンスを向上させ、新機能を紹介します。 2。Laravel、Symfony、Codeigniterなどの最新のフレームワークは、開発を簡素化し、コードの品質を向上させます。 3.パフォーマンスの最適化とベストプラクティスは、アプリケーションの効率をさらに改善します。

PHPの影響:Web開発などPHPの影響:Web開発などApr 18, 2025 am 12:10 AM

phphassiblasifly-impactedwebdevevermentandsbeyondit.1)itpowersmajorplatformslikewordpratsandexcelsindatabase interactions.2)php'sadaptableability allowsitale forlargeapplicationsusingframeworkslikelavel.3)

スカラータイプ、リターンタイプ、ユニオンタイプ、ヌル可能なタイプなど、PHPタイプのヒントはどのように機能しますか?スカラータイプ、リターンタイプ、ユニオンタイプ、ヌル可能なタイプなど、PHPタイプのヒントはどのように機能しますか?Apr 17, 2025 am 12:25 AM

PHPタイプは、コードの品質と読みやすさを向上させるためのプロンプトがあります。 1)スカラータイプのヒント:php7.0であるため、基本データ型は、int、floatなどの関数パラメーターで指定できます。 3)ユニオンタイプのプロンプト:PHP8.0であるため、関数パラメーターまたは戻り値で複数のタイプを指定することができます。 4)Nullable Typeプロンプト:null値を含めることができ、null値を返す可能性のある機能を処理できます。

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 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。