资讯专栏INFORMATION COLUMN

Laravel学习笔记之PHP反射(Reflection) (上)

JessYanCoding / 1507人阅读

摘要:说明中经常使用的反射特性来设计代码,本文主要学习的反射特性,来提高写代码时的设计质量。提供一套检测的两个工具包和,类似于探针一样的东西来探测这些一等公民。限于篇幅,下篇再聊下反射。

说明:Laravel中经常使用PHP的反射特性来设计代码,本文主要学习PHP的反射特性,来提高写代码时的设计质量。PHP提供一套检测class, interface, trait, property, method的两个工具包:Introspection FunctionsReflection API,类似于探针一样的东西来探测这些一等公民。本文先看下Introspection Functions的使用。

开发环境: Laravel5.3 + PHP7

Introspection Functions

Introspection Functions是用来操作object class的一些函数,PHP提供了大量的Introspection Functions来操作class, interface, trait, method, property:

class_exists()

interface_exists()

method_exists()

property_exists()

trait_exists()

class_alias()

get_class()

get_parent_class()

get_called_class()

get_class_methods()

get_class_vars()

get_object_vars()

is_subclass_of()

is_a()

class_exists()

Laravel源码中好多个地方使用到class_exists()方法来判断指定类是否存在,如IlluminateDatabaseConnection::isDoctrineAvailable()的源码:

</>复制代码

  1. public function isDoctrineAvailable()
  2. {
  3. return class_exists("DoctrineDBALConnection"); // DoctrineDBALConnection::class类是否存在,大小写不敏感
  4. }

写个PHPUnit测试下(爆绿灯,说明是正确的,这里不截图了。后面所有Introspection的测试都放在IntrospectionTest这个单元测试里):

</>复制代码

  1. namespace MyRightCapitalContainerTests;
  2. class IntrospectionTest extends PHPUnit_Framework_TestCase
  3. {
  4. public function testClassExists()
  5. {
  6. // Arrange
  7. // Actual
  8. $class_exists = class_exists(TestClassExists::class);
  9. // Assert
  10. $this->assertTrue($class_exists);
  11. }
  12. }
  13. class TestClassExists
  14. {
  15. }
interface_exists()

interface_exists()是用来检查接口是否存在,写个PHPUnit测试下,爆绿灯:

</>复制代码

  1. namespace MyRightCapitalContainerTests;
  2. class IntrospectionTest extends PHPUnit_Framework_TestCase
  3. {
  4. public function testInterfaceExists()
  5. {
  6. // Arrange
  7. // Actual
  8. $interface_exists = interface_exists(TestInterfaceExists::class);
  9. // Assert
  10. $this->assertTrue($interface_exists);
  11. }
  12. }
  13. interface TestInterfaceExists
  14. {
  15. }
method_exists()

检查类的方法(private,protected,public)是否存在于指定的类对象或类名中,Laravel中很多处用到了这个函数,如Application中的register()检查service provider中register是否存在,和bootProvider()中检查service provider中boot()方法是否存在:

</>复制代码

  1. public function register($provider, $options = [], $force = false)
  2. {
  3. ...
  4. if (method_exists($provider, "register")) {
  5. $provider->register();
  6. }
  7. ...
  8. }
  9. protected function bootProvider(ServiceProvider $provider)
  10. {
  11. if (method_exists($provider, "boot")) {
  12. return $this->call([$provider, "boot"]);
  13. }
  14. }

这里写个PHPUnit测试下,爆绿灯:

</>复制代码

  1. public function testMethodExists()
  2. {
  3. // Arrange
  4. $test_class_exists = new TestClassExists();
  5. // Actual
  6. $object_method_exists1 = method_exists($test_class_exists, "testPrivateMethodExists");
  7. $object_method_exists2 = method_exists($test_class_exists, "testProtectedMethodExists");
  8. $object_method_exists3 = method_exists($test_class_exists, "testPublicMethodExists");
  9. $classname_method_exists1 = method_exists(TestClassExists::class, "testPrivateMethodExists");
  10. $classname_method_exists2 = method_exists(TestClassExists::class, "testProtectedMethodExists");
  11. $classname_method_exists3 = method_exists(TestClassExists::class, "testPublicMethodExists");
  12. // Assert
  13. $this->assertTrue($object_method_exists1);
  14. $this->assertTrue($object_method_exists2);
  15. $this->assertTrue($object_method_exists3);
  16. $this->assertTrue($classname_method_exists1);
  17. $this->assertTrue($classname_method_exists2);
  18. $this->assertTrue($classname_method_exists3);
  19. }
  20. class TestClassExists
  21. {
  22. private function testPrivateMethodExists()
  23. {
  24. }
  25. protected function testProtectedMethodExists()
  26. {
  27. }
  28. public function testPublicMethodExists()
  29. {
  30. }
  31. }
