Я начал OOP с Java, и теперь я становлюсь довольно тяжелым в PHP. Можно ли создавать кратные функции с различными аргументами, например, в Java? Или интерпретируемый / нетипизированный характер языка предотвратит это и вызовет конфликты?
У всех остальных есть ответы с хорошими пояснениями кода. Вот объяснение на более высоком уровне: Java поддерживает перегрузку метода , о чем вы говорите, когда вы говорите о функции с тем же именем, но с разными аргументами. Поскольку PHP является динамически типизированным языком, это невозможно. Вместо этого PHP поддерживает аргументы по умолчанию, которые вы можете использовать для получения такого же эффекта.
Если вы имеете дело с классами, вы можете перегружать методы с помощью __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.
Короткий ответ: Нет. Может быть только одна функция с заданным именем.
Более длинный ответ: вы можете сделать это, создав запутанную систему 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"); ?>
Следующее невозможно с 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
Как и все остальные, он не поддерживается по умолчанию. Пример 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);
-$account = new Account(); $account->load(123,'Facebook'); $twitterAccount = new TwitterAccount(); $twitterAccount->load(123);
И ваш результат будет …
Загрузка учетной записи Facebook: 123 Загрузка учетной записи Twitter: 123
Нет, это невозможно, потому что PHP не может вывести из аргументов, которые вы хотите (вы не укажете, какие типы вы ожидаете). Однако вы можете указать значения по умолчанию для аргументов в php.
Таким образом, вызывающий может давать разные аргументы. Однако это вызовет ту же функцию.
Пример:
function test($a = true)
Это дает значение по умолчанию true, если заданы аргументы 0, и принимает значение вызова, если задан 1 аргумент.
Перегрузка невозможна в PHP, но вы можете обойти ее до некоторой степени с значениями параметров по умолчанию, как описано в других ответах.
Предел этого обходного пути – это когда вы хотите перегрузить функцию / метод в соответствии с типами параметров. Это невозможно в PHP, нужно самостоятельно тестировать типы параметров или писать несколько функций. Функции min и max являются хорошим примером этого: если есть один параметр типа массива, он возвращает min / max массива, в противном случае он возвращает min / max параметров.
Я знаю, что это немного старая проблема, но с php56 вы можете:
function sum(...$numbers) { $acc = 0; foreach ($numbers as $n) { $acc += $n; } return $acc; } echo sum(1, 2, 3, 4);
У меня была идея чего-то вроде:
($ param1, $ type = 'array') {switch ($ type) {case 'array': // делать что-то с этим break; case 'associative_array': // делать что-то с этим break; case 'int_array': // делать что-то с этим break; case 'string': // делать что-то с этим break; // etc etc …}}