php面向对象全攻略 (十一)__toString()用法 克隆对象 __call处理调用错误


Posted in PHP onSeptember 30, 2009

16.__toString()方法
我们前面说过在类里面声明“— ”开始的方法名的方法(PHP 给我们提供的),都是在
某一时刻不同情况下自动调用执行的方法,“__toString()”方法也是一样自动被调用的,是在
直接输出对象引用时自动调用的, 前面我们讲过对象引用是一个指针,比如说:“$p=new
Person()”中,$p 就是一个引用,我们不能使用echo 直接输出$p,这样会输出“Catchable fatal
error: Object of class Person could not be converted to string”这样的错误,如果你在类里面定义
了“__toString()”方法,在直接输出对象引用的时候,就不会产生错误,而是自动调用了
“__toString()”方法,输出“__toString()”方法中返回的字符,所以“__toString()”方法一定
要有个返回值(return 语句)。
代码片段

<?php 
// Declare a simple class 
class TestClass{ 
public $foo; 
public function __construct($foo) { 
$this->foo = $foo; 
} 
//定义一个__toString方法,返加一个成员属性$foo 
public function __toString() { 
return $this->foo; 
} 
} 
$class = new TestClass('Hello'); 
//直接输出对象 
echo $class; 
?>

上例输出:Hello
17.克隆对象
有的时候我们需要在一个项目里面,使用两个或多个一样的对象,如果你使用“new”
关键字重新创建对象的话,再赋值上相同的属性,这样做比较烦琐而且也容易出错,所以要
根据一个对象完全克隆出一个一模一样的对象,是非常有必要的,而且克隆以后,两个对象
互不干扰。
在PHP5 中我们使用“clone”这个关键字克隆对象;
代码片段
<? 
class Person{ 
//下面是人的成员属性 
var $name; //人的名子 
var $sex; //人的性别 
var $age; //人的年龄 
//定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值 
function __construct($name="", $sex="", $age=""){ 
$this->name=$name; 
$this->sex=$sex; 
$this->age=$age; 
} 
//这个人可以说话的方法, 说出自己的属性 
function say() { 
echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>"; 
} 
} 
$p1=new Person("张三", "男", 20); 
//使用“clone”克隆新对象p2,和p1对象具有相同的属性和方法。 
$p2=clone $p1; 
$p2->say(); 
?>

PHP5 定义了一个特殊的方法名“__clone()”方法,是在对象克隆时自动调用的方法,
用“__clone()”方法将建立一个与原对象拥有相同属性和方法的对象,如果想在克隆后改变
原对象的内容,需要在__clone()中重写原本的属性和方法,“__clone()”方法可以没有参数,
它自动包含$this 和$that 两个指针,$this 指向复本,而$that 指向原本;
代码片段
class Person{ 
//下面是人的成员属性 
var $name; //人的名子 
var $sex; //人的性别 
var $age; //人的年龄 
//定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值 
function __construct($name="", $sex="", $age=""){ 
$this->name=$name; 
$this->sex=$sex; 
$this->age=$age; 
} 
//这个人可以说话的方法, 说出自己的属性 
function say() { 
echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>"; 
} 
//对象克隆时自动调用的方法, 如果想在克隆后改变原对象的内容,需要在__clone()中重写原本 
的属性和方法 
function __clone(){ 
//$this指的复本p2, 而$that是指向原本p1,这样就在本方法里,改变了复本的属性。 
$this->name="我是假的$that->name"; 
$this->age=30; 
} 
} 
$p1=new Person("张三", "男", 20); 
$p2=clone $p1; 
$p1->say(); 
$p2->say(); 
?>

上例输出:
执行结果
我的名子叫:张三性别:男我的年龄是:20
我的名子叫:我是假的张三性别:男我的年龄是:30
18.__call 处理调用错误
在程序开发中,如果在使用对象调用对象内部方法时候,调用的这个方法不存在那么程
序就会出错,然后程序退出不能继续执行。那么可不可以在程序调用对象内部不存在的方法
时,提示我们调用的方法及使用的参数不存在,但程序还可以继续执行,这个时候我们就要
使用在调用不存在的方法时自动调用的方法“__call()”。
代码片段
<?php 
//这是一个测试的类,里面没有属性和方法 
class Test{ 
} 
//产生一个Test类的对象 
$test=new Test(); 
//调用对象里不存在的方法 
$test->demo("one", "two", "three"); 
//程序不会执行到这里 
echo "this is a test<br>"; 
?>

