php规定以两个下划线(__)开头的方法都保留为魔术方法,所以建议大家函数名最好不用__开头,除非是为了重载已有的魔术方法

PHP中的魔术方法有 :__get, __set, __isset, __unset,__construct, __destruct , __call, __callStatic, , __sleep, __wakeup, __toString, __set_state, __clone, __autoload,__invoke
详解:

1.__get,__set

这两个方法是为在类和他们的父类中没有声明的属性而设计的 
__get( $property ) 当调用一个未定义的属性时,此方法会被触发,传递的参数是被访问的属性名 
__set( $property, $value ) 给一个未定义的属性赋值时,此方法会被触发,传递的参数是被设置的属性名和值;这里的没有声明包括当使用对象调用时,访问控制为proteced,private的属性(即没有权限访问的属性)

// 如果类中的属性设置为私有属性,在类的实例中是无法访问的,但怎样才能访问呢?
// 我们就可以使用__get()
Class Person
{private $name;private $age;function __get($proName)
{return this->$proName;
}
}
// 实例化
$per=new Person()
$per->$name; //这样是取不到值的
// 但是如果我们在类中增加__GET方法
// 我们再次调用$per->$name 就可以访问了
// 这样做有人会提出疑问了,这样可以直接访问私有变量,和声明成公有的有什么区别呢?
// 如果声明成公有的,我们可以任意读取,如果是私有,如果我们增加了get方法,那么每次调用私有属性都会
// 调用GET方法的内容,这样我们就可以在get方法中增加一些逻辑处理。
// 原理同上,我们可以再类中添加__set()函数,每当通过调用类实例给私有属性赋值,都会执行__set函数 ,
// 函数原型:
function __set($proName,$value)
{
this->$proName=$value;
}//既然是方法赋值,我们就可以做一些逻辑处理

2.__isset、__unset 

__isset( $property ) 当在一个未定义的属性上调用isset()函数时调用此方法 (判断类中私有属性或方法是否存在时自动调用)
__unset( $property ) 当在一个未定义的属性上调用unset()函数时调用此方法 (清除类中私有变量时自动调用)
与__get方法和__set方法相同,这里的没有声明包括当使用对象调用时,访问控制为proteced,private的属性(即没有权限访问的属性)

//isset 方法,该方法用于判定属性和方法是否存在,但是我们无法通过类类实例判断类中的某个私有属性是否 //存在
//如果我们使用isset(per->$name);//返回值是false,但是$name属性的确存在,怎么解决呢?
//解决方法:
//1.将$name定义为私有属性
//2.在类定义中添加function __isset($proName)
{
Return  isset(this->$proName);//再类内部是可以访问私有属性的
}// 这样的话我们再次调用isset($name);返回值就为true了
//unset方法可以删除属性,当我们需要删除类中属性的时候,如果是公有属性我们可以直接
删除,但是如果是私有我们只通过该方法就无法实现了
怎样实现呢我们可以使用__unset()方法实现该功能我们需要在类中添加function __unset($proName)
{
unset(this->$proName);
}//现在我们再调用unset($name);就可以删除person类中的私有属性$name了

3.__call

__call( $method, $arg_array ) 当调用一个未定义的方法是调用此方法 (当调用类实例中不存在的函数时自动执行),该方法有两个参数,第一个参数 $function_name 会自动接收不存在的方法名,第二个 $arguments 则以数组的方式接收不存在方法的多个参数.这里的未定义的方法包括没有权限访问的方法;如果方法不存在就去父类中找这个方法,如果父类中也不存在就去调用本类的__call()方​法,如果本类中不存在__call()方法就去找父类中的__call()方法;如果试图调用类中不存在的函数,会出现语法错误,为了能够友好的提示
我们可以在类中声明Call()方法;

function __call($funName,$argu)
{echo "名为".$funName."参数为".printf($argh)."的函数不存在",
}
<?php
class Person
{                             function say(){  echo "Hello, world!<br>"; }      /*** 声明此方法用来处理调用对象中不存在的方法*/function __call($funName, $arguments){ echo "你所调用的函数:" . $funName . "(参数:" ;  // 输出调用不存在的方法名print_r($arguments); // 输出调用不存在的方法时的参数列表echo ")不存在!<br>\n"; // 结束换行                      }
}
$Person = new Person();
$Person->run("teacher"); // 调用对象中不存在的方法,则自动调用了对象中的__call()方法
$Person->eat("小明", "苹果");
$Person->say();

运行结果:

你所调用的函数:run(参数:Array ( [0] => teacher ) )不存在!你所调用的函数:eat(参数:Array ( [0] => 小明 [1] => 苹果 ) )不存在!Hello, world!

4.__clone

对象的复制(引用赋值)
$per1=$per2; 而这在内存中只有一块地址
而$per1=clone $per2   这时有两块内存地址

5.__toString

用于定义输出对象引用时调用  常用于打印一些对象的信息 必须有返回值(返回一个字符串)

在将一个对象转化成字符串时自动调用,比如使用echo打印对象时
如果类没有实现此方法,则无法通过echo打印对象,否则会显示:Catchable fatal error: Object of class test could not be converted to string in

在PHP 5.2.0之前,__toString方法只有结合使用echo() 或 print()时 才能生效。PHP 5.2.0之后,则可以在任何字符串环境生效(例如通过printf(),使用%s修饰符),但 不能用于非字符串环境(如使用%d修饰符)。从PHP 5.2.0,如果将一个未定义__toString方法的对象 转换为字符串,会报出一个E_RECOVERABLE_ERROR错误。

// eg:有一个persion类
$per =new persion()
echo $per;    //直接调用会出错
//我们可以在类的定义中添加__tostring()方法
function  __Tostring()
{$str=this->$name.this->age;return $str;
}

6.__autoload 
自动加载使用的类文件  该函数是在引用的页面添加,它会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。 
我们都使用过这样情况,在页面中需要调用其他php文件,我们需要使用include方法
但是如果有几十个页面需要引用,未免太过繁琐,我们可以在该页面中使用autoload方法

function __autoload($className)
{include $className.".php";
}
//这样凡是引用到其他类的地方,都会自动引用该类文件  前提类文件的名称必须是   类名.php

如果要定义一个全局的自动加载类,则必须用spl_autoload_register()方法将处理类注册到PHP标准库:

<?php
class Loader
{   static function autoload_class($class_name)
{
//寻找正确的$class_name类,并引入,没有则抛出异常
}
}
/**
*   设置对象的自动载入
*   spl_autoload_register — Register given function as __autoload() implementation
*/
spl_autoload_register(array('Loader', 'autoload_class'));
$a = new Test();//Test没用require就实例化,实现自动加载,很多框架就用这种方法自动加载类
?>//注意: 在 __autoload 函数中抛出的异常不能被 catch 语句块捕获并导致致命错误,所以应该在函数本身做 //捕获

7.__construct、__destruct 

__construct 构造方法,当一个对象创建时调用此方法,相对于PHP4使用此方法的好处是:可以使构造方法有一个独一无二的名称,无论它所在的类的名称是什么.这样你在改变类的名称时,就不需要改变构造方法的名称

<?phpclass Person{                                                                      public $name;        public $age;        public $sex;        /*** 显示声明一个构造方法且带参数*/                                                                                       public function __construct($name="", $sex="男", $age=22){      $this->name = $name;$this->sex = $sex;$this->age = $age;}/*** say 方法*/public function say(){ echo "我叫:" . $this->name . ",性别:" . $this->sex . ",年龄:" . $this->age;}   }$Person1 = new Person();
echo $Person1->say(); //输出:我叫:,性别:男,年龄:22$Person2 = new Person("小明");
echo $Person2->say(); //输出:我叫:小明,性别:男,年龄:22$Person3 = new Person("李四","男",25);
echo $Person3->say(); //输出:我叫:李四,性别:男,年龄:25

__destruct 析构方法,PHP将在对象被销毁前(即从内存中清除前)调用这个方法。析构方法允许在销毁一个类之前执行的一些操作或完成一些功能,比如说关闭文件、释放结果集等。析构方法是PHP5才引进的新内容。默认情况下,PHP仅仅释放对象属性所占用的内存并销毁对象相关的资源,析构函数允许你在使用一个对象之后执行任意代码来清除内存。当PHP决定你的脚本不再与对象相关时,析构函数将被调用。 在一个函数的命名空间内,这会发生在函数return的时候。 对于全局变量,这发生于脚本结束的时候。 如果你想明确地销毁一个对象,你可以给指向该对象的变量分配任何其它值.通常将变量赋值勤为NULL或者调用unset.

//析构方法的声明格式
//注意:析构函数不能带有任何参数
//一般来说,析构方法在PHP中并不是很常用,它属类中可选择的一部分,通常用来完成一些在对象销毁前的清理
//任务。
function __destruct()
{//方法体
}
<?php
class Person{     public $name;         public $age;         public $sex;         public function __construct($name="", $sex="男", $age=22){   $this->name = $name;$this->sex  = $sex;$this->age  = $age;}/*** say 说话方法*/public function say(){  echo "我叫:".$this->name.",性别:".$this->sex.",年龄:".$this->age;}    /*** 声明一个析构方法*/public function __destruct(){echo "我觉得我还可以再抢救一下,我的名字叫".$this->name;}
}$Person = new Person("小明");
unset($Person); //销毁上面创建的对象$Person//上面的程序运行时输出:我觉得我还可以再抢救一下,我的名字叫小明

8.__sleep,__wakeup

serialize() 检查类中是否有魔术名称 __sleep 的函数。如果这样,该函数将在任何序列化之前运行。它可以清除对象并应该返回一个包含有该对象中应被序列化的所有变量名的数组。 
使用 __sleep 的目的是关闭对象可能具有的任何数据库连接,提交等待中的数据或进行类似的清除任务。此外,如果有非常大的对象而并不需要完全储存下来时此函数也很有用。 
相反地,unserialize() 检查具有魔术名称 __wakeup 的函数的存在。如果存在,此函数可以重建对象可能具有的任何资源。 
使用 __wakeup 的目的是重建在序列化中可能丢失的任何数据库连接以及处理其它重新初始化的任务

9.__invoke 

当尝试以调用函数的方式调用一个对象时,__invoke 方法会被自动调用

10.__set_state

静态方法,当调用var_export()的时候,才会调用这个静态方法,php5.1.0之后生效。唯一参数是接收一个数组

11.__callStatic 

它的工作方式类似于 __call() 魔术方法,__callStatic() 是为了处理静态方法调用, 
PHP5.3.0以上版本有效 
PHP 确实加强了对 __callStatic() 方法的定义;它必须是公共的,并且必须被声明为静态的。同样,__call() 魔术方法必须被定义为公共的,所有其他魔术方法都必须如此

// 魔术方法:
// 构造方法:__construct  当实例化一个对象时,自动执行此方法,通常用于赋值操作
// 析构方法:__destruct   释放资源
// isset魔术方法:__isset  当类外检测一个私有属性时,自动调用魔术方法__isset  [名]
// unset魔术方法:__unset  当类外删除一个私有属性时,自动调用魔术方法__unset  [名]
// get魔术方法: __get     当类外获取一个私有属性时,自动调用魔术方法__get    [名]
// set魔术方法: __set     当类外设置一个私有属性时,自动调用魔术方法__set    [名,值]
// sleep魔术方法: 当类外使用序列化时调用此方法   serialize(value)
// wakeup魔术方法: 当类外使用反序列化时调用此方法  unserialize(value)
// toString魔术方法:  当直接输入对象时调用此方法,如果不写toString方法,会报一个致命错误,底下代码不执行 ,如果写一个Tostring方法,底下继续执行
// call魔术方法: 当调用一个不存在的方法时自动调用
// 自动加载:  __autoload   引入文件,注意:引入文件的一个规律    spl_autoload_register("方法名")
// 克隆方法:  __clone  克隆一个方法
//实例化对象时,会调用对象的__construct方法
$obj = new Object();
//给对象不存在的属性赋值时,会调用对象的__set方法
$obj->title = "hello";
//使用对象不存在的属性时,会调用对象的__get方法
echo $obj->title;
//调用对象不存在的方法时,会调用对象的__call方法
$obj->test("hello",123,567);
//调用不存在的类静态方法时,会调用类的__callStatic方法
Object::staticMethod("static","not found method");
//直接输出对象时,会调用对象的__toString方法
echo $obj;
//将一个对象当作函数一样使用时,会调用对象的__invoke方法
echo $obj("test");
//克隆对象时,会调用对象的__clone方法
$obj2 = clone $obj;
//判断对象属性是否存在时,会调用对象的__isset方法
var_dump(isset($obj->aaa));
//销毁对象属性时,会调用对象的__unset方法
unset($obj->aaa);class Object{protected $array = array();function __construct(){echo __METHOD__."你正在实例化对象<br>";}function __set($name, $value){$this->array[$name]=$value;}function __get($name){return $this->array[$name];}function __call($name, $arguments){var_dump($name,$arguments);return "magic function\n";}static function __callStatic($name, $arguments){var_dump($name,$arguments);return "magic static function";}function __toString(){return __CLASS__.'<br>';}function __invoke($arguments){var_dump($arguments);return __METHOD__.'<br>';}function __clone(){echo __METHOD__."你正在克隆对象<br>";}function __isset($name){echo __METHOD__."你想判断有没有属性".$name."<br>";return 1;}function __unset($name){echo __METHOD__."你想删除属性".$name."<br>";}function __destruct(){echo __METHOD__."你正在注销对象<br>";}
}

php常用的魔术方法相关推荐

