在面向对象语言中,有一个很重要的概念——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!
*/
?>

php中的重载以及几个常用的魔术方法示例的更多相关文章

  1. php面向对象类中常用的魔术方法

    php面向对象类中常用的魔术方法   1.__construct():构造方法,当类被实例化new $class时被自动调用的方法,在类的继承中可以继承与覆盖该方法,例: //__construct( ...

  2. Python | Python常用函数、方法示例总结(API)

    目录 前言 1. 运算相关 2. Sring与数字 3. 列表相关 4. 集合相关 5. 序列化类型 6. 字典相关 7. 输入输出 8. 文件相关 9. json模块 10. unittest测试模 ...

  3. PHP中常用的魔术方法

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

  4. PHP序列化、反序列化常用的魔术方法

    __wakeup() //使用unserialize时触发__sleep() //使用serialize时触发__destruct() //对象被销毁时触发__call() //在对象上下文中调用不可 ...

  5. PHP常用的魔术方法及规则

    1. __construct 具有构造函数的类会在每次创建新对象时先调用此方法;初始化工作执行.2. __desstruct 对象的所有引用都被删除或者当对象被显式销毁时执行.3.__call()在对 ...

  6. php常用的魔术方法

    __construct:构造函数,一旦创建对象都就会自动调用 __call:当调用了未定义的方法时会自动触发 __set:当给类外部不可访问的属性设置值时会自动触发 __get:当获取类外部不可访问的 ...

  7. PHP面向对象中常用的关键字和魔术方法

    PHP面向对象中常用的关键字 final        1.final不能修饰成员属性(类中常量不是用这个关键字)        2.final只能修饰类和方法 作用:            使用fi ...

  8. php中的常用魔术方法总结

    以下是对php中的常用魔术方法进行了详细的总结介绍,需要的朋友可以过来参考下 常用的魔术方法有:__Tostring () __Call() __autoLoad() __ clone() __GET ...

  9. java中的重载与重写

    重载简述 在java语言中,同一个类中的两个或者两个以上的方法可以有同一个名字,只要他们的的参数声明不同即可,该方法被称为重载,这个过程称为方法的重载,它是实现java多态性的一种方式. 重载是友好的 ...

随机推荐

  1. [ARC103F]Distance Sums

    题意:有一棵树,对于每个点$i$,给出了它到其他点的距离和$i$,现在要还原这棵树,保证$d_i$两两不同 一个点从$u$移到相邻节点$v$时,若删掉$(u,v)$后$u$这边的连通块大小为$siz_ ...

  2. [AGC025D]Choosing Points

    [AGC025D]Choosing Points 题目大意: 输⼊\(n(n\le300),d_1,d_2\),你要找到\(n^2\)个整点\((x,y)\)满⾜\(0\le x,y<2n\). ...

  3. [洛谷P3809]【模板】后缀排序

    [洛谷P3809][模板]后缀排序 题目大意: 对于给定的长度为\(n(n\le10^6)\)的字符串求后缀数组\(sa[i]\). 思路: 倍增+快排构造后缀数组.代码参考<挑战程序设计竞赛& ...

  4. React中的Keys

    前言 当你在React当中渲染列表项的时候,React会尝试存储对应每个单独项的相关信息,如果你的组件包含state状态数据,那么这些状态数据必须被排序. 当你想要更新这些列表项的时候,React必须 ...

  5. 解决URL中包含“%2F”导致Apache地址重写mod_rewrite失效的问题

    在使用Apache地址重写mod_rewrite期间,发现,当URL和PATH_INFO中出现%2f(/)或者%5c(\), 会被认为这是个不合法的请求, Apache将会直接返回"404 ...

  6. 一个简单的WebService服务

    现在,网上提供的免费的webservice服务的网站: http://www.webxml.com.cn/ 从扩展名上看,是 .net构建的网站. 看看功能的实现效果: 需求:我们要远程调用手机号归属 ...

  7. 什么是webview

    WebView(网络视图)能加载显示网页,可以将其视为一个浏览器.它使用了WebKit渲染引擎加载显示网页,实现WebView有以下两种不同的方法:第一种方法的步骤:1.在要Activity中实例化W ...

  8. python遍历目录的方法 walk listdir

    这篇文章里描述了这些情况: https://www.cnblogs.com/jiaxin359/p/7324077.html 不用递归的时候,用 listdir 需要递归的时候,用walk

  9. unity reflection probe --- forward deferred transparent opaque

    deferred 和forward reflection probe 的差别 deferred ref是逐像素的 forward是逐 obj 但我还遇到一个问题就是box projection ref ...

  10. http://my.oschina.net/lenglingx/blog/205269

    http://my.oschina.net/lenglingx/blog/205269 http://www.2cto.com/os/201402/281465.html 单点登录原理: http:/ ...