在面向对象语言中,有一个很重要的概念——overload,即重载。所谓重载,一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同。但是,在php中,这个概念跟大多面向对象语言中的“重载”一点关系都没有,根本就是风马牛不相及的。

php中的重载,是指动态地"创建"类属性和方法。当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。再说的直白点,就是访问一个类或者对象的不可访问的属性或者方法的时候的一种处理机制。(不可访问,比如不存在或者因访问关键字的限制而不能访问)

1、属性重载

四个魔术方法:

1)__get($属性名)

  访问对象中不可访问的属性的时候,会自动调用该方法  

2)__set($属性名,$属性值)

  给对象中不可访问的属性赋值的时候,会自动调用该方法。方法中的两个参数,依次代表所访问的属性和对应的值。

3)__isset($属性名)

  当对一个对象不可访问的属性进行isset()或者empty()判断的时候,会自动调用该方法。

4)__unset($属性名)

  当对一个对象不可访问的属性进行unset()销毁的时候,会自动调用该方法。

使用的代码如下:

<?php
header("Content-type:text/html;charset = utf-8"); class Test{
public $p1 = 1; function __get($property) {//访问不可访问属性的时候,会自动调用该方法
echo "不可访问的属性:{$property}";
} function __set($property,$value) {//对不可访问的属性赋值,会自动调用该方法
echo "对不可访问的属性{$property} 赋值 {$value}<br/>";
} function __isset($property){//对不可访问的属性进行isset判断,会自动调用该方法
echo "对不可访问的属性{$property}进行isset判断<br/>";
} function __unset($property){//对不可访问的属性进行unset操作,会自动调用该方法
echo "对不可访问的属性{$property}进行unset操作<br/>";
}
} $t = new Test();
echo $t->p1."<br/>";
echo $t->p2."<br/>"; //给不可访问的属性进行赋值
$t->p3 = 2; //对不可访问的属性进行isset判断
isset($t->p4); //对不可访问的属性进行unset操作
unset($t->p5); /*
运行结果:
1
不可访问的属性:p2
对不可访问的属性p3 赋值 2
对不可访问的属性p4进行isset判断
对不可访问的属性p5进行unset操作
*/
?>

配合是用__get()和__set()方法,可以使类变得更加灵活和自由,可以很方便给类添加属性。如下:

<?php
header("Content-type:text/html;charset = utf-8"); class Test{
//定义数组,用于存储不可访问的属性
protected $plist = array(); function __get($property) {//访问不可访问属性的时候,会自动调用该方法
//属性不可访问,从plist中读取
if (isset($this->plist[$property])) {
return $this->plist[$property];
}
else {
return "属性{$property}不可访问";
}
} function __set($property,$value) {//对不可访问的属性赋值,会自动调用该方法
//属性不可访问,将之存放到plist中
$this->plist[$property] = $value;
} function __isset($property){//对不可访问的属性进行isset判断,会自动调用该方法
$v = isset($this->plist[$property]);
return $v;
} function __unset($property){//对不可访问的属性进行unset操作,会自动调用该方法
unset($this->plist[$property]);
}
} $t = new Test();
$t->p1 = 1;//对不可访问的属性赋值
echo "不可访问的属性p1的值为:".$t->p1."<br/>";//使用p1属性(经过上一行代码,p1已经添加到了plist中) echo "不可访问的属性p2的值为:".$t->p2."<br/>";//没对p2赋值过 //分别对p1和p2进行isset操作
$r1 = isset($t->p1);//结果为true,但是如果不处理__isset魔术方法,将返回false
$r2 = isset($t->p2);//结果为false,本来也不存在...
var_dump($r1);echo "<br/>";
var_dump($r2);echo "<br/>"; //分别对p1和p2进行unset操作
unset($t->p1);
unset($t->p2);
echo "不存在的属性p1的值为:".$t->p1."<br/>";
echo "不存在的属性p2的值为:".$t->p2."<br/>"; /*
结果:
不可访问的属性p1的值为:1
不可访问的属性p2的值为:属性p2不可访问
bool(true)
bool(false)
不可访问的属性p1的值为:属性p1不可访问
不可访问的属性p2的值为:属性p2不可访问
*/
?>

