PHP中实现函数重载

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

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

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

运行结果为:

__call调用

$name为test

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

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

代码如下:

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

输出如下:

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

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

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

执行构造函数

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

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

转载于:https://blog.51cto.com/cnn237111/1284085

原文地址:https://www.cnblogs.com/onew/p/12658683.html

时间: 2025-01-05 20:05:46

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

c++中的函数重载

c++中的函数重载 什么是函数重载 重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数.类型或者顺序)必须不同,这组函数被称为重载函数. 函数重载的作用 重载函数常用来实现功能类似而所处理的数据类型不同的问题,能减少函数名的数量,提高程序的可读性. 重载函数的构成说明 定义一个类,添加一系列函数名相同的函数,但参数形式各有不同,测试一下能否构成重载. #include <iostream> using names

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

函数重载是个什么概念,才接触的这个概念的时候我也是完全昏了,还在自己看看了书后就理解了.那什么是函数重载呢?我个人理解的是在同一个作用域下有多个同名的函数,但是他们的形参的类型是不同的,或者参数个数是不同的.当我们调用这些函数时,怎么判断我们调用的是那一个函数呢,这个就要看你在使用重载函数时所传参数的类型或者参数个数.好了,话不说.看看代码就知道了. using System;namespace overload{    class a    {        public void print

js中没有函数重载,怎样实现函数重载的功能?

js中没有函数重载,javasript中使用可选参数:arguments实现相同的功能.. 函数在定义的时候可不定义参数: <script type="text/javascript" > function say() { for (var i = 0; i < arguments.length; i++) { alert(arguments[i].toString()); } } </script> 调用:<input type="but

C++中的函数重载与模板

函数就像工具,工具有好多种,我们就以螺丝刀为例来感受一下它和函数重载和模板的一些相似关系. 螺丝刀的种类有很多,常见的是一字型和梅花型, 每种类型从小到大又有好多个号. 我们根据螺丝样式和大小 选择使用那种类型的和选择多大号的螺丝刀. 螺丝刀就干了一件事,拧螺丝,也就是说各种螺丝刀他们的功能是相 同的,只是类型不同而已. 一.函数重载 在C++中,允许用一个函数名来表达功能相同,只是操作类型(形参个数和类型)不同的函数,这就是函数重载. 编译器能够根据他们各自的实参和形参以及参数的个数进行最佳分

对比C++与Java中的函数重载、覆盖、和隐藏

                                  在C++中 1.函数的重载 C++中的函数的重载要求的是  函数名相同 参数列表必须不同  返回值类型可以相同也可以不相同:只有参数列表不相同,在函数调用时,编译环境才能准确抉择调用的是哪个函数.例如:void display():void display(int  i);void dispaly(double  i);void  display(int i,double i); void display(double  i,i

C/C++中的函数重载(overloading)

几年前,我已经介绍过如何使用const和volatile限定词声明数据.使用这些限定词来声明数据,产生的影响会波及到函数的声明.在C和C++中,影响是不一样的,很大程度上是因为C++中的函数声明比C有更多的功能.为了更清楚描述清楚影响的不同,我们先来看看C和C++中函数最主要的差异是什么. 很多C库包含至少一组的命名非常接近的函数.每个函数除了参数或返回值不同,功能在本质上是相同的. 标准C库也包含若干这样的组.例如,有一组“abs”函数专门用来计算一个数值的绝对值.组里包含: int abs(

第29课 类中的函数重载

函数重载回顾: 类中的重载: 万变不离其宗: 类中的普通成员函数和静态成员函数也够成重载. 示例程序: 1 #include <stdio.h> 2 3 class Test 4 { 5 int i; 6 public: 7 Test() 8 { 9 printf("Test::Test()\n"); 10 this->i = 0; 11 } 12 13 Test(int i) 14 { 15 printf("Test::Test(int i)\n"

类中的函数重载

函数重载回顾: - 函数重载的本质为相互独立的不同函数; -C++通过函数名和函数参数确定函数调用. -无法直接通过函数名得到重载函数的入口地址. -函数重载必然发生在同一作用域. 类中的重载: -构造函数的重载; -普通成员函数的重载 -静态成员函数的重载 Question: 全局函数,普通成员函数以及静态成员函数之间是否可以构成重载. 万变不离其宗: 1.重载函数的本质为多个不同的函数. 2,函数名和参数列表是唯一的标识符; 3.函数重载必然发生在同一作用域. 深度的意义: -通过函数名对函

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

函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表(参数个数.类型.顺序)的函数,这组函数被称为重载函数.重载函数通常用来声明一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处. 但是在 JS 如果不通过一些方法是无法实现重载的,可以从以下两个角度去理解. 1. 方法签名 方法签名指的是函数的名称加形参列表,并且通过函数的名称或者形参列表都可以区分出是不同的函数. JS 中通过形参是没有办法区分出不同的函数的,只能通过函数的名称区分出