PHP类成员的重载与命名空间

2021年02月23日 17:57:39阅读数:28博客 / Jason Pu? /

一:类成员重载的原理与实现

php所提供的“重载”是指通过魔术方法来动态的“创建”类属性和方法。
当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用,所以重载的方法都必须被声明为public。

1.属性重载:

名称 属性
public __set($name,$value) 在不给不可访问属性赋值时,__set会被调用
public __get($name) 读取不可访问属性的值时,__get会被调用
public __isset($name) 当对不可访问属性调用isset()或empty()时,__isset会被调用
public __unset($name) 当对不可访问属性调用unset()时,__unset()会被调用

参数$name是指要操作的变量名称,__set()方法的$value参数指定了$name变量的值 —>

示例:

  1. class PropertyTest {
  2. // 被重载的数据保存在此
  3. private $data = array();
  4. public function __set($name,$value)
  5. {
  6. echo "Setting '$name' to '$value' \n";
  7. $this->data[$name]=$value;
  8. }
  9. }
  10. $obj = new PropertyTest;
  11. $obj->a = 1;
  12. //以上会输出:Setting 'a' to '1'

2.方法重载

名称 属性
public __call($name,$arguments) 在对象中调用一个不可访问方法时,__call()会被调用
public static __callStatic($name,$arguments) 在静态上下文中调用一个不可访问方法时,__callStatic会被调用

示例:

  1. class MethodTest
  2. {
  3. public function __call($name,$arguments)
  4. {
  5. echo "Call object method '$name'". implode(',',$arguments)."\n";
  6. }
  7. public static function __callStatic($name,$arguments)
  8. {
  9. echo "Call static method '$name'". implode(",",$arguments)."\n";
  10. }
  11. }
  12. $method_obj = new MethodTest;
  13. $method_obj->runTest('in object context');
  14. //运行结果:Call object method 'runTest'in object context
  15. echo "<br>";
  16. MethodTest::runTest('in static context');
  17. //运行结果:Call static method 'runTest'in static context

二.PHP中的全局成员

PHP中的全局成员有:类(class),常量(const),函数(function);
全局成员的特点是:一旦定义就不能重复声明,例如:

  1. const abc = 123;
  2. const abc = 321;
  3. class a{
  4. }
  5. class a{
  6. }

运行后会出现报错:

为了解决此类问题接下来我们需要接触命名空间的概念


三.命名空间

概述: 在 PHP 中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:
1.用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
2.为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

1.命名空间的创建与访问:

  1. namespace a
  2. {
  3. $title = "php中文网";
  4. echo "当前空间的变量:".$title;//本空间访问
  5. echo "<br>";
  6. const name = 'Jasper';
  7. }
  8. namespace b
  9. {
  10. echo '访问另一个空间中的变量'.$title;
  11. }
  12. //全局命名空间:
  13. namespace
  14. {
  15. echo "<hr>";
  16. echo '全局空间中访问另一空间中的变量'.$title;
  17. echo "<hr>";
  18. echo a\name;
  19. }

运行结果:


2.命名空间成员的分解与合并操作:

为了防止一个空间中的代码过大,可以将同一空间的代码写到多个脚本中:
例如创建一个test1的php文件,再创建一个命名空间:

  1. namespace ns;
  2. class test1{
  3. //...
  4. }

再创建一个test2的php文件,并在当中创建同名的命名空间和不同的类名:

  1. namespace ns;
  2. class test2{
  3. //...
  4. }

再到另一个文件引入,并验证:

  1. namespace ns;
  2. require 'test1.php';
  3. require 'test2.php';
  4. echo test1::class,'<br>';
  5. echo test2::class;

运行结果如下:


3.子命名空间中访问任何空间中成员的方式:

例如我们创建一个命名空间,并创建两个子空间:

  1. //父空间:
  2. namespace father{
  3. class test
  4. {
  5. }
  6. }
  7. //子空间:
  8. namespace father\son{
  9. class test
  10. {
  11. }
  12. }
  13. //son的子空间:
  14. namespace father\son\grandson{
  15. class test
  16. {
  17. }
  18. }

在子空间访问任何空间的方法:

  1. //子空间:
  2. namespace father\son{
  3. class test
  4. {
  5. }
  6. //访问它的子空间grandson的方法:
  7. echo grandson\test::class,"<br>";
  8. }
  9. //son的子空间:
  10. namespace father\son\grandson{
  11. class test
  12. {
  13. }
  14. //访问它的上级空间:
  15. echo \father\son\test::class,'<br>';
  16. echo \son\test::class,'<br>';
  17. }

运行结果:

批改状态:合格

老师批语:

全部评论

文明上网理性发言,请遵守新闻评论服务协议

条评论
  • 博主信息
    Jason Pu?
    博文
    36
    粉丝
    1
    评论
    0
    访问量
    2889
    积分:0
    P豆:82