PHP中overload __call魔术方法 和引用传递的问题
来源:互联网 发布:js在线视频教程 编辑:程序博客网 时间:2024/04/29 19:07
PHP5 中类默认支持 overload(重载)功能,通过这个功能可以实现自定义属性和 overload 方法。在这篇文章里主要谈的是关于 overload 方法的问题。
这里的 overload 其实跟 C++ 中的 overload 不太一样。在这里你可以通过定一个 __call 方法,来处理用户调用的在类中没有定义的方法。用户调用的方法名被作为第一个参数传给 __call 方法,而用户调用该方法的参数被作为一个数组传给 __call 方法的第二个参数。
PHP4 默认不支持 overload 对象,必须用 overload 方法来明确指定那个类需要 overload 。
PHP5 和 PHP4 的 overload __call 有些不一致的地方。PHP5 中 __call 方法有且只有 2 个参数,即 function_name 和 arguments,返回值在 __call 中用 return 语句返回。而在 PHP4 中,__call 方法有第三个可选参数,而且这个参数是引用参数,它代表返回值,如果需要返回值,只需要在 __call 方法中给第三个参数赋值即可。另外 PHP4 中的 __call 方法中,return 语句如果返回真,表示用户调用方法成功,否则表示用户调用方法失败,即用户调用的方法不存在。
PHP5 和 PHP4 的 overload __call 另外一个区别是,PHP5 中用户调用的方法名传给 __call 方法时,是有大小写区分的,而 PHP4 中用户调用的方法名传给 __call 方法时,方法名会全部转化为小写。
这两个程序,大家会发现在 PHP4 中和 PHP5 中的执行结果是不同的。
PHP4 中的结果是:
12122
12233
而 PHP5 中的结果是:
12233
12233
也就是说 PHP4 中 overload __call 方法的类,在引用参数传递时,必须要在调用时的参数前加 & 才能传递引用,否则就变成了值传递。PHP5 就不存在这种情况。
比较有意思的一点是,PHP 手册上写:“注意在函数调用时没有引用符号――只有函数定义中有。光是函数定义就足够使参数通过引用来正确传递了。在最近版本的 PHP 中如果把 & 用在 foo(&$a); 中会得到一条警告说‘Call-time pass-by-reference’已经过时了。 ”
而实际上我们看到,在 overload __call 方法以后的类中,引用传递如果按照手册上写的方式书写的话,不但不能正确传递,反而会得不到引用传递的效果。而只有用它所谓警告的方式写的时候才能得到正 确的结果,而且也没有它所谓的“Call-time pass-by-reference”警告信息。可能手册上写的所谓的最新版本是指 PHP5 吧?(不过在 PHP5 上,上面这段所谓可能引起警告的程序也没有引起任何警告信息)难道是 PHP 手册写错了吗?还是 PHP4 的一个 bug 呢?也许只有官方能够解释了。
这里的 overload 其实跟 C++ 中的 overload 不太一样。在这里你可以通过定一个 __call 方法,来处理用户调用的在类中没有定义的方法。用户调用的方法名被作为第一个参数传给 __call 方法,而用户调用该方法的参数被作为一个数组传给 __call 方法的第二个参数。
PHP4 默认不支持 overload 对象,必须用 overload 方法来明确指定那个类需要 overload 。
PHP5 和 PHP4 的 overload __call 有些不一致的地方。PHP5 中 __call 方法有且只有 2 个参数,即 function_name 和 arguments,返回值在 __call 中用 return 语句返回。而在 PHP4 中,__call 方法有第三个可选参数,而且这个参数是引用参数,它代表返回值,如果需要返回值,只需要在 __call 方法中给第三个参数赋值即可。另外 PHP4 中的 __call 方法中,return 语句如果返回真,表示用户调用方法成功,否则表示用户调用方法失败,即用户调用的方法不存在。
PHP5 和 PHP4 的 overload __call 另外一个区别是,PHP5 中用户调用的方法名传给 __call 方法时,是有大小写区分的,而 PHP4 中用户调用的方法名传给 __call 方法时,方法名会全部转化为小写。
不管是 PHP5 还是 PHP4,overload __call 产生的虚拟方法,都不支持参数的引用传递。还有一个可能没有多少人注意的问题。官方手册和官方手册的用户注释中也没有提到这个问题。那就是 PHP4 在 overload __call 以后,该类中其它的方法在引用传递时,将不再符合手册中的描述。请先看下面的程序:
<?phpclass test1 { function test1() { } function __call($function, $args) { return true; } function inc(&$n) { $n++; return $n; }} if (function_exists("overload") && version_compare(phpversion(), "5", "<")) { overload('test1');} class test2 { function test2() { } function inc(&$n) { $n++; return $n; }}$t1 = new test1();$t2 = new test2(); $n = 1; echo $n;echo $t1->inc($n);echo $n;echo $t1->inc(&$n);echo $n; echo "<br />"; $n = 1; echo $n;echo $t2->inc($n);echo $n;echo $t2->inc(&$n);echo $n; ?>
这两个程序,大家会发现在 PHP4 中和 PHP5 中的执行结果是不同的。
PHP4 中的结果是:
12122
12233
而 PHP5 中的结果是:
12233
12233
也就是说 PHP4 中 overload __call 方法的类,在引用参数传递时,必须要在调用时的参数前加 & 才能传递引用,否则就变成了值传递。PHP5 就不存在这种情况。
比较有意思的一点是,PHP 手册上写:“注意在函数调用时没有引用符号――只有函数定义中有。光是函数定义就足够使参数通过引用来正确传递了。在最近版本的 PHP 中如果把 & 用在 foo(&$a); 中会得到一条警告说‘Call-time pass-by-reference’已经过时了。 ”
而实际上我们看到,在 overload __call 方法以后的类中,引用传递如果按照手册上写的方式书写的话,不但不能正确传递,反而会得不到引用传递的效果。而只有用它所谓警告的方式写的时候才能得到正 确的结果,而且也没有它所谓的“Call-time pass-by-reference”警告信息。可能手册上写的所谓的最新版本是指 PHP5 吧?(不过在 PHP5 上,上面这段所谓可能引起警告的程序也没有引起任何警告信息)难道是 PHP 手册写错了吗?还是 PHP4 的一个 bug 呢?也许只有官方能够解释了。
来自:http://www.coolcode.org/archives/?article-105.html
0 0
- PHP中overload __call魔术方法 和引用传递的问题
- php 魔术方法 __call
- php 魔术方法 __call
- php魔术方法__call和__callStatic
- 关于PHP的魔术方法__call()
- php魔术方法__call的用法
- php __call()魔术方法介绍
- 魔术方法__call 和__callStatic
- PHP魔术方法之__call重载方法
- PHP 魔术方法之 __call 与 __callStatic
- PHP面向对象:魔术方法__call()
- PHP 中__Call()和call_user_func_array()方法的使用方法
- __call 魔术方法
- 魔术方法(__call/__callstatic)
- 魔术方法:__call
- PHP的魔术常量和魔术方法
- PHP魔术方法之__call与__callStatic方法
- PHP魔术方法之__call与__callStatic方法
- hdu 2617 Happy 2009
- 音视频同步基本原理
- 用css实现三角形
- 关于html+ashx开发中几个问题的解决方法
- 一个C笔试题引出一系列的问题
- PHP中overload __call魔术方法 和引用传递的问题
- Android之高仿微信“登录加载框”(四)
- maven 发布jar包到远程仓库,
- 标记一下 :QNetworkAccessManager
- android edittext 自动不获取焦点
- Write Error
- 音视频播放的基本原理
- OSD显示原理
- uva 188(哈希)