2、方法重载

1)__call()

  调用对象的不可访问的方法的时候,会自动调用该方法。

2)__callstatic()

  调用类的不可访问的静态方法的时候,会自动调用该方法。

示例:

<?php
header("Content-type:text/html;charset = utf-8"); class Test {
/*
@desc 调用不存在的成员方法的时候,会自动调用该方法
@param $name,方法名
@param $args,方法参数
*/
function __call($name,$args){
echo "调用不存在的方法{$name}";
}
} $t1 = new Test();
$t1->f1();
echo "<br />";
$t1->f2(); /*
结果:
调用不存在的方法f1
调用不存在的方法f2
*/
?>

实例:利用php的方法重载来实现面向对象中通用的重载,即一个类内多个方法的方法名相同但是参数不同

设计一个打招呼的方法,至少输入一个参数(人名)

输入一个参数,输出:hello,xx;

输入两个参数,输出:hello,xx,yy;

输入三个及以上参数,输出:hello,guys;

<?php
header("Content-type:text/html;charset = utf-8"); class Test {
/*
@desc 调用不存在的成员方法的时候,会自动调用该方法
@param $name,方法名
@param $args,方法参数
*/
function __call($name,$args){
if ($name === "sayHello") {//处理未定义方法sayHello
$n = count($args);
if ($n<1) {
trigger_error("There's zero params!!!!");
}
else if ($n == 1) {
echo "hello,{$args[0]}<br/>";
}
else if ($n == 2) {
echo "hello,{$args[0]},{$args[1]}<br/>";
}
else {
echo "hello,guys!<br/>";
}
}
}
} $t1 = new Test();
$t1->sayHello();
$t1->sayHello("Richard");
$t1->sayHello("Maria","Robert");
$t1->sayHello("Maria","Robert","Richard"); /*
结果: Notice: There's zero params!!!! in /Users/xx/xx/xx/xx.php on line 14
hello,Richard
hello,Maria,Robert
hello,guys!
*/
?>

最新文章

  1. Eclipse右下角一直提示Computing additional info解决办法
  2. tcpdump交叉编译及使用
  3. More on Conditions - To Compare -Comparing Sequences and Other Types
  4. mysql 中 isnull 和 ifnull 判断字段是否为null
  5. easyui源码翻译1.32--ComboGrid(数据表格下拉框)
  6. 使用SSH代理上IPV6(使用SSH端口转发)
  7. OpenSceneGraph是一个开源的三维引擎
  8. sql中插入多条记录-微软批处理
  9. POJ3233(矩阵二分再二分)
  10. Java异常处理总结
  11. 用于 SELECT 和 WHERE 子句的函数
  12. line-height的定义
  13. 【Hihocoder1413】Rikka with String(后缀自动机)
  14. Luogu P4070 [SDOI2016]生成魔咒
  15. tp5学习
  16. 使用gitlab, jenkins搭建CI(持续集成)系统(3) -- 根据不同触发条件执行不同的构建任务
  17. 【hdu5306】 Gorgeous Sequence
  18. C++ 关于滚动条的滚动问题
  19. Sword redis补充
  20. DOS中符号的英文对照

热门文章

  1. BZOJ 2738 矩阵乘法(整体二分+二维树状数组)
  2. AIM Tech Round (Div. 1) D. Birthday 数学 暴力
  3. php 自动补位
  4. mysql-proxy使用中的问题
  5. CentOS 6.9/Ubuntu 16.04搭建OpenVPN服务器以及客户端的使用
  6. [Java基础] Java对象内存结构
  7. iOS: 环信的推送
  8. tag subshader shaderlab
  9. Tomcat9 访问 Manager App
  10. Java 程序员快速上手 Kotlin 11招