PHP function overloading

前端 未结 10 895
北恋
北恋 2020-11-22 17:24

Coming from C++ background ;)
How can I overload PHP functions?

One function definition if there are any arguments, and another if there are no arguments? Is it

相关标签:
10条回答
  • 2020-11-22 17:31

    PHP doesn't support traditional method overloading, however one way you might be able to achieve what you want, would be to make use of the __call magic method:

    class MyClass {
        public function __call($name, $args) {
    
            switch ($name) {
                case 'funcOne':
                    switch (count($args)) {
                        case 1:
                            return call_user_func_array(array($this, 'funcOneWithOneArg'), $args);
                        case 3:
                            return call_user_func_array(array($this, 'funcOneWithThreeArgs'), $args);
                     }
                case 'anotherFunc':
                    switch (count($args)) {
                        case 0:
                            return $this->anotherFuncWithNoArgs();
                        case 5:
                            return call_user_func_array(array($this, 'anotherFuncWithMoreArgs'), $args);
                    }
            }
        }
    
        protected function funcOneWithOneArg($a) {
    
        }
    
        protected function funcOneWithThreeArgs($a, $b, $c) {
    
        }
    
        protected function anotherFuncWithNoArgs() {
    
        }
    
        protected function anotherFuncWithMoreArgs($a, $b, $c, $d, $e) {
    
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 17:31

    Sadly there is no overload in PHP as it is done in C#. But i have a little trick. I declare arguments with default null values and check them in a function. That way my function can do different things depending on arguments. Below is simple example:

    public function query($queryString, $class = null) //second arg. is optional
    {
        $query = $this->dbLink->prepare($queryString);
        $query->execute();
    
        //if there is second argument method does different thing
        if (!is_null($class)) { 
            $query->setFetchMode(PDO::FETCH_CLASS, $class);
        }
    
        return $query->fetchAll();
    }
    
    //This loads rows in to array of class
    $Result = $this->query($queryString, "SomeClass");
    //This loads rows as standard arrays
    $Result = $this->query($queryString);
    
    0 讨论(0)
  • 2020-11-22 17:37
    <?php
    
        class abs
        {
            public function volume($arg1=null, $arg2=null, $arg3=null)
            {   
                if($arg1 == null && $arg2 == null && $arg3 == null)
            {
                echo "function has no arguments. <br>";
            }
    
            else if($arg1 != null && $arg2 != null && $arg3 != null)
                {
                $volume=$arg1*$arg2*$arg3;
                echo "volume of a cuboid ".$volume ."<br>";
                }
                else if($arg1 != null && $arg2 != null)
                {
                $area=$arg1*$arg2;
                echo "area of square  = " .$area ."<br>";
                }
                else if($arg1 != null)
                {
                $volume=$arg1*$arg1*$arg1; 
                echo "volume of a cube = ".$volume ."<br>";
                }
    
    
            }
    
    
        }
    
        $obj=new abs();
        echo "For no arguments. <br>";
        $obj->volume();
        echo "For one arguments. <br>";
        $obj->volume(3);
        echo "For two arguments. <br>";
        $obj->volume(3,4);
        echo "For three arguments. <br>";
        $obj->volume(3,4,5);
        ?>
    
    0 讨论(0)
  • 2020-11-22 17:38

    To over load a function simply do pass parameter as null by default,

    class ParentClass
    {
       function mymethod($arg1 = null, $arg2 = null, $arg3 = null)  
         {  
            if( $arg1 == null && $arg2 == null && $arg3 == null ){ 
               return 'function has got zero parameters <br />';
            }
            else
            {
               $str = '';
               if( $arg1 != null ) 
                  $str .= "arg1 = ".$arg1." <br />";
    
               if( $arg2 != null ) 
                  $str .= "arg2 = ".$arg2." <br />";
    
               if( $arg3 != null ) 
                  $str .= "arg3 = ".$arg3." <br />";
    
               return $str;
             }
         }
    }
    
    // and call it in order given below ...
    
     $obj = new ParentClass;
    
     echo '<br />$obj->mymethod()<br />';
     echo $obj->mymethod();
    
     echo '<br />$obj->mymethod(null,"test") <br />';
     echo $obj->mymethod(null,'test');
    
     echo '<br /> $obj->mymethod("test","test","test")<br />';
     echo $obj->mymethod('test','test','test');
    
    0 讨论(0)
  • 2020-11-22 17:38
    <?php   
    /*******************************
     * author  : hishamdalal@gmail.com 
     * version : 3.8
     * create on : 2017-09-17
     * updated on : 2020-01-12
     *****************************/
    
    #> 1. Include Overloadable class
    
    class Overloadable
    {
        static function call($obj, $method, $params=null) {
            $class = get_class($obj);
            // Get real method name
            $suffix_method_name = $method.self::getMethodSuffix($method, $params);
    
            if (method_exists($obj, $suffix_method_name)) {
                // Call method
                return call_user_func_array(array($obj, $suffix_method_name), $params);
            }else{
                throw new Exception('Tried to call unknown method '.$class.'::'.$suffix_method_name);
            }
        }
    
        static function getMethodSuffix($method, $params_ary=array()) {
            $c = '__';
            if(is_array($params_ary)){
                foreach($params_ary as $i=>$param){
                    // Adding special characters to the end of method name 
                    switch(gettype($param)){
                        case 'array':       $c .= 'a'; break;
                        case 'boolean':     $c .= 'b'; break;
                        case 'double':      $c .= 'd'; break;
                        case 'integer':     $c .= 'i'; break;
                        case 'NULL':        $c .= 'n'; break;
                        case 'object':
                            // Support closure parameter
                            if($param instanceof Closure ){
                                $c .= 'c';
                            }else{
                                $c .= 'o'; 
                            }
                        break;
                        case 'resource':    $c .= 'r'; break;
                        case 'string':      $c .= 's'; break;
                        case 'unknown type':$c .= 'u'; break;
                    }
                }
            }
            return $c;
        }
        // Get a reference variable by name
        static function &refAccess($var_name) {
            $r =& $GLOBALS["$var_name"]; 
            return $r;
        }
    }
    //----------------------------------------------------------
    #> 2. create new class
    //----------------------------------------------------------
    
    class test 
    {
        private $name = 'test-1';
    
        #> 3. Add __call 'magic method' to your class
    
        // Call Overloadable class 
        // you must copy this method in your class to activate overloading
        function __call($method, $args) {
            return Overloadable::call($this, $method, $args);
        }
    
        #> 4. Add your methods with __ and arg type as one letter ie:(__i, __s, __is) and so on.
        #> methodname__i = methodname($integer)
        #> methodname__s = methodname($string)
        #> methodname__is = methodname($integer, $string)
    
        // func(void)
        function func__() {
            pre('func(void)', __function__);
        }
        // func(integer)
        function func__i($int) {
            pre('func(integer '.$int.')', __function__);
        }
        // func(string)
        function func__s($string) {
            pre('func(string '.$string.')', __function__);
        }    
        // func(string, object)
        function func__so($string, $object) {
            pre('func(string '.$string.', '.print_r($object, 1).')', __function__);
            //pre($object, 'Object: ');
        }
        // func(closure)
        function func__c(Closure $callback) {
    
            pre("func(".
                print_r(
                    array( $callback, $callback($this->name) ), 
                    1
                ).");", __function__.'(Closure)'
            );
    
        }   
        // anotherFunction(array)
        function anotherFunction__a($array) {
            pre('anotherFunction('.print_r($array, 1).')', __function__);
            $array[0]++;        // change the reference value
            $array['val']++;    // change the reference value
        }
        // anotherFunction(string)
        function anotherFunction__s($key) {
            pre('anotherFunction(string '.$key.')', __function__);
            // Get a reference
            $a2 =& Overloadable::refAccess($key); // $a2 =& $GLOBALS['val'];
            $a2 *= 3;   // change the reference value
        }
    
    }
    
    //----------------------------------------------------------
    // Some data to work with:
    $val  = 10;
    class obj {
        private $x=10;
    }
    
    //----------------------------------------------------------
    #> 5. create your object
    
    // Start
    $t = new test;
    
    #> 6. Call your method
    
    // Call first method with no args:
    $t->func(); 
    // Output: func(void)
    
    $t->func($val);
    // Output: func(integer 10)
    
    $t->func("hello");
    // Output: func(string hello)
    
    $t->func("str", new obj());
    /* Output: 
    func(string str, obj Object
    (
        [x:obj:private] => 10
    )
    )
    */
    
    // call method with closure function
    $t->func(function($n){
        return strtoupper($n);
    });
    
    /* Output:
    func(Array
    (
        [0] => Closure Object
            (
                [parameter] => Array
                    (
                        [$n] => 
                    )
    
            )
    
        [1] => TEST-1
    )
    );
    */
    
    ## Passing by Reference:
    
    echo '<br><br>$val='.$val;
    // Output: $val=10
    
    $t->anotherFunction(array(&$val, 'val'=>&$val));
    /* Output:
    anotherFunction(Array
    (
        [0] => 10
        [val] => 10
    )
    )
    */
    
    echo 'Result: $val='.$val;
    // Output: $val=12
    
    $t->anotherFunction('val');
    // Output: anotherFunction(string val)
    
    echo 'Result: $val='.$val;
    // Output: $val=36
    
    
    
    
    
    
    
    // Helper function
    //----------------------------------------------------------
    function pre($mixed, $title=null){
        $output = "<fieldset>";
        $output .= $title ? "<legend><h2>$title</h2></legend>" : "";
        $output .= '<pre>'. print_r($mixed, 1). '</pre>';
        $output .= "</fieldset>";
        echo $output;
    }
    //----------------------------------------------------------
    
    0 讨论(0)
  • 2020-11-22 17:45

    What about this:

    function($arg = NULL) {
    
        if ($arg != NULL) {
            etc.
            etc.
        }
    }
    
    0 讨论(0)
提交回复
热议问题