PHP8.1.21版本已发布
vue8.1.21版本已发布
jquery8.1.21版本已发布

博客列表 > PHP基础: 类的重载和命名空间的部分知识(声明, 调用,分解与合并, 子空间和子空间的调用)

PHP基础: 类的重载和命名空间的部分知识(声明, 调用,分解与合并, 子空间和子空间的调用)

zl的php学习博客
zl的php学习博客 原创
2021年02月23日 15:46:16 693浏览

1. 描述类成员重载的原理与实现;

  1. 1.原理: 动态的创建属性和方法.
  2. 2.实现: 通过魔术方法[__set,__get,__isset,__unset,__call,__callStatic]来实现.

实例:

  1. // 实例:
  2. class Demo1
  3. {
  4. private $overloadData = [];
  5. public $name;
  6. public $email;
  7. public function __construct($name, $email)
  8. {
  9. $this->name = $name;
  10. $this->email = $email;
  11. }
  12. public function getUser(): string
  13. {
  14. return "{$this->name} : {$this->email}";
  15. }
  16. public function insertData($name): string
  17. {
  18. $this->overloadData[$name] = $name;
  19. echo nl2br("创建成功...\n");
  20. return $this->overloadData[$name];
  21. }
  22. // 当调用未设置的属性时,会自动调用
  23. public function __get($name): string
  24. {
  25. if (array_key_exists($name, $this->overloadData)) {
  26. return $this->overloadData[$name];
  27. } else {
  28. echo nl2br("没有该属性$name, 尝试创建中.....\n");
  29. return $this->insertData($name);
  30. }
  31. }
  32. // 当对未设置的属性赋值时,会自动调用
  33. public function __set($name, $value)
  34. {
  35. // echo "$name : $value<br>";
  36. $this->overloadData[$name] = $value;
  37. }
  38. // 当对未设置的属性调用isset()方法并且时,会自动调用
  39. public function __isset($name): string
  40. {
  41. echo "Is '{$name}' set?\n";
  42. return isset($this->overloadData[$name]);
  43. }
  44. // 当对未设置的属性调用unset()方法并且时,会自动调用
  45. public function __unset($name)
  46. {
  47. echo "类实例中没有 '$name'\n";
  48. unset($this->overloadData[$name]);
  49. }
  50. // 当访问的非静态方法不存在时,会自动调用该方法
  51. public function __call($funcName, $ages)
  52. {
  53. return "函数名: $funcName, 参数: [" . implode(', ', $ages) . "]";
  54. }
  55. // 当访问的静态方法不存在时,会自动调用该方法
  56. public static function __callStatic($funcName, $ages)
  57. {
  58. return "静态函数名: $funcName, 参数: [" . implode(', ', $ages) . "]";
  59. }
  60. }
  61. $objTest0222 = new Demo1('张三', 'admin@test.com');
  62. echo $objTest0222->name, '<br>';
  63. echo $objTest0222->email, '<br>';
  64. echo $objTest0222->getUser(), '<hr>';
  65. // 调用没有创建的属性
  66. echo $objTest0222->a, '<br>';
  67. echo '<hr>';
  68. // 对为创建的属性赋值
  69. $objTest0222->aa = '随便赋的值';
  70. echo $objTest0222->aa, '<br>';
  71. echo '<hr>';
  72. // 对未创建的属性调用isset或者unset
  73. var_dump(isset($objTest0222->aaa));
  74. unset($objTest0222->aaa);
  75. echo '<hr>';
  76. // 调用没有创建的方法时
  77. // 非静态方法
  78. echo $objTest0222->testtest(1,2,3,4,5,6), '<br>';
  79. echo Demo1::testtestStatic(...([6,5,4,3,2,1])), '<br>';

2. 全局成员有哪几种,有什么特点,并实例演示;

  1. 全局成员: 类, 常量, 函数
  1. const PATH = '/0222/test2/';
  2. class Test2Demo1
  3. {
  4. //...
  5. }
  6. function test2Demo1()
  7. {
  8. // ....
  9. }

