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('skill', $this->skills); } } $ref = new ReflectionClass('Demo'); if ($ref->isInstantiable()) { p('检查类是否可实例化isInstantiable', null); } $constructor = $ref->getConstructor(); p('获取构造函数getConstructor', $constructor); $parameters = $constructor->getParameters(); foreach ($parameters as $param) { p('获取参数getParameters', $param); } if ($ref->hasProperty('name')) { $attr = $ref->getProperty('name'); p('获取属性getProperty', $attr); } $attributes = $ref->getProperties(); foreach ($attributes as $row) { p('获取属性列表getProperties', $row->getName()); } if ($ref->hasMethod('getSkill')) { $method = $ref->getMethod('getSkill'); p('获取方法getMethod', $method); } $methods = $ref->getMethods(); foreach ($methods as $row) { p('获取方法列表getMethods', $row->getName()); } $instance = $ref->newInstanceArgs([1, 'sai', ['php', 'js']]); p('newInstanceArgs', $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.
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.
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.
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!