  1. 魔术方法php,PHP中常用的魔术方法

    我们在PHP中经常用到魔术方法,像构造方法,析构方法等等魔术变量,下面总结一下一些常用的魔术变量: __construct(),__destruct(),__clone(),__autoload(), ...

  2. 常用的魔术方法有哪些?举例说明

    php规定以两个下划线(__)开头的方法都保留为魔术方法,所以建议大家函数名最好不用__开头,除非是为了重载已有的魔术方法. __construct() 实例化类时自动调用. __destruct() ...

  3. PHP几种常用的魔术方法

    魔术方法 __get 获取对象中的非公有或不存在的成员属性时, 触发该方法 接受一个参数 属性名 __set 设置对象中的非公有或不存在的成员属性时, 触发该方法 接受两个参数 (属性名,属性值) c ...

  4. php 所有魔术方法,PHP常用的魔术方法及规则

    转:https://www.cnblogs.com/wanglijun/p/10926303.html 1. __construct 具有构造函数的类会在每次创建新对象时先调用此方法;初始化工作执行. ...

  5. php类退出魔术方法,php类中常用的魔术方法

    1.__construct() //构造函数, 2.__destruct()//析构函数, 3.__call() .__callStatic() //调用一个不可访问的方法.调用不可访问的静态方法时被 ...

