PHP 重载 __call() _callStatic方法
在C++和java中,可以函数参数的个数或类型来进行重载。但php是弱类型的语言,无法采用传统的方法。若下面这样;
class Person{
function fun1($a)
{
echo 'fun1 '.$a.'<br/>';
}
function fun1($a,$b)
{
echo 'fun1 '.$a.' '.$b.' <br/>';
}
}
$t=new Person();
$t->fun1(1);
会报错:
Fatal error: Cannot redeclare PropertyTest::fun1()。
所以php采用了一套新的方法。
__call() is triggered when invoking inaccessible methods in an object context.
PHP5 的对象新增了一个专用方法 __call(),这个方法用来监视一个对象中的其它方法。如果你试着调用一个对象中不存在的方法,__call 方法将会被自动调用。
例七:__call
<?php
class foo {
function __call($name,$arguments) {
print("Did you call me? I'm $name!");
}
} $x = new foo();
$x->doStuff();
$x->fancy_stuff();
?>
这个特殊的方法可以被用来实现“过载(overloading)”的动作,这样你就可以检查你的参数并且通过调用一个私有的方法来传递参数。
例八:使用 __call 实现“过载”动作
<?php
class Magic {
function __call($name,$arguments) {
if($name=='foo') {
if(is_int($arguments[0])) $this->foo_for_int($arguments[0]);
if(is_string($arguments[0])) $this->foo_for_string($arguments[0]);
}
} private function foo_for_int($x) {
print("oh an int!");
} private function foo_for_string($x) {
print("oh a string!");
}
} $x = new Magic();
$x->foo(3);
$x->foo("3");
?>
引自:
_call和___callStatic这两个函数是php类 的默认函数,
__call() 在一个对象的上下文中,如果调用的方法不能访问,它将被触发
__callStatic() 在一个静态的上下文中,如果调用的方法不能访问,它将被触发
实例:
<?php
abstract class Obj
{
protected $property = array(); abstract protected function show(); public function __call($name,$value)
{
if(preg_match("/^set([a-z][a-z0-9]+)$/i",$name,$array))
{
$this->property[$array[1]] = $value[0];
return;
}
elseif(preg_match("/^get([a-z][a-z0-9]+)$/i",$name,$array))
{
return $this->property[$array[1]];
}
else
{
exit("<br>;Bad function name '$name' ");
} }
} class User extends Obj
{
public function show()
{
print ("Username: ".$this->property['Username']."<br>;");
//print ("Username: ".$this->getUsername()."<br>;");
print ("Sex: ".$this->property['Sex']."<br>;");
print ("Age: ".$this->property['Age']."<br>;");
}
} class Car extends Obj
{
public function show()
{
print ("Model: ".$this->property['Model']."<br>;");
print ("Sum: ".$this->property['Number'] * $this ->property['Price']."<br>;");
}
} $user = new User;
$user ->setUsername("Anny");
$user ->setSex("girl");
$user ->setAge(20);
$user ->show(); print("<br>;<br>;"); $car = new Car;
$car ->setModel("BW600");
$car ->setNumber(5);
$car ->setPrice(40000);
$car ->show();
?>
更多参考:hhttp://php.net/manual/zh/language.oop5.overloading.php 提供了很多例子。
http://www.garfieldtech.com/blog/magical-php-call
php 5.3 后新增了 __call 与__callStatic 魔法方法。
__call 当要调用的方法不存在或权限不足时,会自动调用__call 方法。
__callStatic 当调用的静态方法不存在或权限不足时,会自动调用__callStatic方法。
__call($funcname, $arguments)
__callStatic($funcname, $arguments)
参数说明:
$funcname String 调用的方法名称。
$arguments Array 调用方法时所带的参数。
__call 例子
<?php
class Member{
protected $memberdata = array();
public function __call($func, $arguments){
list($type, $name) = explode('_', $func);
if(!in_array($type, array('set','get')) || $name==''){
return '';
}
switch($type){
case 'set':
$this->memberdata[$name] = $arguments[];
break;
case 'get':
return isset($this->memberdata[$name])? $this->memberdata[$name] : '';
break;
default:
}
}
}
class User extends Member{
public function show(){
if($this->memberdata){
foreach($this->memberdata as $key=>$member){
echo $key.':'.$member.'<br>';
}
}
}
}
class Profession extends Member{
public function show(){
if($this->memberdata){
foreach($this->memberdata as $key=>$member){
echo $key.':'.$member.'<br>';
}
}
}
}
$userobj = new User();
$userobj->set_name('fdipzone');
$userobj->set_age();
$userobj->show();
$probj = new Profession();
$probj->set_profession('IT SERVICE');
$probj->set_price();
$probj->show();
?>
__callStatic例子
<?php
class Member{
protected static $memberdata = array();
public static function __callStatic($func, $arguments){
list($type, $name) = explode('_', $func);
if(!in_array($type, array('set','get')) || $name==''){
return '';
}
$feature = get_called_class();
switch($type){
case 'set':
self::$memberdata[$feature][$name] = $arguments[0];
break;
case 'get':
return isset(self::$memberdata[$feature][$name])? self::$memberdata[$feature][$name] : '';
break;
default:
}
}
}
class User extends Member{
public static function show(){
$feature = get_called_class();
if(self::$memberdata[$feature]){
foreach(self::$memberdata[$feature] as $key=>$member){
echo $key.':'.$member.'<br>';
}
}
}
}
class Profession extends Member{
public static function show(){
$feature = get_called_class();
if(self::$memberdata[$feature]){
foreach(self::$memberdata[$feature] as $key=>$member){
echo $key.':'.$member.'<br>';
}
}
}
}
User::set_name('fdipzone');
User::set_age(29);
User::show();
Profession::set_profession('IT SERVICE');
Profession::set_price(2500);
Profession::show();
?>
PHP 重载 __call() _callStatic方法的更多相关文章
- PHP面向对象_重载新的方法(parent::)
在学习PHP 这种语言中你会发现, PHP中的方法是不能重载的, 所谓的方法重载就是定义相同的方法名,通过“参数的个数“不同或“参数的类型“不 同,来访问我们的相同方法名的不同方法.但是因为PHP是弱 ...
- 【PHP面向对象(OOP)编程入门教程】12.重载新的方法(parent::)
在学习PHP 这种语言中你会发现, PHP中的方法是不能重载的, 所谓的方法重载就是定义相同的方法名,通过“参数的个数“不同或“参数的类型“不 同,来访问我们的相同方法名的不同方法.但是因为PHP是弱 ...
- 子类重载父类的方法“parent::方法名”转于 恩聪PHP学习教程
在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...
- Java学习笔记之方法重载,动态方法调度和抽象类
一.方法重载 如果子类中的方法与它的超类中的方法有相同的方法名,则称子类中的方法重载超类中的方法,特别是当超类和子类中的方法名和参数类型都相同时,在子类中调用该方法时,超类中的方法会被隐藏.考虑下面程 ...
- 子类重载父类的方法“parent:方法名”
在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...
- Java常见面试题02-方法重写和方法重载的区别?方法重载能改变返回值类型吗?
方法重写和方法重载的区别?方法重载能改变返回值类型吗? A:Override方法重写和Overload方法重载的区别? Overload是否可以改变返回值类型?可以 方法重写 • 子类中 ...
- PHP的重载及魔术方法
首先你要知道什么是php的魔术方法,它不是变魔术的,如果你想学习变魔术来错地方了哦! 定义:PHP 将所有以 __(两个下划线)开头的类方法保留为魔术方法.所以在定义类方法时,除了上述魔术方法,建议不 ...
- PHP的重载-使用魔术方法实现
摘录PHP官网对PHP重载的解释: PHP所提供的"重载"(overloading)是指动态地"创建"类属性和方法.我们是通过魔术方法(magic method ...
- Java编译器如何生成重载和覆盖方法代码
下面是一个很简单的例子,关于Java中的多态:方法重载和方法覆盖: 多态指的是方法在不同的时刻表现出不同的形式:在编译期间,这被叫做方法重载:方法重载允许相关的方法被同一个方法名字调用,这有时候被叫做 ...
随机推荐
- 27_Blog Reader
这个App是用来读取 Official Google Blog 的内容,然后显示出来. 用了新建工程时用了 Master-Detail Application 这个模板.用了Core Data用来存储 ...
- Protel99se轻松入门:特殊技巧和高级设置(一)
这里简单介绍一下自动布线和手动布线方面的设置问题 1.如何进入PCB的这个布线规则选项: 2.电气安全距离的设置 3.导线宽度的设置 4.学会了设置图层就可以做单面板以及多层板,而不只是双面板 5.布 ...
- [置顶] SOLR 4.4 部署
SOLR 4.4 部署 前言:近期研究下solr4.4的部署,一下是部署步骤,与大家分享下. 下载solr4.4.0.zip 地址 http://mirror.esocc.com/apa ...
- invalid nib registered for identifier (重用符) - nib must contain exactly one top level object which must be a UITableViewCell instance'
通过xib创建cell的时候 一定要注意!!! 这个错误是在这个xib中在View同一层级出现了其他的控件,检查一下xib中左边的层级关系,让cell的view是唯一的控件就可以了,否则一执行 就会提 ...
- grunt用来压缩前端脚本
grunt作为一个任务管理工具,提供丰富的插件和强大的自动化管理功能.需要安装node及npm. 主要使用到两个文件,一个是npm的依赖配置文件package.json { "name&qu ...
- 开发板-PC机(宿主机)-虚拟机(VM)之间网络通信设置方法及须要注意的问题
1.不使用路由器交换机 硬件连接: 使用网线将开发板和PC机相连 串口线将PC机和开发板相连 使用命令: ifconfig -a 串口控制端查看开发板的网络配置 route -n 串口控制端查看开发板 ...
- Objective-c 方法的调用
在书写了类的声明和实现后,应用程序如何去调用它呢? 在Objective-c中,调用方法的简单格式如下: 1⃣ [实例 方法]; 如: [person setAge:32]; 其中 pe ...
- doctype(文档类型)的作用是什么?转载
<!DOCTYPE> 声明位于文档中的最前面的位置,处于 <html> 标签之前.此标签可告知浏览器文档使用哪种 HTML 或 XHTML 规范. Document Type ...
- 关于移动端 rem 布局的一些总结
[资源一]基础知识恕不回顾 基础知识参考以下两篇博客: http://isux.tencent.com/web-app-rem.html http://www.w3cplus.com/css3/def ...
- JavaSE学习总结第17天_集合框架3
17.01 ArrayList集合的toString()方法源码解析 代码: Collection c = new ArrayList(); c.add("hello"); c ...