property_exists()

检查该属性(private, protected, public)是否存在于类对象或类名中,Laravel很多地方用到了该函数,如IlluminateFoundationAuthRedirectsUsers::redirectPath()源码:

</>复制代码

  1. public function redirectPath()
  2. {
  3. return property_exists($this, "redirectTo") ? $this->redirectTo : "/home";
  4. }

写个PHPUnit测试下该函数,爆绿灯:

</>复制代码

  1. // class IntrospectionTest
  2. public function testPropertyExists()
  3. {
  4. // Arrange
  5. $test_class_exists = new TestClassExists();
  6. // Actual
  7. $private_property1 = property_exists($test_class_exists, "testPrivatePropertyExists");
  8. $private_property2 = property_exists(TestClassExists::class, "testPrivatePropertyExists");
  9. $protected_property1 = property_exists($test_class_exists, "testProtectedPropertyExists");
  10. $protected_property2 = property_exists(TestClassExists::class, "testProtectedPropertyExists");
  11. $public_property1 = property_exists($test_class_exists, "testPublicPropertyExists");
  12. $public_property2 = property_exists(TestClassExists::class, "testPublicPropertyExists");
  13. // Assert
  14. $this->assertTrue($private_property1);
  15. $this->assertTrue($private_property2);
  16. $this->assertTrue($protected_property1);
  17. $this->assertTrue($protected_property2);
  18. $this->assertTrue($public_property1);
  19. $this->assertTrue($public_property2);
  20. }
  21. class TestClassExists
  22. {
  23. private $testPrivatePropertyExists;
  24. protected $testProtectedPropertyExists;
  25. public $testPublicPropertyExists;
  26. }
trait_exists()

检查trait是否存在,写下PHPUnit测试,爆绿灯:

</>复制代码

  1. // class IntrospectionTest
  2. public function testTraitExists()
  3. {
  4. // Arrange
  5. // Actual
  6. $test_trait_exists = trait_exists(TestTraitExists::class);
  7. // Assert
  8. $this->assertTrue($test_trait_exists);
  9. }
  10. trait TestTraitExists
  11. {
  12. }
class_alias()

给指定类取别名,Laravel中只有一处使用了class_alias(),用来给config/app.php中$aliases[ ]注册别名,可看下Laravel学习笔记之bootstrap源码解析,看下Laravel中如何使用的:

</>复制代码

  1. public function load($alias)
  2. {
  3. if (isset($this->aliases[$alias])) {
  4. return class_alias($this->aliases[$alias], $alias);
  5. }
  6. }

写个PHPUnit测试,爆绿灯:

</>复制代码

  1. public function testClassAlias()
  2. {
  3. // Arrange
  4. class_alias(TestClassExists::class, "MyRightCapitalContainerTestsAliasTestClassExists");
  5. $test_class_exists = new TestClassExists();
  6. // Actual
  7. $actual = new AliasTestClassExists();
  8. //Assert
  9. $this->assertInstanceOf(TestClassExists::class, $actual);
  10. $this->assertInstanceOf(AliasTestClassExists::class, $test_class_exists);
  11. }
get_class()

get_class()获取对象的类名,这个函数在Laravel中大量地方在用了,如Application::getProvider($provider)方法,是个很好用的方法:

</>复制代码

  1. public function getProvider($provider)
  2. {
  3. $name = is_string($provider) ? $provider : get_class($provider);
  4. return Arr::first($this->serviceProviders, function ($value) use ($name) {
  5. return $value instanceof $name;
  6. });
  7. }

写个PHPUnit测试,爆绿灯:

