我们来看一下__call()方法:
public function __call($function_name,$arguments)
{
}
__call()在调用的方法不存在时会被自动调用,第一个参数function_name是被调用的方法名,第二个参数arguments是传入参数的数组。
举个栗子:
<?php
class Foo
{
public function __call($function_name,$arguments)
{
var_dump($function_name,$arguments);
}
public function A()
{
echo 'hello world';
}
}
$test = new Foo();
$data1 = 1;
$data2 = 2;
$test->B($data1,$data2);
?>
/*以上例程会输出:
string(1) "B"
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}/
到此算是理解了__call()的基本原理,接下来思考下有哪些优(zhuang)雅(bi)的用法
一、调用的方法不存在时做统一错误处理
public function __call($function_name,$arguments)
{
//统一处理,抛异常,写日志之类的
}
这种用法比较简单,不做过多叙述
二、实现代码简化
假设我们要在BO(Business Object)层使用curl来调用http服务,一般的写法是:
class base
{
public function httpCall($url,$params)
{
//此处假设已经有封装好的CURL类
$result = CURL::request($url,$params);
return $result;
}
}
class bo extends base
{
public function a($params)
{
$url = $urlA;//$urlA指a方法的url,下同
return $this->httpCall($url,$params);
}
public function b($params)
{
$url = $urlB;
return $this->httpCall($url,$params);
}
public function c($params)
{
$url = $urlC;
return $this->httpCall($url,$params);
}
public function d($params)
{
$url = $urlD;
return $this->httpCall($url,$params);
}
.
.
.
}
这样的写法,在bo类里面只实现传参的功能,代码却非常的冗长
使用__call的简化版
class base
{
public function __call($name,$arguments)
{
$className = get_class($this);
$url = $className::$urls[$name];
$params = $arguments[0];
$result = $this->httpCall($url, $params));
return $result;
}
public function httpCall($url,$params)
{
$result = CURL::request($url,$params);
return $result;
}
}
class bo extends base
{
public static $urls = [
'a' => $urlA,//指a方法的url,下同
'b' => $urlB,
'c' => $urlC,
'd' => $urlD,
.
.
.
];
}
可以看到bo类里的代码瞬间就变得非常简洁,就和写配置文件一样。
总结
大部分情况下工程会有很多业务模块,每个业务模块都会有自己的bo类,合理使用__call()方法可以简化很多冗余的代码,提高开发效率,增加可读性,balabala…这都不重要,重要的是用起来非常的优(zhuang)雅(bi)。大家还有别的什么好玩的用法欢迎互相讨论学习。