1. 获取类属性、类方法

如果有一个类,我想要获取类中定义的属性、常量、方法,不使用发射该如何做到。

1.1 get_class() 获取类名称

语法:

  1. <?php
  2. // 返回对象实例 object 所属类的名字
  3. get_class(object $object = null): string

例子1:基本类使用

  1. <?php
  2. class A
  3. {
  4. }
  5. $a = new A();
  6. echo get_class($a) . PHP_EOL; // A

例子2:带有继承类使用

  1. <?php
  2. abstract class bar
  3. {
  4. public function __construct()
  5. {
  6. echo (get_class($this)) . PHP_EOL; // foo
  7. echo (get_class()) .PHP_EOL; // bar
  8. }
  9. }
  10. class foo extends bar
  11. {
  12. }
  13. new foo();

例子3:在命名空间中使用

  1. <?php
  2. namespace Foo\Bar;
  3. class Baz
  4. {
  5. public function __construct()
  6. {
  7. }
  8. }
  9. $baz = new \Foo\Bar\Baz;
  10. var_dump(get_class($baz)); // Foo\Bar\Baz

1.2 ::class 获取类名称

= php 5.5 的版本使用 className::class,是更号的方式

例子1:完全限定的类名

  1. <?php
  2. namespace my\library\mvc;
  3. class Dispatcher
  4. {
  5. }
  6. var_dump(Dispatcher::class); // string(25) "my\library\mvc\Dispatcher"

1.3 get_class_vars() 获取类属性数组

语法:

  1. <?php
  2. // 返回由类的默认公有属性组成的关联数组,注意返回的关联数组中的属性的值是属性定义的默认值,而且只会返回 public 修饰的属性。
  3. get_class_vars(string $class_name): array

例子1:直接这么使用获取的只是 public 修饰的公共属性

  1. <?php
  2. namespace reflact\demo5;
  3. class Foo
  4. {
  5. public $p1 = 1;
  6. public $p2 = 2;
  7. protected $p3 = 3;
  8. private $p4 = 4;
  9. }
  10. $properties = get_class_vars(Foo::class);
  11. foreach ($properties as $name => $value) {
  12. echo "{$name} : {$value} \n";
  13. }
  14. //p1 : 1
  15. //p2 : 2

1.4 get_class_methods() 获取类方法数组

语法:

  1. <?php
  2. // 返回由类的方法名组成的数组。入参:类名或者是类的实例
  3. get_class_methods(mixed $class_name): array

例子1:测试发现和 get_clas_vals()一样只会返回 public 修饰的。真的是这样吗?

  1. <?php
  2. namespace reflect\demo6;
  3. class MyClass
  4. {
  5. public function fun1()
  6. {
  7. }
  8. protected function fun2()
  9. {
  10. }
  11. private function fun3()
  12. {
  13. }
  14. }
  15. // 传入类名称
  16. $methods = get_class_methods(MyClass::class);
  17. foreach ($methods as $name => $value) {
  18. echo "{$name}: {$value} \n"; // 0 :fun1
  19. }
  20. // 传入类实例
  21. $methods2 = get_class_methods(new MyClass());
  22. foreach ($methods2 as $name => $value) {
  23. echo "{$name}: {$value} \n"; // 0 :fun1
  24. }