</>复制代码

  1. public function testGetClass()
  2. {
  3. // Arrange
  4. $test_class_exists = new TestClassExists();
  5. // Actual
  6. $class_name = get_class($test_class_exists);
  7. // Assert
  8. $this->assertSame(TestClassExists::class, $class_name);
  9. }
get_parent_class()

get_parent_class()是用来获取类的父类名,目前Laravel中还没用到这个函数,传入的可以是子类对象或者子类名,写个PHPUnit测试下:

</>复制代码

  1. // namespace MyRightCapitalContainerTests;
  2. // class IntrospectionTest extends PHPUnit_Framework_TestCase
  3. public function testGetParentClass()
  4. {
  5. // Arrange
  6. $child_class = new ChildClass();
  7. // Actual
  8. $parent_class1 = get_parent_class($child_class);
  9. $parent_class2 = get_parent_class(ChildClass::class);
  10. // Assert
  11. $this->assertSame(ParentClass::class, $parent_class1);
  12. $this->assertSame(ParentClass::class, $parent_class2);
  13. }
  14. class ChildClass extends ParentClass
  15. {
  16. }
  17. class ParentClass
  18. {
  19. }
get_called_class()

get_called_class()获取后期静态绑定类即实际调用类的名称,Laravel中还没使用到该函数,不妨写个测试看下如何使用:

</>复制代码

  1. // namespace MyRightCapitalContainerTests;
  2. // class IntrospectionTest extends PHPUnit_Framework_TestCase
  3. public function testGetCalledClass()
  4. {
  5. // Arrange
  6. $child_class = new ChildClass();
  7. $parent_class = new ParentClass();
  8. // Actual
  9. $child_called_class = $child_class->testGetCalledClass();
  10. $parent_called_class = $parent_class->testGetCalledClass();
  11. // Assert
  12. $this->assertSame(ChildClass::class, $child_called_class);
  13. $this->assertSame(ParentClass::class, $parent_called_class);
  14. }
  15. class ChildClass extends ParentClass
  16. {
  17. }
  18. class ParentClass
  19. {
  20. public function testGetCalledClass()
  21. {
  22. return get_called_class();
  23. }
  24. }
get_class_methods()

get_class_methods()用来获取类的方法名组成一个数组(测试只能是public),Laravel只有一处用到了该方法IlluminateDatabaseEloquentModel::cacheMutatedAttributes() :line 3397,这里写个PHPUnit测试,爆绿灯:

</>复制代码

  1. public function testGetClassMethod()
  2. {
  3. // Arrange
  4. $get_class_methods1 = get_class_methods(ChildClass::class);
  5. $get_class_methods2 = get_class_methods(new ChildClass());
  6. // Actual
  7. // Assert
  8. $this->assertFalse(in_array("testPrivateGetClassMethod", $get_class_methods1, true));
  9. $this->assertFalse(in_array("testPrivateGetClassMethod", $get_class_methods2, true));
  10. $this->assertFalse(in_array("testProtectedGetClassMethod", $get_class_methods1, true));
  11. $this->assertFalse(in_array("testProtectedGetClassMethod", $get_class_methods2, true));
  12. $this->assertTrue(in_array("testPublicGetClassMethod", $get_class_methods1, true));
  13. $this->assertTrue(in_array("testPublicGetClassMethod", $get_class_methods2, true));
  14. $this->assertTrue(in_array("testGetCalledClass", $get_class_methods1, true));
  15. $this->assertTrue(in_array("testGetCalledClass", $get_class_methods2, true));
  16. }
  17. class ChildClass extends ParentClass
  18. {
  19. private function testPrivateGetClassMethod()
  20. {
  21. }
  22. protected function testProtectedGetClassMethod()
  23. {
  24. }
  25. public function testPublicGetClassMethod()
  26. {
  27. }
  28. }
get_class_vars()

get_class_vars()只会读取类的public属性组成一个数组,类似于get_class_methods(),若属性没有默认值就为null,目前Laravel中还未使用,看下PHPUnit测试:

</>复制代码

  1. public function testGetClassVars()
  2. {
  3. // Arrange
  4. // Actual
  5. $class_vars = get_class_vars(ChildClass::class);
  6. // Assert
  7. $this->assertArrayNotHasKey("privateNoDefaultVar", $class_vars);
  8. $this->assertArrayNotHasKey("privateDefaultVar", $class_vars);
  9. $this->assertArrayNotHasKey("protectedNoDefaultVar", $class_vars);
  10. $this->assertArrayNotHasKey("protectedDefaultVar", $class_vars);
  11. $this->assertEmpty($class_vars["publicNoDefaultVar"]);
  12. $this->assertEquals("public_laravel", $class_vars["publicDefaultVar"]);
  13. }
  14. class ChildClass extends ParentClass
  15. {
  16. private $privateNoDefaultVar;
  17. private $privateDefaultVar = "private_laravel";
  18. protected $protectedNoDefaultVar;
  19. protected $protectedDefaultVar = "protected_laravel";
  20. public $publicNoDefaultVar;
  21. public $publicDefaultVar = "public_laravel";
  22. }
get_object_vars()

get_object_vars()只会读取对象的public属性组成一个数组,类似于get_class_vars(), get_class_methods(),且属性没有默认值就是null,Laravel中只有一处使用到IlluminateMailJobsHandleQueuedMessage::__sleep() :line 78,写个PHPUnit测试下,爆绿灯:

</>复制代码

  1. public function testGetObjectVars()
  2. {
  3. // Arrange
  4. $get_object_vars = new TestGetObjectVars(1, 2, 3);
  5. // Actual
  6. $object_vars = get_object_vars($get_object_vars);
  7. // Assert
  8. $this->assertArrayNotHasKey("x", $object_vars);
  9. $this->assertArrayNotHasKey("y", $object_vars);
  10. $this->assertEquals(3, $object_vars["z"]);
  11. $this->assertArrayNotHasKey("dot1", $object_vars);
  12. $this->assertArrayNotHasKey("dot2", $object_vars);
  13. $this->assertArrayNotHasKey("circle1", $object_vars);
  14. $this->assertArrayNotHasKey("circle2", $object_vars);
  15. $this->assertEquals(10, $object_vars["line1"]);
  16. $this->assertEmpty($object_vars["line2"]);
  17. }
  18. class TestGetObjectVars
  19. {
  20. private $x;
  21. protected $y;
  22. public $z;
  23. private $dot1 = 10;
  24. private $dot2;
  25. protected $circle1 = 20;
  26. protected $circle2;
  27. public $line1 = 10;
  28. public $line2;
  29. public function __construct($x, $y, $z)
  30. {
  31. $this->x = $x;
  32. $this->y = $y;
  33. $this->z = $z;
  34. }
  35. }
is_subclass_of()

is_subclass_of()用来判断给定类对象是否是另一给定类名的子类,Laravel中有用到,这里写下PHPUnit测试,爆绿灯:

</>复制代码

  1. public function testIsSubclassOf()
  2. {
  3. // Arrange
  4. $child_class = new ChildClass();
  5. // Actual
  6. $is_subclass = is_subclass_of($child_class, ParentClass::class);
  7. // Assert
  8. $this->assertTrue($is_subclass);
  9. }
is_a()

is_a()用来判定给定类对象是否是另一给定类名的对象或是子类,和is_subclass_of()有点类似,只是is_a()还可以判定是不是该类的对象,is_a()类似于instanceof操作符,Laravel中还没用到这个方法,这里写个PHPUnit测试,爆绿灯:

</>复制代码

  1. public function testIsA()
  2. {
  3. // Arrange
  4. $child_class = new ChildClass();
  5. // Actual
  6. $is_object = is_a($child_class, ChildClass::class);
  7. $is_subclass = is_a($child_class, ParentClass::class);
  8. // Assert
  9. $this->assertTrue($is_object);
  10. $this->assertTrue($is_subclass);
  11. }

最后,给下整个PHPUnit的测试代码:

