Web

Перегрузка функций PHP

Как я могу перегрузить функции PHP?

Одинаково ли определение функции, если у нее есть аргументы, и иначе, если аргументов нет? Возможно ли это в PHP? Или я должен использовать if else, чтобы проверить, есть ли параметры, переданные из $_GET и POST, и связать их?

 

Ответ 1

Вы не можете перегружать функции PHP. Сигнатуры функций основываются только на их именах и не включают списки аргументов, поэтому вы не можете иметь две функции с одинаковыми именами. Перегрузка методов классов отличается в PHP от многих других языков. В PHP используется тот же принцип, но он описывает другую схему.

Тем не менее вы можете объявить переменную функцию, которая принимает переменное количество аргументов. Вы будете использовать func_num_args() и func_get_arg(), чтобы получить переданные аргументы и использовать их обычным образом. Например:

function myFunc() {

    for ($i = 0; $i < func_num_args(); $i++) {

        printf("Argument %d: %s\n", $i, func_get_arg($i));

    }

}

 

/*

Argument 0: a

Argument 1: 2

Argument 2: 3.5

*/

myFunc('a', 2, 3.5);

 

 Ответ 2

PHP не поддерживает традиционную перегрузку методов, однако одним из способов добиться желаемого может быть использование «магического» метода __call:

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) {

 

    }

}

 

Ответ 3

Чтобы перегрузить функцию, просто передайте параметр как null по умолчанию:

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;

         }

     }

}

// и вызовите его в порядке, указанном ниже ...

 $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');

 

Ответ 4

<?php   

/*******************************

 * author  : hishamdalal@gmail.com 

 * version : 3.8

 * create on : 2017-09-17

 * updated on : 2020-01-12

 * download example:  https://github.com/hishamdalal/overloadable

 *****************************/

 

#> 1. Include Overloadable class

class Overloadable {

    static function call($obj, $method, $params=null) {

        $class = get_class($obj);

        // Получение реального имени метода

        $suffix_method_name = $method.self::getMethodSuffix($method, $params);

        if (method_exists($obj, $suffix_method_name)) {

            // Вызов метода

            return call_user_func_array(array($obj, $suffix_method_name), $params);

        }else{

            throw new Exception('Попытка вызова неизвестного метода '.$class.'::'.$suffix_method_name);

        }

    }

    static function getMethodSuffix($method, $params_ary=array()) {

        $c = '__';

        if(is_array($params_ary)){

            foreach($params_ary as $i=>$param){

                // Добавление специальных символов в конец имени метода 

                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':

                        // Поддержка параметра закрытия

                        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;

    }

    // Получение ссылочной переменной по имени
    static function &refAccess($var_name) {

        $r =& $GLOBALS["$var_name"]; 

        return $r;

    }

}

//----------------------------------------------------------

#> 2. создать новый класс

//----------------------------------------------------------

 

class test  {

    private $name = 'test-1';

    #> 3. Добавьте __call 'магический метод' в ваш класс

    // Вызов перегружаемого класса 

    // вы должны скопировать этот метод в свой класс, чтобы активировать перегрузку

    function __call($method, $args) {

        return Overloadable::call($this, $method, $args);

    }

    #> 4. Добавьте ваши методы с __ и тип arg как одну букву, т. е.:(__i, __s, __is) и так далее.

    #> 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]++;        // изменение опорного значения

        $array['val']++;    // изменение опорного значения

    }

    // anotherFunction(string)

    function anotherFunction__s($key) {

        pre('anotherFunction(string '.$key.')', __function__);

        // Получение ссылки

        $a2 =& Overloadable::refAccess($key); // $a2 =& $GLOBALS['val'];

        $a2 *= 3;   // изменение опорного значения

    }

}

 

//----------------------------------------------------------

// Немного данных для работы:

$val  = 10;

class obj {

    private $x=10;

}

 

//----------------------------------------------------------

#> 5. Создайте свой объект

// Начать

$t = new test;

#> 6. Вызовите свой метод

// Вызовите первый метод без args:

$t->func(); 

// Вывод: func(void)

 

$t->func($val);

// Вывод: func(integer 10)

 

$t->func("hello");

// Вывод: func(string hello)

 

$t->func("str", new obj());

/* Вывод: 

func(string str, obj Object (

    [x:obj:private] => 10

)

)

*/

// вызов метода с функцией закрытия

$t->func(function($n){

    return strtoupper($n);

});

 

/* Вывод:

func(Array (

    [0] => Closure Object  (

            [parameter] => Array  (

                    [$n] => 

                )

        )

    [1] => TEST-1

)

);

*/

 

## Передача по ссылке:

echo '<br><br>$val='.$val;

// Вывод: $val=10

$t->anotherFunction(array(&$val, 'val'=>&$val));

/* Output:

anotherFunction(Array (

    [0] => 10

    [val] => 10

)

)

*/

echo 'Result: $val='.$val;

// Вывод: $val=12

$t->anotherFunction('val');

// Вывод: anotherFunction(string val)

echo 'Result: $val='.$val;

// Вывод: $val=36

// Вспомогательные функции

//----------------------------------------------------------

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;

}

//----------------------------------------------------------

 

 Ответ 5

Еще один вариант использования:

<?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 "Без аргументов. <br>";

    $obj->volume();

    echo "Для одного аргумента. <br>";

    $obj->volume(3);

    echo "Для двух аргументов. <br>";

    $obj->volume(3,4);

    echo "Для трех аргументов. <br>";

    $obj->volume(3,4,5);

    ?>

 

Схожие статьи

Web

Laravel 5 — перенаправление на HTTPS

Web

Как изменить mysql на mysqli?

Web

Как выполнить цикл по массиву в php с форматированным html оформлением?

Web

Принудительная загрузка файла с помощью PHP

×