例子2:注意当前的作用域,在类的内部,传入类实例的话是可以获取到 private 和 protected 修饰的方法名称的

  1. <?php
  2. class C
  3. {
  4. private function fun1(){}
  5. protected function fun2(){}
  6. public function fun3(){}
  7. public function __construct()
  8. {
  9. echo '$this:' . PHP_EOL;
  10. var_dump(get_class_methods($this));
  11. echo 'C (inside class):' . PHP_EOL;
  12. var_dump(get_class_methods('C'));
  13. }
  14. }
  15. $c = new C;
  16. echo '$c:' . PHP_EOL;
  17. var_dump(get_class_methods($c));
  18. echo 'C (outside class):' . PHP_EOL;
  19. var_dump(get_class_methods('C'));
  20. /*
  21. $this:
  22. /Users/xs/workPlace/php/river/src/reflect/07_demo.php:20:
  23. array(4) {
  24. [0] =>
  25. string(4) "fun1"
  26. [1] =>
  27. string(4) "fun2"
  28. [2] =>
  29. string(4) "fun3"
  30. [3] =>
  31. string(11) "__construct"
  32. }
  33. C (inside class):
  34. /Users/xs/workPlace/php/river/src/reflect/07_demo.php:23:
  35. array(4) {
  36. [0] =>
  37. string(4) "fun1"
  38. [1] =>
  39. string(4) "fun2"
  40. [2] =>
  41. string(4) "fun3"
  42. [3] =>
  43. string(11) "__construct"
  44. }
  45. $c:
  46. /Users/xs/workPlace/php/river/src/reflect/07_demo.php:30:
  47. array(2) {
  48. [0] =>
  49. string(4) "fun3"
  50. [1] =>
  51. string(11) "__construct"
  52. }
  53. C (outside class):
  54. /Users/xs/workPlace/php/river/src/reflect/07_demo.php:33:
  55. array(2) {
  56. [0] =>
  57. string(4) "fun3"
  58. [1] =>
  59. string(11) "__construct"
  60. }
  61. */

官方文档的提示:

需要注意的是,get_class_methods($class)不仅返回$class定义的方法,还返回继承的方法。 似乎没有任何PHP函数来确定哪些方法被继承,哪些方法是由类显式定义的。

1.5 get_object_var()

语法:

  1. <?php
  2. // 返回由 obj 指定的对象中定义的属性组成的关联数组。
  3. get_object_vars(object $obj): array

例子1:通过这个类实例的媒介获取这个类中所有的属性

  1. <?php
  2. namespace reflact\demo8;
  3. class A
  4. {
  5. private $p1 = 1;
  6. protected $p2 = 2;
  7. public $p3 = 3;
  8. public function getPropertyArr(): array
  9. {
  10. return get_object_vars($this);
  11. }
  12. }
  13. $obj = new A();
  14. print_r(get_object_vars($obj)); // [p3] => 3
  15. print_r($obj->getPropertyArr()); // [p1] => 1 [p2] => 2 [p3] => 3

2. 类相关方法

通过这些方法,我们可以获取这个类的父类数组、实现的接口数组。

2.1 class_parents() 获取父类名称数组

语法:

  1. <?php
  2. // 本函数返回一个包含了指定类class父类名称的数组。
  3. // 入参:className or object
  4. class_parents(mixed $class, bool $autoload = ?): array

例子1:基本使用

  1. <?php
  2. namespace reflact\demo9;
  3. class A
  4. {
  5. }
  6. class B extends A
  7. {
  8. }
  9. class C extends B
  10. {
  11. }
  12. print_r(class_parents(C::class));
  13. print_r(class_parents(B::class));
  14. print_r(class_parents(A::class));
  15. /*
  16. Array
  17. (
  18. [reflact\demo9\B] => reflact\demo9\B
  19. [reflact\demo9\A] => reflact\demo9\A
  20. )
  21. Array
  22. (
  23. [reflact\demo9\A] => reflact\demo9\A
  24. )
  25. Array
  26. (
  27. )
  28. */

2.2 class_implements() 类实现的所有接口

语法:

  1. <?php
  2. // 本函数返回一个数组,该数组中包含了指定类class及其父类所实现的所有接口的名称。
  3. class_implements(mixed $class, bool $autoload = ?): array

例子1:基本使用

  1. <?php
  2. namespace reflect\demo10;
  3. interface animal
  4. {
  5. }
  6. interface move
  7. {
  8. }
  9. class Cat implements animal, move
  10. {
  11. }
  12. print_r(class_implements(Cat::class));
  13. /*
  14. (
  15. [reflect\demo10\animal] => reflect\demo10\animal
  16. [reflect\demo10\move] => reflect\demo10\move
  17. )
  18. */

2.3 class_uses() 类使用的trait