转载自:http://cnn237111.blog.51cto.com/2359144/1284085

由于PHP是弱类型语言,因此函数的输入参数类型无法确定(可以使用类型暗示,但是类型暗示无法用在诸如整型,字符串之类的标量类型上),并且对于一个函数,比如只定义了3个输入参数,PHP却运行调用的时候输入4个或者更多的参数。因此基于这2点,注定了PHP中无法重载函数,(类似Javascript语言),也无法有构造函数的重载。

由于实现函数的重载对提高开发效率很有帮助,如果能象C#或者C++那样,那就非常好了。事实上,PHP的提供了一个魔术方法,mixed __call ( string name, array arguments )。这个方法在php手册中也有提及,根据官方文档,称此方法可以实现函数重载。当调用对象中一个不存在的方法的时候,如果定义了__call()方法,则会调用该方法。比如下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
class A
{
   function __call ( $name$arguments )
    {
        echo "__call调用<br/>";
        echo '$name为'.$name."<br/>";
        print_r ($arguments);
    }
}
(new A)->test("test","argument");
?>

运行结果为:

__call调用

$name为test

Array ( [0] => test [1] => argument )

因此只需要利用该魔术方法既可以实现函数重载。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
class A
{
     function __call ($name$args )
    {
        if($name=='f')
        {
            $i=count($args);
            if (method_exists($this,$f='f'.$i)) {
                call_user_func_array(array($this,$f),$args);
            }
        }
    }
    function f1($a1)
    {
        echo "1个参数".$a1."<br/>";
    }
    function f2($a1,$a2)
    {
        echo "2个参数".$a1.",".$a2."<br/>";
    }
    function f3($a1,$a2,$a3)
    {
          echo "3个参数".$a1.",".$a2.",".$a3."<br/>";
    }
}
(new A)->f('a');
(new A)->f('a','b');
(new A)->f('a','b','c');
?>

输出如下:

1个参数a   
2个参数a,b    
3个参数a,b,c

同样的在PHP中,实现构造函数的重载,也只能变通的实现。实现的关键要素是获取输入参数,并且根据输入参数判断调用哪个方法。下面是一个示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
class A
{
    function __construct()
    {
        echo "执行构造函数<br/>";
$a = func_get_args(); //获取构造函数中的参数
        $i count($a);
        if (method_exists($this,$f='__construct'.$i)) {
call_user_func_array(array($this,$f),$a);
        }
    }
    function __construct1($a1)
    {
        echo "1个参数".$a1."<br/>";
    }
    function __construct2($a1,$a2)
    {
        echo "2个参数".$a1.",".$a2."<br/>";
    }
function __construct3($a1,$a2,$a3)
    {
          echo "3个参数".$a1.",".$a2.",".$a3."<br/>";
    }
}
$o new A('a');
$o new A('a','b');
$o new A('a','b','c');
?>

执行构造函数   
1个参数a    
执行构造函数    
2个参数a,b    
执行构造函数    
3个参数a,b,c

顺便提一下,和c#等面向对象语言一样,php中,把构造函数设成私有或者protected,就不能实例化该对象了。

PHP中实现函数重载的更多相关文章

  1. C++解析(16):友元与类中的函数重载

    0.目录 1.友元的尴尬能力 2.类中的函数重载 3.小结 1.友元的尴尬能力 什么是友元? 友元是C++中的一种关系 友元关系发生在函数与类之间或者类与类之间 友元关系是单项的,不能传递 友元的用法 ...

  2. 关于在C#中对函数重载理解

    函数重载是个什么概念,才接触的这个概念的时候我也是完全昏了,还在自己看看了书后就理解了.那什么是函数重载呢?我个人理解的是在同一个作用域下有多个同名的函数,但是他们的形参的类型是不同的,或者参数个数是 ...

  3. 《挑战30天C++入门极限》新手入门:C++中的函数重载

        新手入门:C++中的函数重载 函数重载是用来iostream>  using namespace std;  int test(int a,int b);  float test(flo ...

  4. js中的函数重载

    函数重载与js 什么是函数重载 重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数.类型或者顺序)必须不同,也就是说用 ...

  5. c++中的函数重载、函数重写、函数重定义

    目录 一.函数重载 二.函数重写 三.函数重定义 为了更加深刻的理解 函数重载.重写.重定义,我们可以带着如下这两个问题去思考: 1.子类中是否可以定义父类中的同名成员?为什么? 可以,因为子类与父类 ...

  6. 4.C++中的函数重载,C++调用C代码,new/delete关键字,namespace(命名空间)

    本章主要内容: 1)函数重载 2)C++调用C代码 3)new/delete关键字实现动态内存分配 4)namespace命名空间 大家都知道,在生活中,动词和不同的名词搭配一起,意义都会大有不同,比 ...

  7. c++程序设计中的函数重载

    函数重载的意思是在一个作用域内(命名空间内)定义了某个或某些具有相同名称的函数,但是他们的参数列表和定义(实现)不相同,如果相同的话,就没啥意义了.当调用一个重载函数时,编译器会通过所使用的参数类型. ...

  8. C++类中的函数重载

    1,本课程最初阶段就学习了函数重载,但是那时研究目标仅限于全局函数,到目前 为止我们学习了三种函数: 1,全局函数: 2,普通成员函数: 3,静态成员函数: 这三种不同类型的函数之间是否可以构成重载, ...

  9. 从两个角度理解为什么 JS 中没有函数重载

    函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表(参数个数.类型.顺序)的函数,这组函数被称为重载函数.重载函数通常用来声明一组功能相似的函数,这样做减少了函数名的数量,避免了名字空 ...

随机推荐

  1. New Concept English three (24)

    33 72 We often read in novels how a seemingly respectable person or family has some terrible secret ...

  2. 编写configure.ac

    configure.ac由一些宏组成(如果已经有源代码,你可以运行autoscan来产生一个configure.scan文件,在此基础修改成configure.ac将更加方便) 最基本的组成可以是下面 ...

  3. TF随笔-10

    #!/usr/bin/env python# -*- coding: utf-8 -*-import tensorflow as tf x = tf.constant(2)y = tf.constan ...

  4. OpenGL实现3D自由变形

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...

  5. azure最佳实践系列1-自我修复的设计

    如何设计你的应用,能够在系统错误时做到自我修复?在分布式系统中,会经常遇到错误.硬件也会遇到异常情况.网络有时会出现短暂的错误.整个地区出现了服务中断.即便如此,关于这些问题的方案也是要提前规划的.因 ...

  6. js 由快到慢的执行

    let t=0; for(var i=0;i<len;i++){ (function (t) { $timeout(function(){ console.log(t); },t); })(t) ...

  7. hdu 1098

    http://acm.hdu.edu.cn/showproblem.php?pid=1098 假设x=m时,65|f(m),即65|5*m^13+13*m^5+k*a*m 计算f(m+1)=(5*m^ ...

  8. windows 10 安装 sql 2005 安装失败

    windows 10 安装 sql 2005 安装失败 网上的方法记录: 安装中无法启动需要先用sp4的补丁文件sqlos.dll,sqlservr.exe 替换D:\Program Files (x ...

  9. I.MX6 修改调试串口号(ttymx0 -> ttymxc2)

    I.MX6 修改调试串口号(ttymx0 -> ttymxc2) 一.参考文章: uboot修改默认调试串口ttymxc0 ->ttymxc4(imx53) http://www.xueb ...

  10. Why I am not afraid of AI (TBC)

    Freud! Yes, according to Freud's theory, most human activities are driven by libido (or aim-inhibite ...