PHP function overloading

前端 未结 10 900
北恋
北恋 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:38

     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 '

    $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 = "
    "; $output .= $title ? "

    $title

    " : ""; $output .= '
    '. print_r($mixed, 1). '
    '; $output .= "
    "; echo $output; } //----------------------------------------------------------

提交回复
热议问题