ホームページ >バックエンド開発 >PHPチュートリアル >手書きPHP APIフレームワークのリフレクション入門(3)

手書きPHP APIフレームワークのリフレクション入門(3)

藏色散人
藏色散人転載
2023-02-10 10:41:514270ブラウズ

前回の記事「手書きPHP APIフレームワーク:Composerのインストールと使い方(2)」ではComposerのインストールと使い方を紹介しましたが、今回はリフレクションの概念について紹介します。

熟考、直観的理解とは、到着地に基づいて出発地と発信源を見つけることです。リフレクションとは、PHP の実行状態で PHP プログラムの分析を拡張し、クラス、メソッド、プロパティ、パラメーターなどに関するコメントを含む詳細情報をエクスポートまたは提案することを指します。この動的に情報を取得し、オブジェクトのメソッドを動的に呼び出す機能をリフレクションAPIと呼びます。

まずデモを見てみましょう:

<?php


function p($msg, $var)
{
    echo($msg.":".print_r($var, true)).PHP_EOL.PHP_EOL;
}


class Demo
{
    private $id;

    protected $name;

    public $skills = [];

    public function __construct($id, $name, $skills = [])
    {
        $this->id = $id;
        $this->name = $name;
        $this->skills = $skills;
    }

    public function getName()
    {
        return $this->name;
    }
    public function getSkill()
    {
        p(&#39;skill&#39;, $this->skills);
    }
}


$ref = new ReflectionClass(&#39;Demo&#39;);
if ($ref->isInstantiable()) {
    p(&#39;检查类是否可实例化isInstantiable&#39;, null);
}
$constructor = $ref->getConstructor();
p(&#39;获取构造函数getConstructor&#39;, $constructor);

$parameters = $constructor->getParameters();
foreach ($parameters as $param) {
    p(&#39;获取参数getParameters&#39;, $param);
}

if ($ref->hasProperty(&#39;name&#39;)) {
    $attr = $ref->getProperty(&#39;name&#39;);
    p(&#39;获取属性getProperty&#39;, $attr);
}

$attributes = $ref->getProperties();
foreach ($attributes as $row) {
    p(&#39;获取属性列表getProperties&#39;, $row->getName());
}

if ($ref->hasMethod(&#39;getSkill&#39;)) {
    $method = $ref->getMethod(&#39;getSkill&#39;);
    p(&#39;获取方法getMethod&#39;, $method);
}

$methods = $ref->getMethods();
foreach ($methods as $row) {
    p(&#39;获取方法列表getMethods&#39;, $row->getName());
}

$instance = $ref->newInstanceArgs([1, &#39;sai&#39;, [&#39;php&#39;, &#39;js&#39;]]);
p(&#39;newInstanceArgs&#39;, $instance);

出力:

➜  php git:(main) php reflect.php 

检查类是否可实例化isInstantiable:

获取构造函数getConstructor:ReflectionMethod Object
(
    [name] => __construct
    [class] => Demo
)


获取参数getParameters:ReflectionParameter Object
(
    [name] => id
)


获取参数getParameters:ReflectionParameter Object
(
    [name] => name
)


获取参数getParameters:ReflectionParameter Object
(
    [name] => skills
)


获取属性getProperty:ReflectionProperty Object
(
    [name] => name
    [class] => Demo
)


获取属性列表getProperties:id

获取属性列表getProperties:name

获取属性列表getProperties:skills

获取方法getMethod:ReflectionMethod Object
(
    [name] => getSkill
    [class] => Demo
)


获取方法列表getMethods:__construct

获取方法列表getMethods:getName

获取方法列表getMethods:getSkill

newInstanceArgs:Demo Object
(
    [id:Demo:private] => 1
    [name:protected] => sai
    [skills] => Array
        (
            [0] => php
            [1] => js
        )

)

デモでは ReflectionClass クラスが使用されています。もちろん、ReflectionClass クラスはこれらの方法に限定されません。

その他のメソッド

ReflectionClass クラスにはさらに多くのメソッドがあります:

#メソッド説明##ReflectionClass::__constructReflectionClass::exportReflectionClass::getConstant#ReflectionClass::getConstants#ReflectionClass::getConstructorクラスのコンストラクターを取得しますReflectionClass::getDefaultPropertiesデフォルトのプロパティを取得しますReflectionClass::getDocCommentドキュメント コメントの取得ReflectionClass::getEndLine最終行の行番号の取得 ReflectionClass::getExtension定義されたクラスに基づいて拡張機能の ReflectionExtension オブジェクトを取得しますReflectionClass::getExtensionName拡張機能の名前を取得します定義されたクラスの場所ReflectionClass::getFileName定義クラスのファイル名を取得しますReflectionClass: :getInterfaceNamesインターフェイス名を取得ReflectionClass::getInterfacesインターフェイスを取得ReflectionClass:: getMethodクラス メソッドの ReflectionMethod を取得します。 ReflectionClass::getMethodsメソッドの配列を取得するReflectionClass::getModifiersGetクラス ModifiersReflectionClass::getNameクラス名の取得#ReflectionClass::getNamespaceName 名前空間の名前を取得しますReflectionClass::getParentClass親クラスを取得しますReflectionClass::getPropertiesプロパティのセットを取得するReflectionClass::getPropertyクラスのプロパティの ReflectionProperty を取得するReflectionClass::getReflectionConstantクラスの定数の ReflectionClassConstant を取得しますReflectionClass::getReflectionConstantsクラス定数を取得しますReflectionClass::getShortName短縮名を取得しますReflectionClass::getStartLine開始行番号を取得しますReflectionClass::getStaticProperties静的プロパティの取得静的プロパティの値の取得特性エイリアスの配列を返します戻り値 このクラスで使用される特性の名前の配列このクラスで使用される特性の配列を返します定数が定義されているかどうかを確認してくださいメソッドが定義されているかどうかを確認してください定義済みプロパティが定義されているかどうかを確認します##ReflectionClass::implementsInterfaceインターフェースの実装ReflectionClass::inNamespace名前空間にあるかどうかを確認します#ReflectionClass::isCloneableクラスがコピーできるかどうかを返します#ReflectionClass::isFinalReflectionClass::isInstance##ReflectionClass::isInstantiableクラスがインスタンス化可能かどうかを確認するReflectionClass::isInterfaceクラスがインターフェイスであるかどうかを確認するクラスが内部的に定義されている拡張機能またはコアによって表されているかどうかを確認します。 このクラスかどうかを確認しますis iterableiterable(反復可能)かどうかを確認しますサブクラスかどうかを確認する特性であるかどうかを返しますユーザーによって定義されているかどうかを確認します指定されたパラメーターから新しいクラス インスタンスを作成します##ReflectionClass::newInstanceArgs指定されたパラメーターから新しいクラス インスタンスを作成します。 ReflectionClass::newInstanceWithoutConstructorコンストラクターを呼び出さずに新しいクラス インスタンスを作成しますReflectionClass:: setStaticPropertyValue静的プロパティの値を設定しますReflectionClass::__toStringReflectionClass オブジェクトの文字列表現を返します。

強力な ReflectionClass に加えて、Reflection、ReflectionClassConstant、ReflectionMethod、ReflectionFunctionAbstract などもあります。マニュアルを確認することをお勧めします:

Reflection の実践的な応用

  • ##リフレクションはドキュメントとファイルの生成に使用できます。これを使用して、ファイル内のクラスをスキャンし、説明ドキュメントを 1 つずつ生成できます。

  • リフレクションはクラスの内部構造を検出できるため、これをフックとして使用して、プラグイン関数を実装します。

  • は、クラス名が不明または不確かな場合に、一部のクラスと実行メソッドを動的に生成およびインスタンス化するための動的プロキシとして使用できます。

    # 依存性の注入。複数回継承するクラスの場合、複数回のリフレクションを通じて基本クラスの構造を探索するか、再帰リフレクションを使用して継承されたすべてのクラスをインスタンス化できます。これは PHP 依存関係注入の原理でもあります。
  • リフレクションの利点

リフレクションをサポートする言語は、低環境では実装が難しいいくつかのランタイム機能を提供します。 -レベル言語 。
  • はハードコーディングをある程度回避し、柔軟性と汎用性を提供します。
  • ソース コードの構造 (コード ブロック、クラス、メソッド、プロトコルなど) をファーストクラス オブジェクトとして検出および変更できます。
  • ソース コード ステートメントと同じように (JavaScript の eval() 関数と同様)、実行時にシンボリック構文文字列を計算し、クラスまたは関数に一致する文字列を呼び出しまたは参照に変換できます。クラスまたは関数。
  • 新しい言語バイトコード インタプリタを作成して、プログラミング構造に新しい意味や目的を与えることができます。
  • #リフレクションのデメリット

学習コストが高い。リフレクション指向プログラミングでは、より一般的なコード実行を利用するために、フレームワーク、リレーショナル マッピング、オブジェクト インタラクションなど、より高度な知識が必要です。

  • また、リフレクションの概念と構文は比較的抽象的であるため、過剰な知識が必要になります。リフレクション テクノロジを乱用すると、他の人がコードを読みにくくなり、協力やコミュニケーションに役立ちません

  • リフレクションにより、操作効率が少し犠牲になりますが、コードの柔軟性が向上します。一定量の消費があります

  • #リフレクションはクラスのカプセル化も破壊し、公開すべきではないメソッドやプロパティを公開します

  • #日常の開発では、実際にはリフレクションをあまり使用しませんが、なぜここにリフレクションを導入するのでしょうか?まず、後でリフレクションを使用して Ioc コンテナを実装します。次に、リフレクションは PHP のコア機能の 1 つでもあり、一般的なフレームワークでは非常に一般的であり、それを理解する必要があります。
  • このセクションは比較的独立しているため、後続の章で使用します。

  • 推奨学習: 「
PHP ビデオ チュートリアル

ReflectionClass クラスを初期化する
クラスのエクスポート
定義の取得定数
定数のセットを取得
##ReflectionClass::getStaticPropertyValue
ReflectionClass::getTraitAliases
ReflectionClass::getTraitNames
ReflectionClass::getTraits
ReflectionClass::hasConstant
ReflectionClass::hasMethod
#ReflectionClass::hasProperty
##ReflectionClass:: isAbstract クラスが抽象クラスかどうかを確認します。 Class (abstract)
ReflectionClass::isAnonymous クラスが匿名クラスかどうかを確認します
クラスはfinalと宣言されています
クラスのインスタンスを確認してください
ReflectionClass::isInternal
ReflectionClass::isIterable
ReflectionClass::isIterateable
ReflectionClass::isSubclassOf
ReflectionClass::isTrait
ReflectionClass::isUserDefined
ReflectionClass::newInstance

以上が手書きPHP APIフレームワークのリフレクション入門(3)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。