关于魔术方法??

关于魔术方法??

<?php
class Example
{
    //不可访问的属性
    protected $imooc="yes!";

   //不可访问的普通方法
    private function imooc(){
       echo "问慕课!";
   }
    
//不可访问的静态方法
    private static function imoocReal(){
       echo "还真真滴问慕课!他就是不告诉你";
   }
    //魔术方法
    public function __set($n,$v){
      
        if($n=='imooc'){
        //注意这里!!!
          $this->$imooc = $v; 
          echo "给不可访问属性赋值时触发".$n;
        }else{
            echo"弄死你啊,设置你妹啊!";
        }
    }
     public function __get($n){
      //注意这里!!!
        //  echo $this->$imooc;
        if($n=='imooc'){
          echo "调用不可访问属性时触发" .$n;
        }else{
            echo"弄死你啊,得不到!";
        }
    }
     public function __isset($n){
        if($n=='imooc'){
          
          echo "对不可访问属性使用empty与isset()时触发" .$n."已经设置";
        }else{
            echo"弄死你啊,谁知道空不空?";
        }
    }
    public function __unset($n){
        if($n=='imooc'){
          
          echo "对不可访问属性使用empty与isset()时触发" .$n."已经销毁";
        }else{
            echo"弄死你啊,销毁了!";
        }
    }
    public function __call($name,$arg){
        if($name=='imooc'){
             echo "调用不可访问动态方法".$name."时触发<br>";
             var_dump($arg);
        }else{
            echo "你大爷的,谁知道你触发了什么!!!!";
        }
       
    }
        public static function __callStatic($name,$arg){
         if($name=='imoocReal'){
                echo "调用不可访问动态方法".$name."时触发<br>";
                 var_dump($arg);
            }else{
             echo "你大爷的,谁知道你触发了什么!!!!";
            }
       
    }
}
//实例化对象
$imooc = new Example;
//触发各种魔术方法
echo $imooc->imooc;
echo "<hr>";
$imooc->imooc = "真傻!";
echo "<hr>";
$imooc->imooc("慕课很呵呵呵!","我也是这么认为的!");
echo "<hr>";
Example::imoocReal("慕课很呵呵呵!!!","我也是这么认为的!");
echo "<hr>";
isset($imooc->imooc);
echo "<hr>";
unset($imooc->imooc);
echo "<hr>";
?>

http://img1.sycdn.imooc.com//climg/5c2efd06000132f904990584.jpg

  1. 我再使用__set、和__get方法时发现,第一次访问的属性名 都不是 调用时的属性名,都触发了else里的代码,这是为什么?

  2. 我猜想可能__set、和__get方法,也适用于类的内部调用??

  3. 在__get()方法里我调用了echo $this->$imooc; 但是读不出来还警告?这是为啥?

  4. 在__set()方法,我加了$this->$imooc = $v; 但是会先走一遍else语句,我猜这里又触发了__set()方法,这是为啥???

正在回答

登陆购买课程后可参与讨论,去登陆

2回答

您好,魔术方法的作用:在给不可访问属性赋值时,__set() 会被调用。读取不可访问属性的值时,__get() 会被调用。    

  1. 类外不可以调用和赋值受保护的$imooc属性,因此触发__set()__get()方法。

  2. 适用,第四点则是因为这个原因。

  3. 输出属性值应该是:echo $this->imooc;。

  4. $this->$imooc = $v;中属性不存在则调用__set输出else区间内容。__set方法中写为$this->imooc = $v;则不会出现报错。设置属性出错。

另请同学采用文明用语。如果解决了您的问题,请采纳。祝学习愉快!

  • 轩辕小齐V 提问者 #1
    1.关于我提问的第②条,我有点疑问:__set($n,$v)方法中是$this->$n的方式,那么在__get($n)方法内,不是直接用$this->$n?到底如何区别,如何使用,视频里也没有讲的很明白,麻烦老师好好讲下,感谢! 2.关于第四条同样不明白,视频李老师命名说__set($n,$v) 里使用的是$this->$n=$v,而不是$this->n=$v,到底什么书写?学生越来越糊涂了~~~~/(ㄒoㄒ)/~~
    2019-01-06 15:38:06
  • 好帮手慕查理 回复 提问者 轩辕小齐V #2
    您好,__set和__get方法中如果是操作的是属性名,例如代码中是$this->$imooc = $v;和echo $this->$imooc;操作的属性名,那么就不需要在属性名前添加$,但如果是使用的方法的传参$n,那么操作时则需要添加上$,即$this->$n = $v;和echo $this->$n;。祝学习愉快!
    2019-01-07 11:13:38
  • 轩辕小齐V 提问者 回复 好帮手慕查理 #3
    老师,我发现如果直接在__set($n,$v)使用$this->$imooc,这是不对的貌似,但是直接使用$this->$n = $v,就不会报错。这里是不是只能使用$this->$n,而不能直接使用$this->$imooc,那么直接在 __set中使用$this->imooc=$v 与$this->$n=$v 效果是一样的呗?
    2019-01-07 13:28:14
imooc的铁粉 2019-01-04 14:52:04

老师每天看见你这样的学生,还活着真是万幸,你上学的时候也是这样一边问老师一边骂吗,不敢恭维

  • 提问者 轩辕小齐V #1
    您那只眼睛看见我骂人了?莫非我还@某个老师了?您不会又是慕课员工的小号吧?眼睛睁大点,兄弟我没骂人OK?我今天跟你唠唠: 中国的教育就是这样,连老师都是XX制的,就算听不懂老师讲啥你爸你妈,还有你也得当神仙供着,校长也不会开除他,你也只能再上个辅导班,中国人要尊师,更要尊值得尊的师;正所谓,闻道有先后术业有专攻,老师值得尊的地方,是其能够为我们传道受业解惑,再看看慕课,我学完路径1,已然是吐槽无数,未吐出来的,已然又咽了进去。慕课试听太少,凭借几位优秀的老师树立了口碑,但是实战课,几位大神不会非常详细的回答问题,这也是问题之一;就业班视频老旧,就不再说MySQL那里的金斧子与鉄斧子,更不必说最后的Ecshop,最终也没讲源码分析,那是搞笑么?更更不必说,js 直接等于没讲,还有无数的问题,此处省略一万字。 若您是慕课员工小号,那么请您玩蛋去,哥们我是顺手这么写,正所谓 我即画中人,画中人即我,你说你被骂,那是你的事儿,心不净,勿要加罪于人! 如果 您只是一位学生,那请您回答问题或者共勉,你我都在陷阱中又何必,五十步笑百步?
    2019-01-04 15:11:26
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师