</>复制代码

  1. assertTrue($class_exists);
  2. }
  3. public function testInterfaceExists()
  4. {
  5. // Arrange
  6. // Actual
  7. $interface_exists = interface_exists(TestInterfaceExists::class);
  8. // Assert
  9. $this->assertTrue($interface_exists);
  10. }
  11. public function testMethodExists()
  12. {
  13. // Arrange
  14. $test_class_exists = new TestClassExists();
  15. // Actual
  16. $object_method_exists1 = method_exists($test_class_exists, "testPrivateMethodExists");
  17. $object_method_exists2 = method_exists($test_class_exists, "testProtectedMethodExists");
  18. $object_method_exists3 = method_exists($test_class_exists, "testPublicMethodExists");
  19. $classname_method_exists1 = method_exists(TestClassExists::class, "testPrivateMethodExists");
  20. $classname_method_exists2 = method_exists(TestClassExists::class, "testProtectedMethodExists");
  21. $classname_method_exists3 = method_exists(TestClassExists::class, "testPublicMethodExists");
  22. // Assert
  23. $this->assertTrue($object_method_exists1);
  24. $this->assertTrue($object_method_exists2);
  25. $this->assertTrue($object_method_exists3);
  26. $this->assertTrue($classname_method_exists1);
  27. $this->assertTrue($classname_method_exists2);
  28. $this->assertTrue($classname_method_exists3);
  29. }
  30. public function testPropertyExists()
  31. {
  32. // Arrange
  33. $test_class_exists = new TestClassExists();
  34. // Actual
  35. $private_property1 = property_exists($test_class_exists, "testPrivatePropertyExists");
  36. $private_property2 = property_exists(TestClassExists::class, "testPrivatePropertyExists");
  37. $protected_property1 = property_exists($test_class_exists, "testProtectedPropertyExists");
  38. $protected_property2 = property_exists(TestClassExists::class, "testProtectedPropertyExists");
  39. $public_property1 = property_exists($test_class_exists, "testPublicPropertyExists");
  40. $public_property2 = property_exists(TestClassExists::class, "testPublicPropertyExists");
  41. // Assert
  42. $this->assertTrue($private_property1);
  43. $this->assertTrue($private_property2);
  44. $this->assertTrue($protected_property1);
  45. $this->assertTrue($protected_property2);
  46. $this->assertTrue($public_property1);
  47. $this->assertTrue($public_property2);
  48. }
  49. public function testTraitExists()
  50. {
  51. // Arrange
  52. // Actual
  53. $test_trait_exists = trait_exists(TestTraitExists::class);
  54. // Assert
  55. $this->assertTrue($test_trait_exists);
  56. }
  57. public function testClassAlias()
  58. {
  59. // Arrange
  60. class_alias(TestClassExists::class, "MyRightCapitalContainerTestsAliasTestClassExists");
  61. $test_class_exists = new TestClassExists();
  62. // Actual
  63. $actual = new AliasTestClassExists();
  64. //Assert
  65. $this->assertInstanceOf(TestClassExists::class, $actual);
  66. $this->assertInstanceOf(AliasTestClassExists::class, $test_class_exists);
  67. }
  68. public function testGetClass()
  69. {
  70. // Arrange
  71. $test_class_exists = new TestClassExists();
  72. // Actual
  73. $class_name = get_class($test_class_exists);
  74. // Assert
  75. $this->assertSame(TestClassExists::class, $class_name);
  76. }
  77. public function testGetParentClass()
  78. {
  79. // Arrange
  80. $child_class = new ChildClass();
  81. // Actual
  82. $parent_class1 = get_parent_class($child_class);
  83. $parent_class2 = get_parent_class(ChildClass::class);
  84. // Assert
  85. $this->assertSame(ParentClass::class, $parent_class1);
  86. $this->assertSame(ParentClass::class, $parent_class2);
  87. }
  88. public function testGetCalledClass()
  89. {
  90. // Arrange
  91. $child_class = new ChildClass();
  92. $parent_class = new ParentClass();
  93. // Actual
  94. $child_called_class = $child_class->testGetCalledClass();
  95. $parent_called_class = $parent_class->testGetCalledClass();
  96. // Assert
  97. $this->assertSame(ChildClass::class, $child_called_class);
  98. $this->assertSame(ParentClass::class, $parent_called_class);
  99. }
  100. public function testInArray()
  101. {
  102. $this->assertTrue(in_array("a", ["a", "b", 1], true));
  103. }
  104. public function testGetClassMethod()
  105. {
  106. // Arrange
  107. $get_class_methods1 = get_class_methods(ChildClass::class);
  108. $get_class_methods2 = get_class_methods(new ChildClass());
  109. // Actual
  110. // Assert
  111. $this->assertFalse(in_array("testPrivateGetClassMethod", $get_class_methods1, true));
  112. $this->assertFalse(in_array("testPrivateGetClassMethod", $get_class_methods2, true));
  113. $this->assertFalse(in_array("testProtectedGetClassMethod", $get_class_methods1, true));
  114. $this->assertFalse(in_array("testProtectedGetClassMethod", $get_class_methods2, true));
  115. $this->assertTrue(in_array("testPublicGetClassMethod", $get_class_methods1, true));
  116. $this->assertTrue(in_array("testPublicGetClassMethod", $get_class_methods2, true));
  117. $this->assertTrue(in_array("testGetCalledClass", $get_class_methods1, true));
  118. $this->assertTrue(in_array("testGetCalledClass", $get_class_methods2, true));
  119. }
  120. public function testGetClassVars()
  121. {
  122. // Arrange
  123. // Actual
  124. $class_vars = get_class_vars(ChildClass::class);
  125. // Assert
  126. $this->assertArrayNotHasKey("privateNoDefaultVar", $class_vars);
  127. $this->assertArrayNotHasKey("privateDefaultVar", $class_vars);
  128. $this->assertArrayNotHasKey("protectedNoDefaultVar", $class_vars);
  129. $this->assertArrayNotHasKey("protectedDefaultVar", $class_vars);
  130. $this->assertEmpty($class_vars["publicNoDefaultVar"]);
  131. $this->assertEquals("public_laravel", $class_vars["publicDefaultVar"]);
  132. }
  133. public function testGetObjectVars()
  134. {
  135. // Arrange
  136. $get_object_vars = new TestGetObjectVars(1, 2, 3);
  137. // Actual
  138. $object_vars = get_object_vars($get_object_vars);
  139. // Assert
  140. $this->assertArrayNotHasKey("x", $object_vars);
  141. $this->assertArrayNotHasKey("y", $object_vars);
  142. $this->assertEquals(3, $object_vars["z"]);
  143. $this->assertArrayNotHasKey("dot1", $object_vars);
  144. $this->assertArrayNotHasKey("dot2", $object_vars);
  145. $this->assertArrayNotHasKey("circle1", $object_vars);
  146. $this->assertArrayNotHasKey("circle2", $object_vars);
  147. $this->assertEquals(10, $object_vars["line1"]);
  148. $this->assertEmpty($object_vars["line2"]);
  149. }
  150. public function testIsSubclassOf()
  151. {
  152. // Arrange
  153. $child_class = new ChildClass();
  154. // Actual
  155. $is_subclass = is_subclass_of($child_class, ParentClass::class);
  156. // Assert
  157. $this->assertTrue($is_subclass);
  158. }
  159. public function testIsA()
  160. {
  161. // Arrange
  162. $child_class = new ChildClass();
  163. // Actual
  164. $is_object = is_a($child_class, ChildClass::class);
  165. $is_subclass = is_a($child_class, ParentClass::class);
  166. // Assert
  167. $this->assertTrue($is_object);
  168. $this->assertTrue($is_subclass);
  169. }
  170. }
  171. class TestGetObjectVars
  172. {
  173. private $x;
  174. protected $y;
  175. public $z;
  176. private $dot1 = 10;
  177. private $dot2;
  178. protected $circle1 = 20;
  179. protected $circle2;
  180. public $line1 = 10;
  181. public $line2;
  182. public function __construct($x, $y, $z)
  183. {
  184. $this->x = $x;
  185. $this->y = $y;
  186. $this->z = $z;
  187. }
  188. }
  189. class ChildClass extends ParentClass
  190. {
  191. private $privateNoDefaultVar;
  192. private $privateDefaultVar = "private_laravel";
  193. protected $protectedNoDefaultVar;
  194. protected $protectedDefaultVar = "protected_laravel";
  195. public $publicNoDefaultVar;
  196. public $publicDefaultVar = "public_laravel";
  197. private function testPrivateGetClassMethod()
  198. {
  199. }
  200. protected function testProtectedGetClassMethod()
  201. {
  202. }
  203. public function testPublicGetClassMethod()
  204. {
  205. }
  206. }
  207. class ParentClass
  208. {
  209. public function testGetCalledClass()
  210. {
  211. return get_called_class();
  212. }
  213. }
  214. class TestClassExists
  215. {
  216. private $testPrivatePropertyExists;
  217. protected $testProtectedPropertyExists;
  218. public $testPublicPropertyExists;
  219. private function testPrivateMethodExists()
  220. {
  221. }
  222. protected function testProtectedMethodExists()
  223. {
  224. }
  225. public function testPublicMethodExists()
  226. {
  227. }
  228. }
  229. interface TestInterfaceExists
  230. {
  231. }
  232. trait TestTraitExists
  233. {
  234. }

