Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Pengenalan kepada refleksi rangka kerja API PHP tulisan tangan (3)

Pengenalan kepada refleksi rangka kerja API PHP tulisan tangan (3)

藏色散人
藏色散人ke hadapan
2023-02-10 10:41:514236semak imbas

Dalam artikel sebelumnya "Rangka Kerja API PHP Tulisan Tangan - Pemasangan dan Penggunaan Komposer (2) " kami memperkenalkan pemasangan dan penggunaan Komposer Dalam artikel ini kami akan memperkenalkan konsep refleksi.

Refleksi, pemahaman intuitif adalah untuk mencari tempat berlepas dan sumber berdasarkan tempat ketibaan. Refleksi merujuk kepada melanjutkan analisis program PHP dalam keadaan berjalan PHP, mengeksport atau mencadangkan maklumat terperinci tentang kelas, kaedah, sifat, parameter, dll., termasuk ulasan. Fungsi untuk mendapatkan maklumat secara dinamik dan memanggil kaedah objek secara dinamik ini dipanggil API pantulan.

Mari kita lihat demo dahulu:

<?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);

Output:

➜  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
        )

)

Kelas ReflectionClass digunakan dalam demo. kelas ReflectionClass tidak terhad kepada kaedah ini.

Lebih banyak kaedah

Kelas ReflectionClass mempunyai lebih banyak kaedah:

方法 说明
ReflectionClass::__construct 初始化 ReflectionClass 类
ReflectionClass::export 导出一个类
ReflectionClass::getConstant 获取定义过的一个常量
ReflectionClass::getConstants 获取一组常量
ReflectionClass::getConstructor 获取类的构造函数
ReflectionClass::getDefaultProperties 获取默认属性
ReflectionClass::getDocComment 获取文档注释
ReflectionClass::getEndLine 获取最后一行的行数
ReflectionClass::getExtension 根据已定义的类获取所在扩展的 ReflectionExtension 对象
ReflectionClass::getExtensionName 获取定义的类所在的扩展的名称
ReflectionClass::getFileName 获取定义类的文件名
ReflectionClass::getInterfaceNames 获取接口(interface)名称
ReflectionClass::getInterfaces 获取接口
ReflectionClass::getMethod 获取一个类方法的 ReflectionMethod。
ReflectionClass::getMethods 获取方法的数组
ReflectionClass::getModifiers 获取类的修饰符
ReflectionClass::getName 获取类名
ReflectionClass::getNamespaceName 获取命名空间的名称
ReflectionClass::getParentClass 获取父类
ReflectionClass::getProperties 获取一组属性
ReflectionClass::getProperty 获取类的一个属性的 ReflectionProperty
ReflectionClass::getReflectionConstant Gets a ReflectionClassConstant for a class's constant
ReflectionClass::getReflectionConstants Gets class constants
ReflectionClass::getShortName 获取短名
ReflectionClass::getStartLine 获取起始行号
ReflectionClass::getStaticProperties 获取静态(static)属性
ReflectionClass::getStaticPropertyValue 获取静态(static)属性的值
ReflectionClass::getTraitAliases 返回 trait 别名的一个数组
ReflectionClass::getTraitNames 返回这个类所使用 traits 的名称的数组
ReflectionClass::getTraits 返回这个类所使用的 traits 数组
ReflectionClass::hasConstant 检查常量是否已经定义
ReflectionClass::hasMethod 检查方法是否已定义
ReflectionClass::hasProperty 检查属性是否已定义
ReflectionClass::implementsInterface 接口的实现
ReflectionClass::inNamespace 检查是否位于命名空间中
ReflectionClass::isAbstract 检查类是否是抽象类(abstract)
ReflectionClass::isAnonymous 检查类是否是匿名类
ReflectionClass::isCloneable 返回了一个类是否可复制
ReflectionClass::isFinal 检查类是否声明为 final
ReflectionClass::isInstance 检查类的实例
ReflectionClass::isInstantiable 检查类是否可实例化
ReflectionClass::isInterface 检查类是否是一个接口(interface)
ReflectionClass::isInternal 检查类是否由扩展或核心在内部定义
ReflectionClass::isIterable Check whether this class is iterable
ReflectionClass::isIterateable 检查是否可迭代(iterateable)
ReflectionClass::isSubclassOf 检查是否为一个子类
ReflectionClass::isTrait 返回了是否为一个 trait
ReflectionClass::isUserDefined 检查是否由用户定义的
ReflectionClass::newInstance 从指定的参数创建一个新的类实例
ReflectionClass::newInstanceArgs 从给出的参数创建一个新的类实例。
ReflectionClass::newInstanceWithoutConstructor 创建一个新的类实例而不调用它的构造函数
ReflectionClass::setStaticPropertyValue 设置静态属性的值
ReflectionClass::__toString 返回 ReflectionClass 对象字符串的表示形式。