  6. python 析构函数_常用的python类的魔术方法

    对于很少使用python编写大型代码的朋友可能会忘记python还是一种面向对象的语言.在其他面向对象的语言中有构造函数.析构函数等等在生命周期不同时机自动调用的函数,python当然也是有的.除此之 ...

  7. php有多少魔术方法,PHP常用的几个魔术方法

    常用的魔术方法有:__Tostring () __Call() __autoLoad() __ clone() __GET() __SET() __isset() __unset() 1.__Tost ...

  8. python描述符魔术方法_学习笔记-Python基础9-面向对象编程OOP-类的成员描述符(property)、类的常用内置属性、类的常用魔术方法、类和对象的三种方法...

    一.类的成员描述符(property) 类的成员描述符是为了在类中,对类的成员属性进行相关操作而创建的一种方式,大部分属于数据清洗 属性有三种操作:get获取属性值.set修改或添加属性.delete ...

  9. python魔术方法是什么_Python常用魔术方法

    什么是魔术方法? 在Python中,所有以双下划线__包起来的方法,统称为Magic Method(魔术方法),它是一种的特殊方法,普通方法需要调用,而魔术方法不需要调用就可以自动执行. 魔术方法在类 ...

最新文章

  1. opencv矩阵操作函数查询
  2. linux向上翻页_linux学习基础篇——文件管理(一)
  3. python 希尔伯特变换_python scipy signal.hilbert用法及代码示例
  4. mysql标准时间,MySQL时间设置
  5. c 命令导出数据到mysql_MySQL命令行导出数据库
  6. android 信号强度变化,Android监听WIFI网络的变化并且获得当前信号强度
  7. nginx 防止恶意域名解析_配置nginx只允许域名访问,禁止ip访问【图文教程】
  8. 最小生成树——安慰奶牛(蓝桥杯试题集)
  9. 卷积神经网络看见了什么
  10. mysql简单语句_MYSQL常用简单语句
  11. Hadoop初次接触后感
  12. 使用angular4和asp.net core 2 web api做个练习项目(四)
  13. hdu 6096 String(AC自动机巧妙建图)
  14. mpass小程序开发总结
  15. java学习血泪史目录
  16. 智能算法-模拟退火-粒子群-鱼群算法
  17. SSA优化章:SSA优化PID
  18. linux下安装weblogic出现的两个错误解决办法
  19. Synopsys Formality 2018操作流程
  20. 失眠可以用什么东西改善一个失眠多年的朋友给我推荐

热门文章

  1. Python爬虫||Xpath-以豆瓣电视剧为例
  2. Ubuntu11.04中安装中标普华Office5.0
  3. 优秀硬盘分区管理工具--Partition Magic V8.0
  4. 视频添加滤镜怎么弄?这几个方法建议收藏
  5. windows 下 babun 配置
  6. Eclipse,静态,继承,封装,this,super,重写,重载,多态,final,冒泡排序,选择排序,抽象类,接口,内部类
  7. 蜂糖李施肥季节如何管理
  8. 用Python自动生成word文档
  9. C语言小项目 -- 扫雷游戏完整代码(递归展开 + 选择标记)
  10. 张小龙不是广东人 | 小林和腾讯不得不说的故事(五)