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脚本数据库功能详解(下)
Oct 09 PHP
超强分页类2.0发布,支持自定义风格,默认4种显示模式
Jan 02 PHP
php缩放图片(根据宽高的等比例缩放)实例介绍
Jun 09 PHP
FireFox浏览器使用Javascript上传大文件
Oct 30 PHP
Windows和Linux中php代码调试工具Xdebug的安装与配置详解
May 08 PHP
PHP中魔术变量__METHOD__与__FUNCTION__的区别
Sep 29 PHP
PHP魔术方法__GET、__SET使用实例
Nov 25 PHP
php 5.6版本中编写一个PHP扩展的简单示例
Jan 20 PHP
PHP 数组遍历foreach语法结构及实例
Jun 13 PHP
PHP中Notice错误常见解决方法
Apr 28 PHP
php之可变变量的实例详解
Sep 12 PHP
PHP CURL中传递cookie的方法步骤
May 09 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
Laravel5.1自定义500错误页面示例
2016/10/09 PHP
php实现的二分查找算法示例
2017/06/20 PHP
PHP实现时间比较和时间差计算的方法示例
2017/07/24 PHP
PHP实现的支付宝支付功能示例
2019/03/26 PHP
JQuery.ajax传递中文参数的解决方法 推荐
2011/03/28 Javascript
js取滚动条的尺寸的函数代码
2011/11/30 Javascript
简易的投票系统以及js刷票思路和方法
2015/04/07 Javascript
DOM 高级编程
2015/05/06 Javascript
JS与jQ读取xml文件的方法
2015/12/08 Javascript
微信小程序 slider 详解及实例代码
2017/01/10 Javascript
js实现股票实时刷新数据案例
2017/05/14 Javascript
js 只比较时间大小的实例
2017/10/26 Javascript
javascript实现最长公共子序列实例代码
2018/02/05 Javascript
基于vue-ssr的静态网站生成器VuePress 初体验
2018/04/17 Javascript
教你如何用node连接redis的示例代码
2018/07/12 Javascript
微信小程序日历效果
2018/12/29 Javascript
详解使用uni-app开发微信小程序之登录模块
2019/05/09 Javascript
Vue+Bootstrap收藏(点赞)功能逻辑与具体实现
2020/10/22 Javascript
python实现爬虫下载漫画示例
2014/02/16 Python
python2.7 json 转换日期的处理的示例
2018/03/07 Python
Python统计python文件中代码,注释及空白对应的行数示例【测试可用】
2018/07/25 Python
使用Python横向合并excel文件的实例
2018/12/11 Python
python获取微信企业号打卡数据并生成windows计划任务
2019/04/30 Python
Python实现FM算法解析
2019/06/18 Python
python实现小世界网络生成
2019/11/21 Python
Python接口测试环境搭建过程详解
2020/06/29 Python
什么是.net的Remoting技术
2016/07/08 面试题
描述JSP和Servlet的区别、共同点、各自应用的范围
2012/10/02 面试题
高校十八大报告感想
2014/01/27 职场文书
家长会主持词开场白
2014/03/18 职场文书
省级优秀班集体申报材料
2014/05/25 职场文书
2014年团委工作总结
2014/11/13 职场文书
健康状况证明书
2014/11/26 职场文书
环保宣传语大全
2015/07/13 职场文书
银行客户经理培训心得体会
2016/01/09 职场文书
jquery插件实现悬浮的菜单
2021/04/24 jQuery