zoukankan      html  css  js  c++  java
  • 周末,说声php的setter&getter(魔术)方法,你们辛苦了

       php 作为快速迭代项目的语言,其牛逼性质自不必多说。今天咱们要来说说php语言几个魔术方法,当然了,本文主要以setter&getter方法说明为主。

      首先,咱们得知道什么叫魔术方法? 官方定义为:__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等方法在 PHP 中被称为"魔术方法"(Magic methods)。在命名自己的类方法时不能使用这些方法名,除非是想使用其魔术功能。

      妈蛋,看了这么长一句,还是不明白什么叫魔术方法?

      换句简单的话就是(片面的),普通方法做不了的事,这个方法能做到,这就是魔术方法! 总之就是,你平时一般不会用到的方法。

      好,现在咱们来说说,哪几个方法是咱们用得最多的呢?当然是 __construct, __destruct 了,创建一个类时,会使用到构造方法(__construct),你可以初始化你的基本数据在里面。销毁一个类时,则会调用析构方法(__destruct),你可以回收一些东西。

      除了这前面两个方法之外,其他的方法就不一定是每个同学都会用得上的功能了。如果说一定要使用的话,那可能还会用到 __call 方法,因为有时候你可能就是要让外面访问你某些变异了的方法,以迷惑对手。

      那么,回到本文话题,php的setter&getter方法,其实就是 __set & __get 方法,为什么说是setter&getter呢,因为在面向对象语言中,就是setXX($value),getXX(); 这两个魔术方法有什么用呢?

      首先,我们还是魔术方法的方针政策上,魔术方法是具有魔术的,是不能随便调用的,它只会在特定的情况下才会生效。

      那么__set 方法呢,就是在你在设置某个类属性变量的时候(如$obj->mm = "c";),如果没有找到这个变量或者该变量不可访问,那么__set就会生效被调用了。

      而 __get 方法,就是在你获取类的某个类属性变量的时候(如$a = $obj->mm),如果访问不到这个属性,那么 __get就会生效被调用了。 举例:

    <?php
        error_reporting(E_ALL^E_NOTICE);
        class SampleMagicTest {
            public $a;
            private $privVar = "privateVar";
            protected $protectedVar = "protectedVar";
            public function __construct($a) {
                $this->a = $a;
                var_dump("in __construct method....", $a);
            }
            public function __set($name, $value) {
                echo "in __set method...
    ";
                $this->$name = $value;            //设置$name属性为该类属性变量,我猜测修饰符应该是 private, 也就是说 外部仍然是访问不到该变量的,但是结果却让我失望了,居然被设置成public,也就是说,你可直接访问到该变量了
                //当然了,你还可以做其他没用的事
            }
            public function __get($name) {
                echo "in __get method...
    ";
                return $this->$name;            //返回类属性变量 $name, 该$name通常是私有的变量
                //当然了,你还可以做其他没用的事
            }
            public function __call($name, $arguments) {
                var_dump("you called a none defined method,methodName is:", $name, " args is:", $arguments);
            }
            public function __destruct() {
                echo "in __construct method...
    ";
                return "SampleMagicTest.class.toString
    ";
            }
            public function __toString() {
                echo "in __toString method...
    ";
            }
        }
        $sample = new SampleMagicTest("1");
        $sample->yourName = "jue";                //属性不存在, __set 魔术将生效
        echo "yourName:" . $sample->yourName . PHP_EOL;        //由于前面的 __set已经将变量放入,此处可以直接调用,没毛病
        var_dump($sample->aNoneExistVar);        //直接调用一个不存在的变量
        $sample->sayHi("hello");            //调用一个不存在的方法,则会触发 __call方法,也就是说,当有了 __call方法之后,php就再也不会报方法未定义之类的错误了,这坑可是不小哦
        var_dump($sample);    
        unset($sample);            // 可以主动调用销毁方法,当然了,实际开发中是不建议这么干的
        echo "real over...";
    ?>

      输出结果如下:

    $-#: php SampleMagicTest.php
    string(25) "in __construct method...."
    string(1) "1"
    in __set method...
    yourName:jue
    in __get method...
    NULL
    string(47) "you called a none defined method,methodName is:"
    string(5) "sayHi"
    string(9) " args is:"
    array(1) {
      [0]=>
      string(5) "hello"
    }
    in __toString method...
    SampleMagicTest.class.toString
    object(SampleMagicTest)#1 (4) {
      ["a"]=>
      string(1) "1"
      ["privVar":"SampleMagicTest":private]=>
      string(10) "privateVar"
      ["protectedVar":protected]=>
      string(12) "protectedVar"
      ["yourName"]=>
      string(3) "jue"
    }
    in __construct method...
    real over...

      如此,测试完毕。 

      说实话,我一点都没感觉到 __set&__get 方法的方便之处在哪里,而__call方法反而作用会大些(有坑自己别往里跳就行),尤其作为反射功能的调用时。

      而我能想到的setter&getter的作用,则更多的是提示你在获取属性时,IDE能给你一个准确的提示,那将是美好的。

      我看过某人写过的代码,将某个配置设值功能作为调用 __set方法的场景(如: public funtion($name, $value) {$this->config[$name] = $value;},这种情况,恕在下不敢苟同。你直接写个易记的方法不就行了吗?

      魔术方法存在自然有其过人之处,但是,并不是每个场景都能使用,大部分情况可能只需要看看就好。

      如果一定要给这些魔术方法的功能重要性排个序的话,我想官方已经把他排出来了。

      你有什么场景在用这些牛逼的魔术方法呢?不访说出来,吓我一跳。。。

  • 相关阅读:
    Luogu P1396 营救
    Luogu P1339 热浪Heat Wave
    哈夫曼树学习笔记
    题解 CF1372C
    题解 CF 1372 B
    题解 CF 1372A
    题解 UVA1193 Radar Installation
    题解 洛谷 P2287 [USACO07NOV]Sunscreen G
    洛谷 P1080 国王游戏 题解
    牛客练习赛 66C公因子 题解
  • 原文地址:https://www.cnblogs.com/yougewe/p/7182834.html
Copyright © 2011-2022 走看看