php中魔术方法是什么
admin
2023-07-02 20:04:54
0

类中的魔术方法

PHP 魔术方法指的是在某些时刻会自动被调用的内置函数,它们以两个连续的下划线开头。

类中的魔术方法

__construct()

类的构造函数,用于初始化对象,在对象实例化时自动运行

__destruct()

析构函数,用于在 php 运行终止时,释放对象所占用的内存。析构函数是 php 的垃圾回收机制,使用栈结构,后进先出。

构造函数和析构函数的例子

class computer{

    private $brand;

    function __construct($brand){
        $this->brand = $brand;
    }

    function __destruct(){
        echo "release ".$this->brand."
";     } } $myComputer = new computer("MAC"); $yourComputer = new computer("Asus"); $hisComputer = new computer("Dell"); echo "end of php file
";

输出结果如下所示

end of php file
release Dell
release Asus
release MAC

可以发现析构函数在 php 文件执行结束之后才执行

__get($name)

类中用 protected 和 private 关键字定义的成员属性或方法是无法通过对象的实例访问的。__get() 方法会且仅会在对象的实例访问 proctected 和 private 成员属性 时自动执行 (访问成员方法时不会,因为没有意义)。

__get() 方法的意义在于将 proctected 和 private 成员属性进行处理后输出。

__get() 有且仅有一个输入参数

__get() 方法的一个例子

class computer{

    private $brand;
    protected $owner;
    public $price;

    function __construct($brand, $owner, $price){
        $this->brand = $brand;
        $this->owner = $owner;
        $this->price = $price;
    }


    function __get($name){
        echo "It's up to me to decide if let you konw the owner and the brand of this computer or not :)
";         echo "I will tell you the name of woner: ".$this->owner."
";         echo "I won't tell you that the brand is ".md5($this->brand)."
";         echo "
";     }     function __destruct(){         echo "release ".$this->brand."
";     } } $myComputer = new computer("MAC", "me", "1000"); $yourComputer = new computer("Asus", "you", "500"); $hisComputer = new computer("Dell", "his", "700"); echo $myComputer->price;  echo "

"; echo $myComputer->owner; echo $yourComputer->brand; echo "end of php file
";

输出如下

1000

It's up to me to decide if let you konw the owner and the brand of this computer or not :)
I will tell you the name of woner: me
I won't tell you that the brand is 2e25c285356cbb0ed8785a1377027d79

It's up to me to decide if let you konw the owner and the brand of this computer or not :)
I will tell you the name of woner: you
I won't tell you that the brand is cb6ab3315634a1e4d11b091ba48b60ba

end of php file
release Dell
release Asus
release MAC

可以看到,当访问 public 成员属性 price 时,__get()方法并没有被调用。输出 brand 时,我们使用了 md5 对其进行了加密处理,这种对封装的成员属性进行处理后输出的用法就是 get 方法的意义所在。

__set($name, $value)

__set($name, $value) 与用于给当前类中封装的方法或属性进行重新赋值或定义。

与 get 类似但不同的时,__set($name, $value)会在成员属性被访问赋值时自动执行,其中 $name 是被访问的成员属性名,$value 为成员属性被赋予的值

__set() 的例子

class computer{

    private $brand;
    protected $owner;

    function __construct($brand, $owner, $price){
        $this->brand = $brand;
        $this->owner = $owner;
        $this->price = $price;
    }


    function __get($name){
        echo "It's up to me to decide if let you konw the owner and the brand of this computer or not :)
";         echo "I will tell you the name of woner: ".$this->owner."
";         echo "I won't tell you that the brand is ".md5($this->brand)."
";         echo "
";     }     function __set($name, $value){         $this->owner = $value;         echo "set $name to $value"."

";     }     function __destruct(){         echo "release ".$this->brand."
";     } } $myComputer = new computer("MAC", "me", "1000"); echo $myComputer->owner = "my friend"; echo $myComputer->owner; echo "end of php file
";

输出结果

set owner to my friend

my friendIt's up to me to decide if let you konw the owner and the brand of this computer or not :)
I will tell you the name of woner: my friend
I won't tell you that the brand is 2e25c285356cbb0ed8785a1377027d79

end of php file
release MAC

我们看到在给 owner 赋值时调用了 set , 而访问属性时,调用了 get 。

__tostring()

用于直接打印对象句柄,也就是说当我们使用 echo 加对象名时,__torsring()将会被自动调用

__tosring() 例子

class computer{

    function __tostring(){
        return "This is a computer class";
    }
}

$myComputer = new computer();
echo $myComputer;

如果没有 __totring() 方法,我们是无法使用 echo+对象名,会出现 fatal error

__call($method, $arguments)

当我们调用不存在的方法时,__call() 会自动执行,用于进行异常处理,并使程序继续正常运行

__call() 例子

class computer{

    function start(){
        echo "starting computer
";     }     function __call($m, $a){         echo "erro function: ".$m;         echo "
";         echo "error param: ";         print_r($a);         echo "
";     } } $myComputer = new computer(); $myComputer->start(); $myComputer->shutdown('10 min', '20 min'); echo "here";

输出结果为

starting computer
erro function: shutdown
error param: Array ( [0] => 10 min [1] => 20 min ) 
here

我们可以看到,$method 返回了错误的函数名,而 arguments 返回了参数,最后输出了 "here" 说明程序继续正常运行。

__clone() 方法 和 clone 关键字

clone 关键字用于复制对象,__clone() 方法实在克隆对象时自动调用的函数

clone 例子

class computer{

    public $name;

    function __clone(){
        echo "A computer has been cloned
";     } } $myComputer = new computer(); $youComputer = $myComputer; $youComputer->name = 'pc1'; echo "My computer's name is ".$myComputer->name."
"; echo "
"; $hisComputer = clone $myComputer; $hisComputer->name = 'pc2'; echo "My computer's name is ".$myComputer->name."
"; echo "His computer's name is ".$hisComputer->name."
";

输出结果

My computer's name is pc1

A computer has been cloned
My computer's name is pc1
His computer's name is pc2

我们看到用 = 号并不能复制对象,只是为对象添加了一个别名而已,这里 $myComputer 和 $youComputer 指向同一块内存,修改了 $youComputer 的值相当于修改了 $myComputer 的值。

__autolaod()

在实例化对象时,__autolaod() 会自动被调用,用于快速取得对应的类文件

__autoload() 例子

带 try, catch 异常处理的例子

function __autoload($class_name){
    echo "want to load ".$class_name."
";     if(file_exists($class_name.".class.php")){         include($class_name.".class.php");     }else{         throw new Exception("Unable to laod ".$class_name.".class.php");     } } try{     $obj = new myClass(); } catch(Exception $e){     echo $e->getMessage()."
"; }

相关内容

热门资讯

网红“悍马糖”被查 近日,据江苏南京《金陵警事》报道:看似普通糖果,号称“增强精力”,实则暗藏致命风险。南京秦淮警方成功...
灶具打不着火原因 1、如果灶具进入了过压保护的时候,灶具是不会打火启动的,所以这样就会导致灶具打不着火的问题发生。2、...
灶一边打不着火 1、可能是由于一边的打火针上面比较脏,出现点火针跑偏的现象。2、也有可能是由于打火的时候,打不着火的...
苏泊尔电饭锅一会儿通电一会儿不... 由于电饭煲的待机电路出现了问题,待机电路需要一个小信号的信号电路,也就是把220伏转成五伏电压,这个...
红日燃气灶怎么样-红日燃气灶好... 最佳回答 红日燃气灶的质量很不错呀。红日燃气灶还是一个比较受欢迎的燃气灶品牌的,这个品牌的燃气灶,性...
油烟机报警器一直响怎么办 当油烟机报警器一直响时,我们需要立即采取应对措施以确保安全。以下是一些应对措施:1.关闭油烟机:当油...
路面突然塌陷,目击者:两人连人... 近日,四川广安岳池县城,有市民骑车经过一处井盖旁的道路时突遇路面塌陷。现场目击者告诉红星新闻,车上两...
中国人民大学发布“观天 短临降... 中新社北京5月30日电 (记者 曾玥)中国人民大学高瓴人工智能学院30日在北京发布“观天 短临降水智...
无线远程遥控多高速摄像机同步采... 导语:在体育科研、康复医学及工程仿生领域,高速摄像同步采集技术已成为运动行为分析、步态研究及损伤诊断...
原创 小... 随着游戏不断更新,对配置的要求同步提升,所以倾向于游戏的机型,均为中端机起步,确保游戏运行流畅。部分...