实现原理:
在基类中定义一个公共的调用函数,这里我定义函数名为
handleAction
,
handleAction
函数要实现的功能是首先获取调用该函数的子类名称,然后得到子类的实例,最后约定请求某一接口时,通过传参
handle=要调用的接口函数名
,即可实现接口请求的自动分发了。
在实现之前,我们需要先对PHP中
__CLASS__
、
get_class()
和
get_called_class()
的使用和区别有一定的了解。
我们知道,PHP中可以通过
__CLASS__
可以获取当前的类名,但它是静态绑定的,在子类调用,如果继承了父类,那所得到的依旧是父类的名称,而不是子类的名称,比如:
class
Base
{
function
__construct
(
)
{
echo
__CLASS__
;
static
function
getClass
(
)
{
echo
__CLASS__
;
class
Child
extends
Base
{
$child
=
new
Child
();
child::
getClass
();
此时,无论将子类实例化还是直接调用静态方法,得到的都是父类的名称。如果是想得到子类的名称呢,那该如何实现?
这里就要通过PHP自带其他两个函数
get_class()
和
get_called_class()
来解决这个问题:
get_class()
用于实例调用,加入参数
$this
可解决子类继承调用的问题;
get_called_class()
则是用于静态方法调用,获取当前主调类的类名。
注意:
get_called_class()
需要 PHP>=5.3.0 才支持,可查看
官方手册
。
所以还是刚才的例子:
class
Base
{
function
__construct
(
)
{
echo
get_class
(
$this
);
static
function
getClass
(
)
{
echo
get_called_class
();
class
Child
extends
Base
{
$child
=
new
Child
();
child::
getClass
();
最终得到了我们想要的结果,即在父类中获取当前调用父类函数的子类类名。
了解了这些,接下来开始实现我们题目说的功能。
1、首先,为了减少多次new带来的资源消耗,我们要使用单例模式
在基类中,定义实现单例模式的方法,然后在继承它的子类中调用:
class Base {
private static $instance = array();
* 单例模式
static function getInstance() {
$className = get_called_class();
if (isset(self::$instance[$className])) {
return self::$instance[$className];
self::$instance[$className] = new $className;
return self::$instance[$className];
class Child extends Base {
$child = Child::getInstance();
通过以上实现,就可以得到子类 child
的单例实例了,如果有更多的子类,通过以上实现也可以得到对应子类的单例实例,而不用在每个子类中重复声明单例实现方法,是不是很方便呢。
2、实现自动分发调用对应类中的接口函数
其实开头已经说过,实现起来不难,就是根据接口请求时的传参,然后根据传参值,自动分发调用当前类中的对应接口函数:
class Base {
private static $instance = array();
* 单例模式
static function getInstance() {
$className = get_called_class();
if (isset(self::$instance[$className])) {
return self::$instance[$className];
self::$instance[$className] = new $className;
return self::$instance[$className];
* 根据请求接口时传参,自动分发调用对应类实例中的可执行函数
static function handleAction()
$handleFunction = $_REQUEST['handle'];
$instance = self::getInstance();
$currClassName = get_class($instance);
if (is_callable($currClassName, $handleFunction)) {
echo $instance->$handleFunction();
} else {
echo "Error: Method '" . $handleFunction . "' of class '" . $currClassName . "' does not exist!";
class ChildA extends Base {
function getInfo() {
echo 'This is ChildA';
...
class ChildB extends Base {
function getInfo() {
echo 'This is ChildB';
...
然后在接口中引用:
接口文件A A.php
:
require_once 'Base父类文件';
require_once 'ChildA子类文件';
ChildA::handleAction();
接口文件B B.php
同上。
最后你就可以调用接口时,不管是 get
还是 post
请求,只需带上参数 handle=要调用的接口函数名
即可调用对应子类中的接口函数:
requireUrl:
server/api/A.php?handle=getInfo
server/api/B.php?handle=getInfo
This is ChildA
This is ChildB
以上即可实现通过简洁的代码,将请求自动分发到对应类的接口函数了,是不是很简单呢。