上例出现如下错误,程序通出不能继续执行;
Fatal error: Call to undefined method Test::demo()
下面我们加上“__call()”方法,这个方法有2 个参数,第一个参数为调用不存在的方法
过程中,自动调用__call()方法时,把这个不存在的方法的方法名传给第一个参数,第二个参
数则是把这个方法的多个参数以数组的形式传进来。
代码片段
<?php 
//这是一个测试的类,里面没有属性和方法 
class Test{ 
//调用不存的方法时自动调用的方法,第一个参数为方法名,第二个参数是数组参数 
function __call($function_name, $args){ 
print "你所调用的函数:$function_name(参数:"; 
print_r($args); 
print ")不存在!<br>\n"; 
} 
} 
//产生一个Test类的对象 
$test=new Test(); 
//调用对象里不存在的方法 
$test->demo("one", "two", "three"); 
//程序不会退出可以执行到这里 
echo "this is a test<br>"; 
?>

上例输出结果为:
执行结果
你所调用的函数: demo(参数:Array ( [0] => one [1] => two [2] => three ) )不存在!
this is a test.
PHP 相关文章推荐
由php if 想到的些问题
Mar 22 PHP
wiki-shan写的php在线加密的解密程序
Sep 07 PHP
php fckeditor 调用的函数
Jun 21 PHP
php中使用explode查找某个字符是否存在的方法
Jul 12 PHP
php object转数组示例
Jan 15 PHP
php中define用法实例
Jul 30 PHP
使用PHP进行微信公众平台开发的示例
Aug 21 PHP
PHP程序中的文件锁、互斥锁、读写锁使用技巧解析
Mar 21 PHP
PHP实现链式操作的三种方法详解
Nov 16 PHP
PHP7新功能总结
Apr 14 PHP
Laravel框架之解决前端显示图片问题
Oct 24 PHP
PHP安全之register_globals的on和off的区别
Jul 23 PHP
php面向对象全攻略 (十) final static const关键字的使用
Sep 30 #PHP
php面向对象全攻略 (九)访问类型
Sep 30 #PHP
php面向对象全攻略 (八)重载新的方法
Sep 30 #PHP
php面向对象全攻略 (七) 继承性
Sep 30 #PHP
php面向对象全攻略 (六)__set() __get() __isset() __unset()的用法
Sep 30 #PHP
php面向对象全攻略 (五) 封装性
Sep 30 #PHP
php面向对象全攻略 (四)构造方法与析构方法
Sep 30 #PHP
You might like
使用session判断用户登录用户权限(超简单)
2013/06/08 PHP
从PHP的源码中深入了解stdClass类
2014/04/18 PHP
PHP5.5和之前的版本empty函数的不同之处
2014/06/13 PHP
PHP用mb_string函数库处理与windows相关中文字符及Win环境下开启PHP Mb_String方法
2015/11/11 PHP
php 数组随机取值的简单实例
2016/05/23 PHP
PHP的mysqli_set_charset()函数讲解
2019/01/23 PHP
JavaScript URL参数读取改进版
2009/01/16 Javascript
js保留两位小数使用toFixed实现
2013/07/29 Javascript
javascript不同类型数据之间的运算的转换方法
2014/02/13 Javascript
字段太多jquey快速清空表单内容方法
2014/08/21 Javascript
JavaScript参数个数可变的函数举例说明
2014/10/10 Javascript
使用jquery动态加载js文件的方法
2014/12/24 Javascript
纯JavaScript代码实现文本比较工具
2016/02/17 Javascript
利用AJAX实现WordPress中的文章列表及评论的分页功能
2016/05/17 Javascript
基于jQuery实现数字滚动效果
2017/01/16 Javascript
微信小程序页面滑动屏幕加载数据效果
2020/11/16 Javascript
js防刷新的倒计时代码 js倒计时代码
2017/09/06 Javascript
结合Vue控制字符和字节的显示个数的示例
2018/05/17 Javascript
vue 中的keep-alive实例代码
2018/07/20 Javascript
JavaScript函数节流和函数去抖知识点学习
2018/07/31 Javascript
vue自定义指令限制输入框输入值的步骤与完整代码
2020/08/30 Javascript
nuxt.js服务端渲染中axios和proxy代理的配置操作
2020/11/06 Javascript
[00:56]2014DOTA2国际邀请赛 DK、iG 赛前探访
2014/07/10 DOTA
[54:33]2018DOTA2亚洲邀请赛小组赛 A组加赛 Liquid vs Optic
2018/04/03 DOTA
[44:41]Fnatic vs Liquid 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python面向对象程序设计之类的定义与继承简单示例
2019/03/18 Python
pyqt5 tablewidget 利用线程动态刷新数据的方法
2019/06/17 Python
Numpy(Pandas)删除全为零的列的方法
2020/09/11 Python
python 用Matplotlib作图中有多个Y轴
2020/11/28 Python
用C或者C++语言实现SOCKET通信
2015/02/24 面试题
毕业生个人求职信范例分享
2013/12/17 职场文书
公司股权转让协议书
2014/04/12 职场文书
任命书怎么写
2014/06/04 职场文书
会议开幕词
2015/01/28 职场文书
欠条样本
2015/07/03 职场文书
Java9新特性之Module模块化编程示例演绎
2022/03/16 Java/Android