К сожалению, в PHP нет перегрузки, как в C #. Но у меня есть маленькая хитрость. Я объявляю аргументы с нулевыми значениями по умолчанию и проверяю их в функции. Таким образом, моя функция может делать разные вещи в зависимости от аргументов. Ниже приведен простой пример:

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

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

 Spechal15 янв. 2011 г., 04:05
Вы можете перегружать только методы класса, но не функции. Видетьphp.net/manual/en/language.oop5.overloading.php
 Edwin Daniels26 февр. 2014 г., 21:46
Какphp.net/manual/en/language.oop5.overloading.php говорит, что определение перегрузки PHP отличается от типичного языка ООП. Они просто ссылаются на магические методы, которые позволяют динамическую маршрутизацию свойств и функций на основе X.
 nawfal29 янв. 2016 г., 12:06
Что-нибудь изменилось с PHP 7? : о
 kolypto15 янв. 2011 г., 04:55
Вы можете создать функцию, которая явно проверяет количество аргументов и выполняет другую функцию из предопределенного набора из них. Как бы то ни было, вам лучше переделать свое решение или использовать классы, реализующие ваш интерфейс
 ToolmakerSteve17 июл. 2015 г., 20:12
Для будущих читателей: то, на что ссылается @Spechal, - это другое значение словаoverloading, чем задается в вопросе. (См. Принятый ответ для более подробной информации.)

Ответы на вопрос(10)

что это будет реализовано в других версиях, как и другие языки программирования.

Оформить заказ этой библиотеки, это позволит вам использовать перегрузку PHP с точки зрения замыканий.https://github.com/Sahil-Gulati/Overloading

 MikeT14 февр. 2017 г., 18:11
если вы собираетесь сделать такое заявление, оно должно действительно включать версии, на которые вы ссылаетесь, таким образом, люди узнают, насколько устарел ваш комментарий, когда они увидят его в будущем.

В PHP 5.6 вы можете использоватьоператор сплат ... в качестве последнего параметра и покончить сfunc_get_args() а такжеfunc_num_args():

function example(...$args)
{
   count($args); // Equivalent to func_num_args()
}

example(1, 2);
example(1, 2, 3, 4, 5, 6, 7);

Вы также можете использовать его для распаковки аргументов:

$args[] = 1;
$args[] = 2;
$args[] = 3;
example(...$args);

Эквивалентно:

example(1, 2, 3);
<?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);
    ?>
 Kashish Arora23 авг. 2014 г., 09:18
Попробуйте отредактировать вопрос и использовать форматирование. Это сделает ваш ответ более читабельным и привлечет больше пользователей.

но я узнал об этом из того, как Cakephp выполняет некоторые функции, и адаптировал его, потому что мне нравится гибкость, которую он создает

Идея в том, что у вас есть другой тип аргументов, массивов, объектов и т. Д., Затем вы обнаруживаете, что вам передали, и идете оттуда

function($arg1, $lastname) {
    if(is_array($arg1)){
        $lastname = $arg1['lastname'];
        $firstname = $arg1['firstname'];
    } else {
        $firstname = $arg1;
    }
    ...
}
 BoltClock♦16 янв. 2011 г., 01:28
Нет, я не считаю это хакерским, 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);
 doug6553607 сент. 2013 г., 11:16
Возможно, я слишком много занимался разработкой на C ++, но я бы предложил намек на то, что это делается в параметрах функции, таких какmyFunc(/*...*/).
 Sz.12 июн. 2014 г., 15:45
@ doug65536, PHP 5.6+ будет поддерживать это«...» как синтаксический маркерК нашему великому облегчению. ;)

просто передайте параметр как ноль по умолчанию,

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');
 Scalable02 дек. 2013 г., 16:31
Я не рассматриваю параметр по умолчанию как перегрузку функции. Перегрузка функции [или метода] больше связана с вызовом другой реализации, основанной на типе передаваемого аргумента. Использование параметров по умолчанию позволяет вам вызывать одну и ту же реализацию с удобством меньшего количества параметров.
 Adil Abbasi02 дек. 2013 г., 17:01
да, вы также можете манипулировать им на основе типов, но, как будто вы знаете свободно типизированный язык php, и для его решения необходимо решить эту проблему.
 ToolmakerSteve17 июл. 2015 г., 20:18
