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 相关文章推荐
数字转英文
Dec 06 PHP
PHP中查询SQL Server或Sybase时TEXT字段被截断的解决方法
Mar 10 PHP
fetchAll()与mysql_fetch_array()的区别详解
Jun 05 PHP
获取URL文件名后缀
Oct 24 PHP
不使用php api函数实现数组的交换排序示例
Apr 13 PHP
PHP产生不重复随机数的5个方法总结
Nov 12 PHP
php访问数组最后一个元素的函数end()用法
Mar 18 PHP
phalcon框架使用指南
Feb 23 PHP
cakephp常见知识点汇总
Feb 24 PHP
thinkPHP微信分享接口JSSDK用法实例
Jul 07 PHP
PHP PDOStatement::execute讲解
Jan 31 PHP
laravel Model 执行事务的实现
Oct 10 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
PHP封装的验证码工具类定义与用法示例
2018/08/22 PHP
PHP中上传文件打印错误错误类型分析
2019/04/14 PHP
php接口隔离原则实例分析
2019/11/11 PHP
YII2框架中添加自定义模块的方法实例分析
2020/03/18 PHP
JavaScript 事件冒泡简介及应用
2010/01/11 Javascript
让元素在网页中可拖动示例代码
2013/08/13 Javascript
jQuery 获取、设置HTML或TEXT内容的两种方法
2014/05/23 Javascript
使用Plupload实现直接上传附件至七牛云存储
2014/12/26 Javascript
windows 下安装nodejs 环境变量设置
2017/02/02 NodeJs
浅谈 Vue 项目优化的方法
2017/12/16 Javascript
详解Javascript中new()到底做了些什么?
2018/03/29 Javascript
JavaScript中的惰性载入函数及优势
2020/02/18 Javascript
[03:56]DOTA2完美大师赛趣味视频之小鸽子和Mineski打台球
2017/11/24 DOTA
easy_install python包安装管理工具介绍
2013/02/10 Python
python实现简单ftp客户端的方法
2015/06/28 Python
python实现用户登录系统
2016/05/21 Python
Python端口扫描简单程序
2016/11/10 Python
Python+树莓派+YOLO打造一款人工智能照相机
2018/01/02 Python
Python实现二维数组输出为图片
2018/04/03 Python
python 实现交换两个列表元素的位置示例
2019/06/26 Python
Python使用sqlite3模块内置数据库
2020/05/07 Python
详解python中groupby函数通俗易懂
2020/05/14 Python
几款好用的python工具库(小结)
2020/10/20 Python
Python json解析库jsonpath原理及使用示例
2020/11/25 Python
计算 s=(x*y)1/2,用两个宏定义来实现
2016/08/11 面试题
如何判断计算机可能已经中马
2013/03/22 面试题
测绘工程专业个人自我评价
2013/12/01 职场文书
高中英语教学反思
2014/02/04 职场文书
校运动会广播稿300字
2014/10/07 职场文书
学校党的群众路线教育实践活动总结材料
2014/10/30 职场文书
学习普通话的体会
2014/11/07 职场文书
干部考察材料范文
2014/12/24 职场文书
婚礼新人答谢词
2015/01/04 职场文书
辞职信的写法
2015/02/27 职场文书
远程教育学习心得体会
2016/01/23 职场文书
div与span之间的区别与使用介绍
2021/12/06 HTML / CSS