1. 获取类属性、类方法
如果有一个类,我想要获取类中定义的属性、常量、方法,不使用发射该如何做到。
1.1 get_class() 获取类名称
语法:
<?php
// 返回对象实例 object 所属类的名字
get_class(object $object = null): string
例子1:基本类使用
<?php
class A
{
}
$a = new A();
echo get_class($a) . PHP_EOL; // A
例子2:带有继承类使用
<?php
abstract class bar
{
public function __construct()
{
echo (get_class($this)) . PHP_EOL; // foo
echo (get_class()) .PHP_EOL; // bar
}
}
class foo extends bar
{
}
new foo();
例子3:在命名空间中使用
<?php
namespace Foo\Bar;
class Baz
{
public function __construct()
{
}
}
$baz = new \Foo\Bar\Baz;
var_dump(get_class($baz)); // Foo\Bar\Baz
1.2 ::class 获取类名称
= php 5.5 的版本使用 className::class,是更号的方式
例子1:完全限定的类名
<?php
namespace my\library\mvc;
class Dispatcher
{
}
var_dump(Dispatcher::class); // string(25) "my\library\mvc\Dispatcher"
1.3 get_class_vars() 获取类属性数组
语法:
<?php
// 返回由类的默认公有属性组成的关联数组,注意返回的关联数组中的属性的值是属性定义的默认值,而且只会返回 public 修饰的属性。
get_class_vars(string $class_name): array
例子1:直接这么使用获取的只是 public 修饰的公共属性
<?php
namespace reflact\demo5;
class Foo
{
public $p1 = 1;
public $p2 = 2;
protected $p3 = 3;
private $p4 = 4;
}
$properties = get_class_vars(Foo::class);
foreach ($properties as $name => $value) {
echo "{$name} : {$value} \n";
}
//p1 : 1
//p2 : 2
1.4 get_class_methods() 获取类方法数组
语法:
<?php
// 返回由类的方法名组成的数组。入参:类名或者是类的实例
get_class_methods(mixed $class_name): array
例子1:测试发现和 get_clas_vals()一样只会返回 public 修饰的。真的是这样吗?
<?php
namespace reflect\demo6;
class MyClass
{
public function fun1()
{
}
protected function fun2()
{
}
private function fun3()
{
}
}
// 传入类名称
$methods = get_class_methods(MyClass::class);
foreach ($methods as $name => $value) {
echo "{$name}: {$value} \n"; // 0 :fun1
}
// 传入类实例
$methods2 = get_class_methods(new MyClass());
foreach ($methods2 as $name => $value) {
echo "{$name}: {$value} \n"; // 0 :fun1
}
例子2:注意当前的作用域,在类的内部,传入类实例的话是可以获取到 private 和 protected 修饰的方法名称的
<?php
class C
{
private function fun1(){}
protected function fun2(){}
public function fun3(){}
public function __construct()
{
echo '$this:' . PHP_EOL;
var_dump(get_class_methods($this));
echo 'C (inside class):' . PHP_EOL;
var_dump(get_class_methods('C'));
}
}
$c = new C;
echo '$c:' . PHP_EOL;
var_dump(get_class_methods($c));
echo 'C (outside class):' . PHP_EOL;
var_dump(get_class_methods('C'));
/*
$this:
/Users/xs/workPlace/php/river/src/reflect/07_demo.php:20:
array(4) {
[0] =>
string(4) "fun1"
[1] =>
string(4) "fun2"
[2] =>
string(4) "fun3"
[3] =>
string(11) "__construct"
}
C (inside class):
/Users/xs/workPlace/php/river/src/reflect/07_demo.php:23:
array(4) {
[0] =>
string(4) "fun1"
[1] =>
string(4) "fun2"
[2] =>
string(4) "fun3"
[3] =>
string(11) "__construct"
}
$c:
/Users/xs/workPlace/php/river/src/reflect/07_demo.php:30:
array(2) {
[0] =>
string(4) "fun3"
[1] =>
string(11) "__construct"
}
C (outside class):
/Users/xs/workPlace/php/river/src/reflect/07_demo.php:33:
array(2) {
[0] =>
string(4) "fun3"
[1] =>
string(11) "__construct"
}
*/
官方文档的提示:
需要注意的是,get_class_methods($class)不仅返回$class定义的方法,还返回继承的方法。 似乎没有任何PHP函数来确定哪些方法被继承,哪些方法是由类显式定义的。
1.5 get_object_var()
语法:
<?php
// 返回由 obj 指定的对象中定义的属性组成的关联数组。
get_object_vars(object $obj): array
例子1:通过这个类实例的媒介获取这个类中所有的属性
<?php
namespace reflact\demo8;
class A
{
private $p1 = 1;
protected $p2 = 2;
public $p3 = 3;
public function getPropertyArr(): array
{
return get_object_vars($this);
}
}
$obj = new A();
print_r(get_object_vars($obj)); // [p3] => 3
print_r($obj->getPropertyArr()); // [p1] => 1 [p2] => 2 [p3] => 3
2. 类相关方法
通过这些方法,我们可以获取这个类的父类数组、实现的接口数组。
2.1 class_parents() 获取父类名称数组
语法:
<?php
// 本函数返回一个包含了指定类class父类名称的数组。
// 入参:className or object
class_parents(mixed $class, bool $autoload = ?): array
例子1:基本使用
<?php
namespace reflact\demo9;
class A
{
}
class B extends A
{
}
class C extends B
{
}
print_r(class_parents(C::class));
print_r(class_parents(B::class));
print_r(class_parents(A::class));
/*
Array
(
[reflact\demo9\B] => reflact\demo9\B
[reflact\demo9\A] => reflact\demo9\A
)
Array
(
[reflact\demo9\A] => reflact\demo9\A
)
Array
(
)
*/
2.2 class_implements() 类实现的所有接口
语法:
<?php
// 本函数返回一个数组,该数组中包含了指定类class及其父类所实现的所有接口的名称。
class_implements(mixed $class, bool $autoload = ?): array
例子1:基本使用
<?php
namespace reflect\demo10;
interface animal
{
}
interface move
{
}
class Cat implements animal, move
{
}
print_r(class_implements(Cat::class));
/*
(
[reflect\demo10\animal] => reflect\demo10\animal
[reflect\demo10\move] => reflect\demo10\move
)
*/