Та же именованная функция с несколькими аргументами в PHP

Вы не можете изменить отклоненное сообщение, когда оно отправлено в DLQ самим RabbitMQ; по этой причине связыватель предоставляет свойство потребителя republishToDlq, где вместо отклонения сообщения и того, что RabbitMQ отправляет его в DLQ, сам связыватель публикует его там и добавляет заголовки с информацией об исключениях и т. д.

23
задан Luís Cruz 30 April 2015 в 15:31
поделиться

10 ответов

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

41
ответ дан 29 November 2019 в 00:40
поделиться

Если вы имеете дело с классами, вы можете перегружать методы с помощью __call() (см. Перегрузка ), например:

class Foo {
    public function doSomethingWith2Parameters($a, $b) {

    }

    public function doSomethingWith3Parameters($a, $b, $c) {

    }

    public function __call($method, $arguments) {
      if($method == 'doSomething') {
          if(count($arguments) == 2) {
             return call_user_func_array(array($this,'doSomethingWith2Parameters'), $arguments);
          }
          else if(count($arguments) == 3) {
             return call_user_func_array(array($this,'doSomethingWith3Parameters'), $arguments);
          }
      }
   }    
}

Тогда вы можете сделать:

$foo = new Foo();
$foo->doSomething(1,2); // calls $foo->doSomethingWith2Parameters(1,2)
$foo->doSomething(1,2,3); // calls $foo->doSomethingWith3Parameters(1,2,3)

Это может быть не лучшим примером, но иногда __call может быть очень удобным. По сути, вы можете использовать его для отлова вызовов методов на объектах, где этот метод не существует.

Но это не так и не так просто, как в Java.

38
ответ дан 29 November 2019 в 00:40
поделиться

Краткий ответ: Нет. Может быть только одна функция с заданным именем.

Более длинный ответ: Вы можете сделать это, создав запутанную систему включения, которая включает в себя функцию с нужным количеством аргументов. Или, что еще лучше, вы можете воспользоваться PHP, позволяющим использовать значения по умолчанию для параметров, а также переменное количество параметров.

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

function do_something($param1, $param2, $param3 = 'defaultvaule') {}

Распространенной практикой является размещение параметров со значениями по умолчанию в конце объявления функции, поскольку они могут быть опускается при вызове функции и делает синтаксис их использования более понятным:

do_something('value1', 'value2'); // $param3 is 'defaultvaule' by default

Вы также можете отправить переменное количество параметров, используя func_num_args() и func_get_arg(), чтобы получить аргументы:

<?php
  function dynamic_args() {
      echo "Number of arguments: " . func_num_args() . "<br />";
      for($i = 0 ; $i < func_num_args(); $i++) {
          echo "Argument $i = " . func_get_arg($i) . "<br />";
      }
  }

  dynamic_args("a", "b", "c", "d", "e");
?>
9
ответ дан 29 November 2019 в 00:40
поделиться

Следующее невозможно с php

function funcX($a){
    echo $a;
}
function funcX($a,$b){
    echo $a.$b;
}

Вместо этого сделайте так

function funcX($a,$b=2){
    echo $a.$b;
}

funcX(1) отобразит 12, func(1,3) отобразит 13

5
ответ дан 29 November 2019 в 00:40
поделиться

Как и все остальные, по умолчанию он не поддерживается. Пример Феликса с использованием __call(), вероятно, является наилучшим способом.

В противном случае, если вы используете классы, которые наследуются друг от друга, вы всегда можете перегрузить имена методов в ваших дочерних классах. Это также позволяет вам вызывать родительский метод.

Возьмите эти классы, например ...

class Account {
  public function load($key,$type) {
    print("Loading $type Account: $key\n");
  }
}

class TwitterAccount extends Account {
  public $type = 'Twitter';

  public function load($key) {
    parent::load($key,$this->type);
  }
}

Тогда вы можете называть их так ...

$account = new Account();
$account->load(123,'Facebook');

$twitterAccount = new TwitterAccount();
$twitterAccount->load(123);

И ваш результат будет ...

Loading Facebook Account: 123
Loading Twitter Account: 123
2
ответ дан 29 November 2019 в 00:40
поделиться

Нет, это невозможно, потому что PHP не может определить из аргументов, какую функцию вы хотите (вы не указываете, какие типы вы ожидаете). Однако вы можете задать значения по умолчанию для аргументов в php.

Таким образом, вызывающая сторона может давать различное количество аргументов. Это вызовет ту же функцию, хотя.

Пример:

function test($a = true)

Это дает значение по умолчанию true, если задано 0 аргументов, и принимает вызывающее значение, если задан 1 аргумент.

1
ответ дан 29 November 2019 в 00:40
поделиться

Я знаю, что это немного старая проблема, но начиная с php56 вы можете:

function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);

ref: http://php.net/manual/en/functions.arguments.php

1
ответ дан 29 November 2019 в 00:40
поделиться

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

Пределом этого обходного пути является случай, когда требуется перегрузить функцию / метод в соответствии с типами параметров. Это не возможно в PHP, нужно протестировать типы параметров самостоятельно или написать несколько функций. Функции min и max являются хорошим примером этого: если есть один параметр типа массива, он возвращает мин / макс массива, в противном случае он возвращает мин / макс параметров.

0
ответ дан 29 November 2019 в 00:40
поделиться

У меня была идея что-то вроде:

функция process ($ param1, $ type = 'array') {switch ($ type) {case 'array': // сделать что-то с этим break; case 'associative_array': // сделать что-то с этим break; case 'int_array': // сделать что-то с этим break; case 'string': // сделать что-то с этим break; // и т. д. ...}}

0
ответ дан 29 November 2019 в 00:40
поделиться

У меня есть 2 метода, getArrayWithoutKey, которые будут выводить все записи массива без указания значения ключа. Второй метод getArrayWithKey выведет конкретную запись из того же массива, используя значение ключа. Именно поэтому я использовал там метод перегрузки.

class abcClass
{
        private $Arr=array('abc'=>'ABC Variable', 'def'=>'Def Variable');


        public function setArr($key, $value)
        {
            $this->Arr[$key]=$value;
        }

        private function getArrWithKey($key)
        {
            return $this->Arr[$key];
        }
        private function getArrWithoutKey()
        {
            return $this->Arr;
        }

        //Method Overloading in PHP

        public function __call($method, $arguments)
        {
            if($method=='getArr')
            {
                    if(count($arguments)==0)
                    {
                                return $this->getArrWithoutKey();
                    }
                    elseif(count($arguments)==1)
                    {
                                return $this->getArrWithKey(implode(',' , $arguments));
                    }
            }

        }


}

/* Setting and getting values of array-> Arr[] */
$obj->setArr('name', 'Sau');
$obj->setArr('address', 'San Francisco');
$obj->setArr('phone', 7777777777);
echo $obj->getArr('name')."<br>";
print_r( $obj->getArr());
echo "<br>";
0
ответ дан 29 November 2019 в 00:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: