php 魔术方法总结(持续更新)

类中的魔术方法

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

类中的魔术方法

__construct()

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

__destruct()

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

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

class computer{

    private $brand;

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

    function __destruct(){
        echo "release ".$this->brand."<br>";
    }
}

$myComputer = new computer("MAC");
$yourComputer = new computer("Asus");
$hisComputer = new computer("Dell");

echo "end of php file<br>";

输出结果如下所示

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 :)<br>";
        echo "I will tell you the name of woner: ".$this->owner."<br>";
        echo "I won‘t tell you that the brand is ".md5($this->brand)."<br>";
        echo "<br>";
    }

    function __destruct(){
        echo "release ".$this->brand."<br>";
    }

}

$myComputer = new computer("MAC", "me", "1000");
$yourComputer = new computer("Asus", "you", "500");
$hisComputer = new computer("Dell", "his", "700");

echo $myComputer->price; 
echo "<br><br>";

echo $myComputer->owner;
echo $yourComputer->brand;

echo "end of php file<br>";

输出如下

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 :)<br>";
        echo "I will tell you the name of woner: ".$this->owner."<br>";
        echo "I won‘t tell you that the brand is ".md5($this->brand)."<br>";
        echo "<br>";
    }

    function __set($name, $value){
        $this->owner = $value;
        echo "set $name to $value"."<br><br>";
    }

    function __destruct(){
        echo "release ".$this->brand."<br>";
    }

}

$myComputer = new computer("MAC", "me", "1000");

echo $myComputer->owner = "my friend";
echo $myComputer->owner;

echo "end of php file<br>";

输出结果

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<br>";
    }

    function __call($m, $a){
        echo "erro function: ".$m;
        echo "<br>";
        echo "error param: ";
        print_r($a);
        echo "<br>";
    }
}

$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<br>";
    }
}

$myComputer = new computer();

$youComputer = $myComputer;
$youComputer->name = ‘pc1‘;
echo "My computer‘s name is ".$myComputer->name."<br>";
echo "<br>";

$hisComputer = clone $myComputer;
$hisComputer->name = ‘pc2‘;
echo "My computer‘s name is ".$myComputer->name."<br>";
echo "His computer‘s name is ".$hisComputer->name."<br>";

输出结果

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() 例子

<?php
function __autoload($class_name) {
    include $class_name . ‘.php‘;
}

$obj  = new MyClass1();
$obj2 = new MyClass2(); 
?>

摘自PHP手册

带 try, catch 异常处理的例子

function __autoload($class_name){
    echo "want to load ".$class_name."<br>";
    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()."<br>";
}

php 魔术方法总结(持续更新),布布扣,bubuko.com

时间: 2024-10-03 12:09:47

php 魔术方法总结(持续更新)的相关文章

做web项目时对代码改动后浏览器端不生效的应对方法(持续更新)

做web项目时,常常会遇到改动了代码,但浏览器端没有生效,原因是多种多样的,我会依据我遇到的情况逐步更新解决的方法 1.执行的时候採用debug模式,普通情况下使用项目部署button右边那个button下的tomcat7中的run即可,假设使用的是serves中的run serves,这样的情况貌似不会自己主动编译 2.点击project菜单下的clean选项,在打开的窗体中选择你使用的项目,ok,这样会删除tomcat容器中关于该项目的一些信息,然后又一次部署,执行 3.删除电脑中tomca

java开发中遇到的问题及解决方法(持续更新)

摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他服务和Web进行交换,Java开发必不可少,又不想动用Eclipse大家伙,只能自己动手编写脚本进行Java代码的编译和运行,期间遇到的一些问题,记录下来供自己和大家参考.1)软件包不存在/软件包 javax.jms 不存在    这是由于javac编译时找不到javax.jms所在的软件包,因此将

做web项目时对代码修改后浏览器端不生效的应对方法(持续更新)

