Подтвердить что ты не робот

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

Я начал OOP с Java, и теперь я очень сильно вписываюсь в PHP. Можно ли создавать кратные функции с различными аргументами, например, в Java? Или интерпретируемый/нетипизированный характер языка предотвратит это и вызовет конфликты?

4b9b3361

Ответ 1

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

Ответ 2

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

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.

Ответ 3

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

Более длинный ответ: вы можете сделать это, создав запутанную систему include, включающую функцию с правильным количеством аргументов. Или, еще лучше, вы можете воспользоваться 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");
?>

Ответ 4

Невозможно выполнить с 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

Как и все остальные, он не поддерживается по умолчанию. Пример Felix с использованием __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

Ответ 6

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

Таким образом, вызывающий может давать разные аргументы. Однако это вызовет ту же функцию.

Пример:

function test($a = true)

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

Ответ 7

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

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

Ответ 8

Я знаю, это немного старая проблема, но с 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

Ответ 9

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

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