PHP不仅提供了检测class, interface, trait, property, method这些函数Introspection Functions,还提供了一整套的API即反射来检测class, interface, trait, property, method,这些API是好几个类组成的,提供了很多好用的方法。限于篇幅,下篇再聊下反射API。

总结:本文主要聊了下PHP提供的一套检测class, interface, trait, property, method的两个工具包:Introspection Functions和Reflection API,这里先聊到Introspection Functions。下篇再聊下Reflection API的使用,到时见。

欢迎关注Laravel-China。

RightCapital招聘Laravel DevOps

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30477.html

相关文章

  • Laravel深入学习2 - 控制反转容器

    摘要:控制反转容器控制反转使依赖注入变得更加便捷。有瑕疵控制反转容器是实现的控制翻转容器的一种替代方案。容器的独立使用即使没有使用框架,我们仍然可以在项目中使用安装组件来使用的控制反转容器。在没有给定任何信息的情况下,容器是无法实例化相关依赖的。 声明:本文并非博主原创,而是来自对《Laravel 4 From Apprentice to Artisan》阅读的翻译和理解,当然也不是原汁原味...

    worldligang 评论0 收藏0
  • PHP高级特性-反射Reflection以及Factory工厂设计模式的结合使用[代码实例]

    摘要:反射提供给面向对象编程可以自省的能力,即反射。在简单工厂模式中,根据传递的参数来返回不同的类的实例简单工厂模式又称为静态工厂方法模式。也就是简单工厂模式工厂工厂类。PHP高级特性-反射以及工厂设计模式的结合使用 [结合 Laravel-Admin 代码实例讲解]利用反射来实现工厂模式的生产而无需创建特定的工厂类本文地址http://janrs.com/?p=833转载无需经过作者本人授权转载...

    番茄西红柿 评论0 收藏2637
  • PHP反射机制

    摘要:反射机制反射机制从开始支持,做业务开发的话应该很少接触反射。我的理解就是反射机制能拿到类里面的属性方法,和的也可以以上是官方文档中给出的东西,说实话我看了感觉没什么感觉。在容器成员变量中数组维护这个类,反射实例调用构造函数,获取返回值。 PHP反射机制 PHP反射机制从PHP5开始支持,做业务开发的话应该很少接触反射。我其实也是接触不多,最近在学习laravel的优雅,就接触了到它其中...

    URLOS 评论0 收藏0
  • Essential SQLAlchemy2th学习笔记反射Reflection

    摘要:基于反射对象进行查询模块反射这里我们不再使用而是使用扩展模块的获取所有的对象名获取表对象进行操作反射关联关系可以反射并建立表之间的但是建立关联列的命名为例如关于更多信息请详细参看官方文档 示例数据库下载:http://chinookdatabase.codepl...在SQLALchemy中,我们使用反射技术来获取相关database schema信息,如tables,views,in...

    NSFish 评论0 收藏0
  • 详解 Laravel 中的依赖注入和 IoC

    摘要:依赖注入依赖注入一词是由提出的术语,它是将组件注入到应用程序中的一种行为。就像说的依赖注入是敏捷架构中关键元素。类依赖于,所以我们的代码可能是这样的创建一个这是一种经典的方法,让我们从使用构造函数注入开始。 showImg(https://segmentfault.com/img/remote/1460000018806800); 文章转自:https://learnku.com/la...

    haitiancoder 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<