Я предпочитаю этот ответ принятому, поскольку в нем четко указано, каким должно быть минимальное и максимальное количество параметров. (Не указывайте значение по умолчанию для обязательных параметров.) @Scalable - я согласен с Adil в том, что поскольку php свободно набирается, это практически все, что он может означать в php дляoverload функция - тем не менее, вы делаете полезное замечание, о котором читатели должны знать.

однако одним из способов достижения желаемого является использование__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) {

    }

}
 BoltClock♦15 янв. 2011 г., 04:27
Я не видел такого использования__call() до. Довольно креативно (если немного многословно)! +1
 Abhishek Gupta18 мар. 2013 г., 00:03
Действительно замечательное использование __call ()
 Oddman14 мая 2013 г., 09:48
На самом деле, не могу согласиться с этим, и должен осуществить переобучение с этим предложением. Во-первых, использование __call () является анти-паттерном. Во-вторых, в PHP возможна перегрузка для методов классов, которые имеют правильную видимость. Вы не можете, однако, перегрузить обычные функции.
 Stephen14 мая 2013 г., 10:41
Можете ли вы объяснить, почему вы думаете, что использование __call () является анти-паттерном? Перегрузка метода PHP - это не то, что ищет OP - им нужна возможность иметь несколько сигнатур методов с одним и тем же именем, но с разным вводом / выводом:en.wikipedia.org/wiki/Function_overloading
 FantasticJamieBurns27 мая 2013 г., 19:38
Нет необходимости использовать __call (). Вместо этого объявите метод с желаемым именем без перечисленных параметров и используйте func_get_args () в этом методе для отправки в соответствующую частную реализацию.

Как насчет этого:

function($arg = NULL) {

    if ($arg != NULL) {
        etc.
        etc.
    }
}
 Mathias Lykkegaard Lorenzen25 июл. 2013 г., 08:41
Может работать, но менее читабельно, если перегрузка будет иметь разные параметры с разными именами и значениями.

Real Overload (версия 3.8) "без расширения" + "поддержка закрытия"

<?php   
/*******************************
 * author  : [email protected]
 * create on : 2017-09-17
 * updated on : 2019-01-23
 *****************************/

#> 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(closure)
    function func__c(Closure $callback) {
        // your code...
        pre("func__c(".print_r($callback, 1).");", 'print_r(Closure)');
        return $callback($this->name);
    }   
    // 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)
    function func__so($string, $object) {
        pre('func(string='.$string.', object='.get_class($object).')', __function__);
        pre($object, 'Object: ');
    }
    // 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;

pre(
    $t->func(function($n){
        return strtoupper($n);
    })
, 
'Closure');

#> 6. Call your method by typing first part before __ and add method $args if exist

// 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, object=obj)
Object: obj Object
(
    [x:obj:private] => 10
)
*/

## Passing by Reference:

echo '$val='.$val;
// Output: $val=10

$t->anotherFunction(array(&$val, 'val'=>&$val));
// Output: anotherFunction(Array ( [0] => 10 [val] => 10 ) )

echo '$val='.$val;
// Output: $val=12

$t->anotherFunction('val');
// Output: anotherFunction(string=val)

echo '$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;
}
//----------------------------------------------------------
 over_optimistic18 авг. 2013 г., 03:50
Это довольно крутое решение. Почему вы делаете $ o = new $ obj ()? Я еще не пробовал, хотя я думаю, что это должно быть \ $ o = \ $ this?
 Hisham Dalal08 сент. 2013 г., 10:47
Спасибо за это важное уведомление, и я буду использовать обратную косую черту, но она работает с обратной косой чертой и без нее! - Я использую phpEazy в качестве локального сервера.
 Hisham Dalal11 апр. 2013 г., 13:45
1 - создать новый класс 2 - расширяет возможности перегрузки. 3- создавать функции, такие как funcname_ () => без аргументов или как funcname_s ($ s) => строковый аргумент </ li>
 Justus Romijn11 апр. 2013 г., 13:03
Не могли бы вы объяснить, как использовать этот класс?
 Mathias Lykkegaard Lorenzen25 июл. 2013 г., 08:42

в PHP нет перегрузки, как в C #. Но у меня есть маленькая хитрость. Я объявляю аргументы с нулевыми значениями по умолчанию и проверяю их в функции. Таким образом, моя функция может делать разные вещи в зависимости от аргументов. Ниже приведен простой пример:

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

Ваш ответ на вопрос