ホームページ バックエンド開発 PHPチュートリアル Pimple 実行プロセス (PHP コンテナー) の簡単な分析

Pimple 実行プロセス (PHP コンテナー) の簡単な分析

Jan 23, 2020 am 10:04 AM
pimple

Pimple 実行プロセス (PHP コンテナー) の簡単な分析

#必要な知識ポイント

クロージャ

クローズド パッケージと匿名関数は

PHP5.3.0 で導入されました。

クロージャとは、

作成時に周囲の状態をカプセル化する関数を指します。クロージャが配置されている環境が存在しなくなっても、クロージャにカプセル化された状態は依然として存在します。

理論的には、クロージャと匿名関数は異なる概念です。しかし、PHP ではこれを同じ概念として扱います。

実際、クロージャと匿名関数は関数に見せかけたオブジェクトです。これらは

Closure クラスのインスタンスです。

クロージャは、文字列や整数と同様、第一級の値型です。

クロージャの作成:

<?php
$closure = function ($name) {
    return &#39;Hello &#39; . $name;
};
echo $closure(&#39;nesfo&#39;);//Hello nesfo
var_dump(method_exists($closure, &#39;__invoke&#39;));//true
ログイン後にコピー

$closure 変数を呼び出すことができる理由は、この変数の値がクロージャであるためです。クロージャー オブジェクトは、__invoke() マジック メソッドを実装します。変数名の後に () がある限り、PHP は __invoke() メソッドを見つけて呼び出します。

通常、PHP クロージャーは関数のコールバックとして使用されます。

array_map()preg_replace_callback() メソッドはすべてコールバック関数を使用します。クロージャを使用するのに最適な時期です。

例:

<?php
$numbersPlusOne = array_map(function ($number) {
    return $number + 1;
}, [1, 2, 3]);
print_r($numbersPlusOne);
ログイン後にコピー

結果の取得:

[2, 3, 4]
ログイン後にコピー

クロージャが登場する前は、名前付き関数を個別に作成し、その関数を名前で参照することしかできませんでした。これを行うと、コードの実行が若干遅くなり、コールバックの実装が使用シナリオから分離されます。

<?php
function incrementNum ($number) {
    return $number + 1;
}
$numbersPlusOne = array_map(&#39;incrementNum&#39;, [1, 2, 3]);
print_r($numbersPlusOne);
ログイン後にコピー

SPL

ArrayAccess

は、オブジェクトが次のように動作できるようにする

ArrayAccess インターフェイスを実装します。配列 。 ArrayAccess インターフェイスには、実装する必要がある 4 つのメソッドが含まれています。

interface ArrayAccess {
    //检查一个偏移位置是否存在 
    public mixed offsetExists ( mixed $offset  );
    
    //获取一个偏移位置的值 
    public mixed offsetGet( mixed $offset  );
    
    //设置一个偏移位置的值 
    public mixed offsetSet ( mixed $offset  );
    
    //复位一个偏移位置的值 
    public mixed offsetUnset  ( mixed $offset  );
}
ログイン後にコピー

SplObjectStorage

SplObjectStorage クラスは、オブジェクトをキーまたはデータ構造として持つマップを実装します。それはオブジェクトのコレクションです (キーとしてオブジェクトに対応するデータを無視した場合)。このクラスのインスタンスは配列によく似ていますが、格納されるオブジェクトはすべて一意です。このクラスのもう 1 つの特徴は、コレクション全体を走査したり検索したりせずに、指定したオブジェクトをクラスから直接削除できることです。

::classSyntax

::class は文字列を表すためです。 ::class を使用する利点は、IDE で class の名前を直接変更できることです。その後、IDE が関連する参照を自動的に処理します。

同時に、PHP が関連コードを実行するときに、最初に関連クラスをロードしません。

同様に、自動コード検査

inspect もクラスを正しく識別できます。

Pimple コンテナー プロセスの簡単な分析

Pimple は、PHP コミュニティで人気のあるコンテナーです。コードの量はそれほど多くありません。詳細については、

https://github.com/silexphp/Pimple/blob/master/src/Pimple/Container.php を参照してください。

私たちのアプリケーションは Pimple に基づいて開発できます:

namespace EasyWeChat\Foundation;
use Pimple\Container;
class Application extends Container
{
    /**
     * Service Providers.
     *
     * @var array
     */
    protected $providers = [
        ServiceProviders\ServerServiceProvider::class,
        ServiceProviders\UserServiceProvider::class
    ];
    /**
     * Application constructor.
     *
     * @param array $config
     */
    public function __construct($config)
    {
        parent::__construct();
        $this[&#39;config&#39;] = function () use ($config) {
            return new Config($config);
        };
        if ($this[&#39;config&#39;][&#39;debug&#39;]) {
            error_reporting(E_ALL);
        }
        $this->registerProviders();
    }
    /**
     * Add a provider.
     *
     * @param string $provider
     *
     * @return Application
     */
    public function addProvider($provider)
    {
        array_push($this->providers, $provider);
        return $this;
    }
    /**
     * Set providers.
     *
     * @param array $providers
     */
    public function setProviders(array $providers)
    {
        $this->providers = [];
        foreach ($providers as $provider) {
            $this->addProvider($provider);
        }
    }
    /**
     * Return all providers.
     *
     * @return array
     */
    public function getProviders()
    {
        return $this->providers;
    }
    /**
     * Magic get access.
     *
     * @param string $id
     *
     * @return mixed
     */
    public function __get($id)
    {
        return $this->offsetGet($id);
    }
    /**
     * Magic set access.
     *
     * @param string $id
     * @param mixed  $value
     */
    public function __set($id, $value)
    {
        $this->offsetSet($id, $value);
    }
}
ログイン後にコピー

アプリケーションの使用方法:

$app = new Application([]);
$user = $app->user;
ログイン後にコピー

その後、$user オブジェクトのメソッドを使用できるようになります。 $this->user 属性はありませんが、直接使用できることがわかりました。主にこれら 2 つのメソッドの役割:

public function offsetSet($id, $value){}
public function offsetGet($id){}
ログイン後にコピー

以下では、これら 2 行のコードを実行するときに Pimple が行う動作について説明します。これを説明する前に、コンテナーの中心的な概念をいくつか見てみましょう。

サービス プロバイダー

サービス プロバイダーは、コンテナーと特定の関数実装クラスの間のブリッジです。サービス プロバイダーはインターフェイスを実装する必要があります

ServiceProviderInterface:

namespace Pimple;
/**
 * Pimple service provider interface.
 *
 * @author  Fabien Potencier
 * @author  Dominik Zogg
 */
interface ServiceProviderInterface
{
    /**
     * Registers services on the given container.
     *
     * This method should only be used to configure services and parameters.
     * It should not get services.
     *
     * @param Container $pimple A container instance
     */
    public function register(Container $pimple);
}
ログイン後にコピー

すべてのサービス プロバイダーはインターフェイス register メソッドを実装する必要があります。

このアプリケーションにはデフォルトで 2 つのサービス プロバイダーがあります:

protected $providers = [
    ServiceProviders\ServerServiceProvider::class,
    ServiceProviders\UserServiceProvider::class
];
ログイン後にコピー

UserServiceProvider を例として、そのコード実装を見てみましょう:

namespace EasyWeChat\Foundation\ServiceProviders;
use EasyWeChat\User\User;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
 * Class UserServiceProvider.
 */
class UserServiceProvider implements ServiceProviderInterface
{
    /**
     * Registers services on the given container.
     *
     * This method should only be used to configure services and parameters.
     * It should not get services.
     *
     * @param Container $pimple A container instance
     */
    public function register(Container $pimple)
    {
        $pimple[&#39;user&#39;] = function ($pimple) {
            return new User($pimple[&#39;access_token&#39;]);
        };
    }
}
ログイン後にコピー

us ご覧のとおり、サービス プロバイダーの登録メソッドは属性

user をコンテナに追加しますが、返されるのはオブジェクトではなくクロージャです。これについては後ほど説明します。

サービス登録

Application すべてのサービスのコンストラクターで $this->registerProviders(); を使用します。プロバイダーが登録されています:

private function registerProviders()
{
    foreach ($this->providers as $provider) {
        $this->register(new $provider());
    }
}
ログイン後にコピー

注意深く見ると、ここでサービス プロバイダーがインスタンス化され、コンテナ Pimple の register メソッドが呼び出されていることがわかります:

public function register(ServiceProviderInterface $provider, array $values = array())
{
    $provider->register($this);
    foreach ($values as $key => $value) {
        $this[$key] = $value;
    }
    return $this;
}
ログイン後にコピー

そして、サービス プロバイダーがここで呼び出されます ##ユーザーの #register

メソッドは前のセクションで説明したものです。登録メソッドは属性 user をコンテナに追加しますが、オブジェクトではなくクロージャを返します。 属性 user をコンテナ Pimple に追加するとき、

offsetSet($id, $value)

メソッドを呼び出します。属性 values をコンテナ Pimple 、キーにはそれぞれ値が割り当てられます: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>$this-&gt;values[$id] = $value; $this-&gt;keys[$id] = true;</pre><div class="contentsignin">ログイン後にコピー</div></div>この時点まで、実際に提供するクラス

EasyWeChat\User\Usr

をインスタンス化していません。実際の機能。ただし、サービスプロバイダーの登録は完了しています。 ここで実行すると:

$user = $app->user;
ログイン後にコピー

は offsetGet($id) を呼び出し、実際のクラスをインスタンス化します:

$raw = $this->values[$id];
$val = $this->values[$id] = $raw($this);
$this->raw[$id] = $raw;
$this->frozen[$id] = true;
return $val;
ログイン後にコピー

$raw はクロージャを取得します:

$pimple[&#39;user&#39;] = function ($pimple) {
    return new User($pimple[&#39;access_token&#39;]);
};
ログイン後にコピー

$raw($this)返回的是实例化的对象User。也就是说只有实际调用才会去实例化具体的类。后面我们就可以通过$this['user']或者$this->user调用User类里的方法了。

当然,Pimple里还有很多特性值得我们去深入研究,这里不做过多讲解。

更多相关php知识,请访问php教程

以上がPimple 実行プロセス (PHP コンテナー) の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

確固たる原則と、それらがPHP開発にどのように適用されるかを説明してください。 確固たる原則と、それらがPHP開発にどのように適用されるかを説明してください。 Apr 03, 2025 am 12:04 AM

PHP開発における固体原理の適用には、次のものが含まれます。1。単一責任原則(SRP):各クラスは1つの機能のみを担当します。 2。オープンおよびクローズ原理(OCP):変更は、変更ではなく拡張によって達成されます。 3。Lischの代替原則(LSP):サブクラスは、プログラムの精度に影響を与えることなく、基本クラスを置き換えることができます。 4。インターフェイス分離原理(ISP):依存関係や未使用の方法を避けるために、細粒インターフェイスを使用します。 5。依存関係の反転原理(DIP):高レベルのモジュールと低レベルのモジュールは抽象化に依存し、依存関係噴射を通じて実装されます。

システムの再起動後にUnixSocketの権限を自動的に設定する方法は? システムの再起動後にUnixSocketの権限を自動的に設定する方法は? Mar 31, 2025 pm 11:54 PM

システムが再起動した後、UnixSocketの権限を自動的に設定する方法。システムが再起動するたびに、UnixSocketの許可を変更するために次のコマンドを実行する必要があります:sudo ...

PHPにおける後期静的結合の概念を説明します。 PHPにおける後期静的結合の概念を説明します。 Mar 21, 2025 pm 01:33 PM

記事では、PHP 5.3で導入されたPHPの後期静的結合(LSB)について説明し、より柔軟な継承を求める静的メソッドコールのランタイム解像度を可能にします。 LSBの実用的なアプリケーションと潜在的なパフォーマ

phpstormでCLIモードをデバッグする方法は? phpstormでCLIモードをデバッグする方法は? Apr 01, 2025 pm 02:57 PM

phpstormでCLIモードをデバッグする方法は? PHPStormで開発するときは、PHPをコマンドラインインターフェイス(CLI)モードでデバッグする必要がある場合があります。

PHPのCurlライブラリを使用してJSONデータを含むPOSTリクエストを送信する方法は? PHPのCurlライブラリを使用してJSONデータを含むPOSTリクエストを送信する方法は? Apr 01, 2025 pm 03:12 PM

PHP開発でPHPのCurlライブラリを使用してJSONデータを送信すると、外部APIと対話する必要があることがよくあります。一般的な方法の1つは、Curlライブラリを使用して投稿を送信することです。

フレームワークセキュリティ機能:脆弱性から保護します。 フレームワークセキュリティ機能:脆弱性から保護します。 Mar 28, 2025 pm 05:11 PM

記事では、入力検証、認証、定期的な更新など、脆弱性から保護するためのフレームワークの重要なセキュリティ機能について説明します。

See all articles