做web项目时,经常会遇到修改了代码,但浏览器端没有生效,原因是多种多样的,我会根据我遇到的情况逐步更新解决办法 1.运行的时候采用debug模式,一般情况下使用项目部署按钮右边那个按钮下的tomcat7中的run就行,如果使用的是serves中的run serves,这种情况貌似不会自动编译 2.点击project菜单下的clean选项,在打开的窗口中选择你使用的项目,ok,这样会删除tomcat容器中关于该项目的一些信息,然后重新部署,运行 3.删除电脑中tomcat文件夹,重新解压,然后在

普元EOS开发积累第一篇(常见错误解决方法) 持续更新

普元启动服务失败的解决方法 当多个人同时使用一个数据库的时候,启动普元控制台会一直停留在rcall,然后显示一个超时的警告,那样就需要修改一下普元的一个定时器配置项. 安装目录下\Primeton\Platform\apps_config\default\config 中的一个user-config.xml文件 将下列代码中高亮字段中的true改为false即可  <module name="Schedule">          <group name="

jupyter notebook 的使用说明 转自 http://blog.csdn.net/tina_ttl/article/details/51031113#pythonjupyter-notebook各种使用方法记录持续更新

Python·Jupyter Notebook各种使用方法记录·持续更新 标签(空格分隔): Python PythonJupyter Notebook各种使用方法记录持续更新 一 Jupyter NoteBook的安装 1 新版本Anaconda自带Jupyter 2 老版本Anacodna需自己安装Jupyter 二 更改Jupyter notebook的工作空间 1 方式一 2 方式二绝招绝招 三Jupyter的各种快捷键 四Jupyter Notebook如何导入代码 1 将本地的py文

Python&#183;Jupyter Notebook各种使用方法记录&#183;持续更新

Python·Jupyter Notebook各种使用方法记录·持续更新 你为什么使用 jupyter 原文地址:https://www.cnblogs.com/lhuser/p/8446420.html

Caffe系统搭建(常见问题解决办法和ubuntu使用中遇到问题解决方法)——持续更新

Caffe编译问题及解决方案汇总: 在编译caffe代码时,之前的各种错误会显现出来,这时候会出现各种各样的问题: 问题1: Error: 'make all' 'make test' .build_release/lib/libcaffe.so: undefined reference to cv::imread(cv::String const&, int)' .build_release/lib/libcaffe.so: undefined reference tocv::imencode

tensorflow与神经网络中遇到的问题与解决方法【持续更新】

1.如何在全连接层拼接特征? 有一种方法是有两个input,一个input通过网络最终达到全连接层,另一个input直接接一个全连接网络,神经元数是特征数,这两个可以进行一个concat.  当然了也可以直接输入特征concat到全连接层,但是据说前者效果要好一点. 2.word2vec词向量如何在网络中更新? 在我的一个模型中(网络层次较浅),我用word2vec词向量的效果比之用随机词向量然后更新的效果要远远远远远远的不如!!!很绝望,发现word2vec词向量生成tensor又不能更新,不

jquery不熟悉的方法(持续更新)

1.jquery有一个筛选api find. 语法很简单,比如: HTML 代码: <p><span>Hello</span>, how are you?</p> jQuery 代码: $("p").find("span") 结果: [ <span>Hello</span> ] 但是我一开始很疑惑,这个不是和$('p span')api完全一致,为什么要用这个find?知道今天我遇到了一个应用场

oracle学习 六 删除表空间,数据文件的语句以及导入导出dmp文件的方法(持续更新中)

要想删除表空间就要先删除数据文件 例如这个例子 CREATE TABLESPACE STHSGIMGDB_SPACE11 DATAFILE 'D:\ORACLEDATABASE\JinHuaDataBase\STHSGIMGDB_SPACE11_01' SIZE 1M AUTOEXTEND ON NEXT 50M MAXSIZE UNLIMITED, 'D:\ORACLEDATABASE\JinHuaDataBase\STHSGIMGDB_SPACE11_02' SIZE 1M AUTOEXTE