3. 空间的声明与空间成员的访问;

  1. // 命名空间的创建由关键值nampspace修饰
  2. namespace ts {
  3. }
  4. // 访问空间成员
  5. namespace ts1 {
  6. const PATH = '/0222/test2';
  7. class Test2Demo1
  8. {
  9. public function text2Demo1(): string
  10. {
  11. return '我是空间内类的函数: ' . __METHOD__;
  12. }
  13. }
  14. function test2Demo1(): string
  15. {
  16. return '我是空间内的函数: ' . __FUNCTION__;
  17. }
  18. echo PATH, '<br>'; // 或者 \ts1\PATH 或者 namespace\PATH ,这三种方式访问都可以
  19. echo (new Test2Demo1())->text2Demo1(), '<br>';
  20. echo test2Demo1(), '<br>';
  21. }

4. 空间成员的分解与合并操作;

空间成员的分解: 当一个空间内的代码过长时,可以把同一个空间内的代码分解到多个php脚本文件中.

空间成员的合并: 只要把分解出去的脚本文件在reqire到一个文件中就实现了合并.

实例:

test2-1.php: 主空间

  1. <?php
  2. namespace test2;
  3. require 'test2-2.php';
  4. require 'test2-3.php';
  5. const PATH = '/0222/test2';
  6. // 访问空间成员
  7. echo PATH, '<br>';
  8. echo (new Test2Demo1())->text2Demo1(), '<br>';
  9. echo test2Demo1(), '<br>';

test2-2.php

  1. <?php
  2. namespace test2;
  3. class Test2Demo1
  4. {
  5. public function text2Demo1(): string
  6. {
  7. return '我是空间内类的函数: ' . __METHOD__;
  8. }
  9. }

test2-3.php

  1. <?php
  2. namespace test2;
  3. function test2Demo1(): string
  4. {
  5. return '我是空间内的函数: ' . __FUNCTION__;
  6. }

5. 子空间,并在子空间中访问任何空间中的成员的方式;

子空间: PHP 命名空间允许指定层次化的命名空间的名称,因此,命名空间的名字可以使用分层次的方式定义

  1. <?php
  2. namespace test3 {
  3. function test31(): string
  4. {
  5. return "我是父级空间的方法" . __METHOD__;
  6. }
  7. echo "当前空间: " . __NAMESPACE__, "<br>";
  8. echo test31(), "<hr>";
  9. echo '------------------调用下级空间的成员------------------<br>';
  10. // namespace\test3One\test1() 和 \test3\test3One\test1() 也是一样的效果
  11. // namespace: 代指当前空间,类似于class中的$this和self
  12. echo "test3\\test3One空间的成员: ", test3One\test1(), "<br>";
  13. }
  14. namespace test3\test3One{
  15. function test1(): string
  16. {
  17. return "我是子空间的方法" . __METHOD__;
  18. }
  19. echo "当前空间: " . __NAMESPACE__, "<br>";
  20. echo test1(), "<hr>";
  21. echo '------------------调用下级空间的成员------------------<br>';
  22. echo "test3\\test3One\\test3Two空间的成员: ", test3Two\test2(), "<br>";
  23. echo '------------------调用上级空间的成员------------------<br>';
  24. echo "test3空间的成员: ", \test3\test31(), "<br>";
  25. }
  26. namespace test3\test3One\test3Two{
  27. function test2(): string
  28. {
  29. return "我是子空间的方法" . __METHOD__;
  30. }
  31. echo "当前空间: " . __NAMESPACE__, "<br>";
  32. echo test2(), "<hr>";
  33. echo '------------------调用上级空间的成员------------------<br>';
  34. echo "test3空间的成员: ", \test3\test31(), "<br>";
  35. echo "test3\\test3One空间的成员: ", \test3\test3One\test1(), "<br>";
  36. }
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议