• 什么重载技术?

    • 面向对象语言中,一个类有多个同名方法,每个方法参数不同,这种现象就成为"重载"。
    • 参数不同可以指 数量、类型、顺序不同。
  • 由上面定义可知PHP在同一个类定义多个相同的方法名称会直接导致语法错误,
    PHP的特性决定了其不支持同名函数方式的重载,但是PHP中所说的重载,另有其说,且姿势还不少。
  • 自我认为,PHP不允许名函数存在的重要原因是function_existsmethod_existsis_callable这些API的存在。
  • PHP中主要有以下几种重载方式:

    • 默认参数,定义一个全面的函数版本,不是必须的值在声明时赋予默认值;

      <?php
      
      function baseFun($param0, $param1 = 1, $param2 = true, $param3 = false, $param4 = ''){
         if ($param1 === 1) {
             //TODO  fun1
         } elseif($param2 === true) {
            //TODO  fun2
         } elseif ($param3 === false) {
            //TODO  fun3
         } elseif ($param4 === '') {
            //TODO  fun4
         }
       }
      ?>
    • 定义一个不声明参数的入口函数,函数内使用func_num_args(传递给函数的参数个数)/func_get_args(传递给函数的参数数组)获取参数个数/数组,然后根据参数个数转发到具体实现的函数;

      <?php
      
      function baseFun()
      {
       $args = func_get_args();
       $num  = func_num_args();
       if ($num == 1) {
         func1($args[0]);
       } elseif ($num == 2) {
         func2($args[0], $args[1]);
       } else {
         //func....()
       }
      }
      function func1($param)
      {
       echo $param; 
      }
      function func2($param1, $param2)
      {
       echo $param1,'-----------', $param2; 
      }
      baseFun('a');
      echo "\n";
      baseFun('a', 'b');
      
      
      ?>
    • 自PHP5.6起,可以用变长参数实现重载,func_get_args的另一种形式;

      <?php
      
      function open_database($a, $b=null, $c=null)
      {
      switch (func_num_args())
      {
      case 1:
        $r = fun($a);
        break;
      case 2:
        $r = fun($a, $b);
        break;
      case 3:
        $r = fun($a, $b, $c);
        break;
      default:
          $r = null;
      }
      return $r;
      }
      function fun($a, $b = null, $c = null){
      return 3;
      }
      ?>
    • 对于类中的成员函数,可以通过__call(在一个对象的上下文中,如果调用的方法不能访问,它将被触发)和__callStatic(在一个静态的上下文中,如果调用的方法不能访问,它将被触发)实现重载。

      <?php
      //__call
      class BC
      {
      public function __call($method, $args){
      //         $class = get_class();
          $method = '_' . $method;
          if (method_exists($this, $method)) {
              call_user_func_array([$this, $method], $args);
          }
      }
      }
      class D extends BC
      {
      public function _fun1($param0)
      {
          echo 'fun1:','param0:',$param0;
      }
      public function _func2($param1,$param2)
      {
          echo 'fun2:','param1:',$param1,'----','param2:',$param2;
      }
      }
      $object = new D();
      echo $object->fun1(1);//fun1:param0:1
      echo "\n";
      echo $object->func2(1,2);//fun2:param1:1----param2:2
      ?>
      <?php
      //__callStatic
      class AB
      {
      public static function __callStatic($method, $args)
      {
          $method = '_' . $method;
          $class = get_called_class();
          if (method_exists($class, $method)) {
              call_user_func_array([$class, $method], $args);
          }
      }
      }
      class ABSon extends AB
      {
      static public function _fun1($param)
      {
          echo 'fun1:','param0:',$param;
      }
      
      static public function _fun2($param1, $param2)
      {
          echo 'fun2:','param1:',$param1,'----','param2:',$param2;
      }
      }
      
      ABSon::fun1(1);//fun1:param0:1
      
      ABSon::fun2(2,3);//fun1:param0:1fun2:param1:2----param2:3
      ?>
Last modification:November 17, 2020
如果觉得我的文章对你有用,请随意赞赏