PHP常见魔法函数:
__construct()
实例化对象时被调用, 当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用。
__destruct()
当删除一个对象或对象操作终止时被调用。
__call()
对象调用某个方法, 若方法存在,则直接调用;若不存在,则会去调用__call函数。
__get()
读取一个对象的属性时,若属性存在,则直接返回属性值; 若不存在,则会调用__get函数。
__set()
设置一个对象的属性时, 若属性存在,则直接赋值;
若不存在,则会调用__set函数。
__toString()
打印一个对象的时被调用。
__clone()
克隆对象时被调用。
__autoload() 或 spl_autoload_register()
实例化一个对象时,如果对应的类不存在,则该方法被调用。
重点来讲几个魔法函数:
注意:魔法函数只会在某个节点动作时被触发这个魔法函数的执行而不是自动执行某个逻辑,魔法函数的内部逻辑逻辑实现均需要自己按需编写。
1、__autoload()
自动加载是当今框架的必备良药。节省了很多依赖导入的代码编写,为程序员的懒提供了进一步的支持。不用写一堆的require包含文件语句了。
new找不到类文件的时候用类名为参自动调用这个函数去查找文件位置。如下。
$db =new DB();
function __autoload($className)
{
require $className .'.php';
}
但是如果一个项目过大,或者需要不同的自动加载来加载不同路径的文件,这个时候__autoload就悲剧了,原因是一个项目中仅能有一个这样的 __autoload() 函数,因为 PHP 不允许函数重名。于是spl_autoload_register()登场了。
function load1($className)
{
echo 1;
if(is_file($className .'.php')){
require $className .'.php';
}
}
function load2($className)
{
echo 2;
if(is_file('./app/'. $className .'.php')){
require'./app/'. $className .'.php';
}
}
function __autoload($className)
{
echo 3;
if(is_file('./lib/'. $className .'.php')){
require'./lib/'. $className .'.php';
}
}
//注册了3个
spl_autoload_register('load1');
spl_autoload_register('load2');
spl_autoload_register('__autoload');//不注册则失效
$db =new DB();//DB就在本目录下
$info =newInfo();//Info 在/lib/Info.php
需要注意的是,如果你同时使用spl_autoload_register和__autoload,__autoload会失效!!! 再说了,本来就是替换它的,就一心使用spl_autoload_register就好了。
我们注册了3个自动加载函数。执行结果是啥呢?
1Hello DB
123Hello Info
new DB的时候,就按照注册顺序,先去找load1()函数了,发现找到了,就停止了,所以输出1 Hello Word
new Info的时候,先是安装注册顺序,先找load1(), 所以输出了1,发现没找到,就去load2()里面去找,所以输出了2,还是没这个文件,就去__autoload()函数里找,所以,先输出了3,再输出Hello Info
注意,前面说过,spl_autoload_register使用时,__autoload会无效,有时候,我们希望它继续有效,就可以也将它注册进来,就可以继续使用。
2、__call()
class Test
{
public function set($key, $value, $expire = 0)
{
}
public function __call($Key, $Args) //$Key为调用函数,$Args为参数数组 ,比如$key = set,$Args = [$key,$value, $expire ]
{
echo "您要调用的 {$Key} 方法不存在。你传入的参数是:" . print_r($Args, true);
}
}
$t = new Test();
$t->getName(aning, go);
再比如我们可以和call_user_func_array函数配合使用。当两个类不是继承关系,是依赖关系的时候(A依赖B)。如果调用子类B中的一个函数,但子类中没有重写父类A的该函数的时候,就直接调用父类A的该函数。如下:
3、__get()
如果试图读取一个对象并不存在的属性的时候,PHP就会给出错误信息。如果在类里添加__get方法,并且我们可以用这个函数实现类似java中反射的各种操作。
class Test
{
public function __get($key)
{
echo $key . " 不存在";
}
}
$t = new Test();
echo $t->name;
4、__toString()
网友评论