Selain ReflectionClass yang berkuasa, terdapat juga Reflection, ReflectionClassConstant, ReflectionMethod, ReflectionFunctionAbstract dan sebagainya. Adalah disyorkan untuk menyemak manual:

Aplikasi Praktikal Refleksi

  • Refleksi boleh digunakan untuk penjanaan dokumen dan fail. Anda boleh menggunakannya untuk mengimbas kelas dalam fail dan menjana dokumen penerangan satu demi satu; melaksanakan fungsi pemalam;

  • boleh digunakan sebagai proksi dinamik untuk menjana dan membuat instantiat beberapa kelas dan kaedah pelaksanaan secara dinamik apabila nama kelas tidak diketahui atau tidak pasti

  • Suntikan kebergantungan. Untuk kelas yang mewarisi berbilang kali, kita boleh meneroka struktur kelas asas melalui pantulan berbilang, atau menggunakan pantulan rekursif untuk membuat seketika semua kelas yang diwarisi Ini juga merupakan prinsip suntikan pergantungan PHP.

  • Kelebihan Refleksi

Bahasa yang menyokong refleksi menyediakan beberapa ciri runtime yang sukar dilaksanakan dalam keadaan rendah -bahasa peringkat .

  • boleh mengelakkan pengekodan keras pada tahap tertentu dan memberikan fleksibiliti dan serba boleh.

  • boleh digunakan sebagai objek kelas pertama untuk menemui dan mengubah suai struktur kod sumber (seperti blok kod, kelas, kaedah, protokol, dll.).

  • boleh mengira rentetan sintaks simbolik pada masa jalan seperti penyataan kod sumber (serupa dengan fungsi eval() JavaScript), dan kemudian menukar rentetan padanan kelas atau fungsi kepada panggilan atau rujukan kepada kelas atau fungsi.

  • Jurubahasa bytecode bahasa baharu boleh dibuat untuk memberikan binaan pengaturcaraan makna atau tujuan baharu.

  • Kelemahan refleksi

Kos pembelajaran yang tinggi. Pengaturcaraan berorientasikan refleksi memerlukan pengetahuan yang lebih maju, termasuk rangka kerja, pemetaan hubungan dan interaksi objek, untuk menggunakan pelaksanaan kod yang lebih umum

  • Juga kerana konsep dan sintaks refleksi adalah agak abstrak, Penyalahgunaan teknologi refleksi yang berlebihan akan menyukarkan orang lain untuk membaca kod, yang tidak kondusif untuk kerjasama dan komunikasi

  • Refleksi meningkatkan fleksibiliti kod sambil mengorbankan sedikit kecekapan operasi di sana adalah jumlah penggunaan tertentu

  • Refleksi juga akan memusnahkan enkapsulasi kelas, mendedahkan kaedah atau sifat yang tidak sepatutnya didedahkan

  • Dalam perkembangan harian, kita sebenarnya tidak banyak menggunakan refleksi, jadi kenapa bawa ke sini? Pertama, kami akan menggunakan refleksi kemudian untuk melaksanakan bekas Ioc Kedua, refleksi juga merupakan salah satu fungsi teras PHP Ia sangat biasa dalam rangka kerja popular kami, dan ia adalah perlu untuk memahaminya.

  • Bahagian ini agak bebas dan kami akan menggunakannya dalam bab seterusnya.

Pembelajaran yang disyorkan: "

Tutorial Video PHP

"

Atas ialah kandungan terperinci Pengenalan kepada refleksi rangka kerja API PHP tulisan tangan (3). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.im. Jika ada pelanggaran, sila hubungi admin@php.cn Padam