Функція PHP з додатковими параметрами


107

Я написав функцію PHP, яка може приймати 10 параметрів, але потрібно лише 2. Іноді я хочу визначити восьмий параметр, але я не хочу вводити порожні рядки для кожного з параметрів, поки я не досягне восьмого.

Однією з ідей у ​​мене була передача абстрагованої функції з масивом параметрів, які передають її реальній функції.

Чи є кращий спосіб налаштування функції, щоб я міг передати лише потрібні параметри?


4

Це дивно. Вбудовані функції в php можуть мати необов'язкові параметри. То чому ми не можемо будувати такі функції?
Родріго

2
Зауважте, що багато хто з цих відповідей є ЗАВЕРШЕНО ... PHP тепер підтримує функції зі списками аргументів змінної довжини .
ashleedawg

Відповіді:


62

Змусьте функцію взяти один параметр: масив. Передати фактичні параметри як значення в масиві.


Редагувати: посилання в коментарі Пекки майже підсумовує її.


1
Це дивно. Вбудовані функції в php можуть мати необов'язкові параметри. То чому ми не можемо будувати такі функції?
Родріго

1
@Rodrigo абсолютно можна визначити такі функції, як ті. Вони є необов'язковими для позиції, що є досить паршивим для будь-якого, що перевищує один необов'язковий параметр.
Метт Бал

1
Добре, я намагався з [], тепер я бачу, як це зробити тут: stackoverflow.com/a/34869/1086511
Rodrigo

Можна зробити ще те, що просто пропозиція "використовувати масив" - подивіться на відповідь Вальфа на аналогічне запитання та більш глибокий приклад із тієї ж
теми

63

У цьому випадку я зробив передачу масиву, де ключовим є ім'я параметра, а значення - значення.

$optional = array(
  "param" => $param1,
  "param2" => $param2
);

function func($required, $requiredTwo, $optional) {
  if(isset($optional["param2"])) {
    doWork();
  }
}

Для вашого прикладу, чи не слід $ необов'язково встановлювати глобальну функцію?
user481826

1
глобальний? немає..? Ви створюєте цей масив, перш ніж викликати функцію, і передаєте її. Мій код - приклад опису Метта Кулі, що потрібно зробити.
Rabbott

Можна зробити ще те, що просто пропозиції "використовувати масив" - подивіться на відповідь Вальфа на подібне запитання та більш глибокий приклад у тій же темі
DJDave

45

Щоб виконати те, що ви хочете, використовуйте масив, як сказав Раббот (хоча при надмірному використанні це може створити біль для документування / підтримки). Або просто використовувати традиційні необов'язкові арги.

//My function with tons of optional params
function my_func($req_a, $req_b, $opt_a = NULL, $opt_b = NULL, $opt_c = NULL)
{
  //Do stuff
}
my_func('Hi', 'World', null, null, 'Red');

Однак, як правило, я вважаю, що коли я починаю писати функцію / метод із такою кількістю аргументів - частіше за все це запах коду, і його можна перетворити на фактор / абстрагувати в щось набагато чистіше.

//Specialization of my_func - assuming my_func itself cannot be refactored
function my_color_func($reg_a, $reg_b, $opt = 'Red')
{
  return my_func($reg_a, $reg_b, null, null, $opt);
}
my_color_func('Hi', 'World');
my_color_func('Hello', 'Universe', 'Green');

У 2010 році такі поняття, як "запах коду", "рефакторинг" або "підтримка коду", не були популярними в нашій громаді. У вас був крок перед більшістю з нас :)
Біллал Бегерадж

15

У PHP 5.6 та пізніших версіях списки аргументів можуть включати маркер ... для позначення того, що функція приймає змінну кількість аргументів. Аргументи будуть передані в дану змінну у вигляді масиву; наприклад:

Приклад Використання ... для доступу до аргументів змінної

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

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

Наведений вище приклад виведе:

10

Аргумент змінної довжини перелічує документацію PHP


Ця відповідь заслуговує більше балів. Не підходить для мого конкретного випадку, але хороша інформація та проста для розуміння. PHP 7.3 незабаром! 5.6 і 7 - EOL.
AdheneManx

12

Ви можете просто встановити значення за замовчуванням на null.

<?php
function functionName($value, $value2 = null) {
// do stuff
}

2
Найкраща відповідь, але, будь ласка, замініть nullнебітами типу дати. наприклад array()для масивів
Мохамед гешам

Дякую ... Це те, що я шукав
Девід Де Маестрі

12

ПРИМІТКА. Це стара відповідь для PHP 5.5 та нижче. PHP 5.6+ підтримує аргументи за замовчуванням

У PHP 5.5 та нижче, ви можете досягти цього, використовуючи один із цих двох методів:

  • використання функцій func_num_args () та func_get_arg () ;
  • використання аргументів NULL;

Як використовувати

function method_1()
{
  $arg1 = (func_num_args() >= 1)? func_get_arg(0): "default_value_for_arg1";
  $arg2 = (func_num_args() >= 2)? func_get_arg(1): "default_value_for_arg2";
}

function method_2($arg1 = null, $arg2 = null)
{
  $arg1 = $arg1? $arg1: "default_value_for_arg1";
  $arg2 = $arg2? $arg2: "default_value_for_arg2";
}

Я віддаю перевагу другий метод, тому що він чистий і легкий для розуміння, але іноді може знадобитися перший метод.


1
Вам потрібен подвійний "=" тут або всі вирази повернуться істинними. Крім того, вирази у другому прикладі завжди повертатимуть істину, оскільки змінна завжди дорівнює самій собі.
chuckieDub

хороший момент, але це насправді працює. У PHP цей код $x = null; if ($x) echo "true"; else echo "false";буде надрукувати "false", навіть якщо $ x var має значення ("null" у цьому коді). Також в обох методах ми використовуємо потрійний оператор, тому правильно використовувати лише один "=". Якщо ви протестуєте з method(); method(1); method(1, 2);, тоді перший виклик буде пов'язувати arg1 і arg2 зі значеннями за замовчуванням, другий виклик буде пов'язувати другий аргумент зі значенням за замовчуванням та "1" для першого аргументу. Останній виклик не пов'язує значення за замовчуванням.
Даніель Лурейро

1
функція method_2 ($ arg1 = "default_value_fot_arg1", $ arg2 = "default_value_fot_arg2") {так що php має справу з параметрами і також ви можете передавати null як параметр (чому люди використовують null, я не знаю)
nerkn

1
@nerkn, ви праві, PHP підтримує аргументи за замовчуванням. Лол, я пам’ятаю, коли нам потрібно було зробити багато обхідних шляхів, щоб досягти простих речей. Хороші часи: P Ви все ще можете бачити ці підходи у старих кодах (до -5,5), хоча.
Даніель Лурейро

4

Я думаю, ви також можете використовувати предмети як парам-транспорти.

$myParam = new stdClass();
$myParam->optParam2 = 'something';
$myParam->optParam8 = 3;
theFunction($myParam);

function theFunction($fparam){      
  return "I got ".$fparam->optParam8." of ".$fparam->optParam2." received!";
}

Звичайно, ви повинні встановити значення за замовчуванням для "optParam8" і "optParam2" в цій функції, в іншому випадку ви отримаєте "Примітка: Не визначене властивість: stdClass :: $ optParam2"

Якщо ви використовуєте масиви як параметри функції, мені подобається такий спосіб встановлення значень за замовчуванням:

function theFunction($fparam){
   $default = array(
      'opt1' => 'nothing',
      'opt2' => 1
   );
   if(is_array($fparam)){
      $fparam = array_merge($default, $fparam);
   }else{
      $fparam = $default;
   }
   //now, the default values are overwritten by these passed by $fparam
   return "I received ".$fparam['opt1']." and ".$fparam['opt2']."!";
}

2

Якщо для створення об'єкта з дійсним станом потрібні лише два значення, ви можете просто видалити всі інші необов’язкові аргументи та надати для них задачі (якщо ви не хочете, щоб вони мінялися під час виконання). Потім просто інстанціюйте об'єкт двома необхідними аргументами та встановіть інші за необхідності через сетер.

Подальше читання


2

Я знаю, що це стара посада, але у мене були проблеми, як ОП, і це те, що я придумав.

Приклад масиву, який ви могли пройти. Ви можете повторно замовити це, якщо потрібно буде певне замовлення, але для цього питання це зробить те, що задається.

$argument_set = array (8 => 'lots', 5 => 'of', 1 => 'data', 2 => 'here');

Це керовано, легко для читання, а пункти вилучення даних можна додавати та видаляти на моменти, помітні в будь-якому місці кодування, і все ж уникати масового перезапису. Я використовував цілі клавіші, щоб порівнювати з початковим питанням про ОП, але рядкові клавіші можна було використовувати так само легко. Насправді для читабельності я б порадив це.

Вставте це у зовнішній файл для зручності

function unknown_number_arguments($argument_set) {

    foreach ($argument_set as $key => $value) {

        # create a switch with all the cases you need. as you loop the array 
        # keys only your submitted $keys values will be found with the switch. 
        switch ($key) {
            case 1:
                # do stuff with $value
                break;
            case 2:
                # do stuff with $value;
                break;
            case 3:
                # key 3 omitted, this wont execute 
                break;
            case 5:
                # do stuff with $value;
                break;
            case 8:
                # do stuff with $value;
                break;
            default:
                # no match from the array, do error logging?
                break;
        }
    }
return;
}

поставте це на початку, якщо файл.

$argument_set = array(); 

Просто використовуйте їх, щоб призначити наступну частину використання нумерації / іменування даних відповідно до того, звідки беруться дані.

$argument_set[1][] = $some_variable; 

І нарешті передайте масив

unknown_number_arguments($argument_set);

1
function yourFunction($var1, $var2, $optional = Null){
   ... code
}

Ви можете зробити звичайну функцію, а потім додати необов’язкові змінні, надавши їм значення за замовчуванням Null.

Null - це все-таки значення, якщо ви не викликаєте функцію зі значенням для цієї змінної, вона не буде порожньою, тому помилки не буде.


2
Чи можете ви пояснити все це далі? Наведений код синтаксично недійсний, оскільки імена змінних не можуть починатися з числа
Ніко Хааз,

0

Якщо ви зазвичай просто передаєте восьме значення, ви можете змінити порядок своїх параметрів, щоб він був першим. Вам потрібно лише вказати параметри до останнього, який потрібно встановити.

Якщо ви використовуєте різні значення, у вас є 2 варіанти.

Можна було б створити набір функцій обгортки, які приймають різні параметри, а інші встановлюють параметри за замовчуванням. Це корисно, якщо ви використовуєте лише кілька комбінацій, але ви можете швидко забруднитись.

Інший варіант - передати масив, де ключі є іменами параметрів. Потім ви можете просто перевірити, чи є значення в масиві за допомогою ключа, а якщо не використовувати за замовчуванням. Але знову ж таки, це може стати безладним і додати багато зайвого коду, якщо у вас багато параметрів.


0

PHP дозволяє аргументи за замовчуванням ( посилання ). У вашому випадку ви можете визначити всі параметри від 3 до 8 як NULL або як порожній рядок "" залежно від коду вашої функції. Таким чином ви можете викликати функцію лише за допомогою перших двох параметрів.

Наприклад:

<?php
  function yourFunction($arg1, $arg2, $arg3=NULL, $arg4=NULL, $arg5=NULL, $arg6=NULL, $arg7=NULL, $arg8=NULL){
echo $arg1;
echo $arg2;
if(isset($arg3)){echo $arg3;}
# other similar statements for $arg4, ...., $arg5
if(isset($arg8)){echo $arg8;}
}

Цікава ідея ... проте ваша пропозиція не вирішує проблему. Насправді, якщо ви додасте інформацію про аргумент, який повторюється (наприклад, за допомогою echo " this is arg3: " . $arg3;тощо), ви побачите, що виклик, наприклад, yourFunction(3, 2, $arg8=5);буде надруковано 32 this is arg3: 5. Проблема полягає в тому, що положення параметра все ще має значення при передачі необов'язкових параметрів у назвах параметрів PHP ... недостатньо для відображення значень параметрів у назвах параметрів
mastropi

0

Просто встановіть Null ігнорувати параметри, які ви не хочете використовувати, а потім встановіть необхідний параметр відповідно до позиції.

 function myFunc($p1,$p2,$p3=Null,$p4=Null,$p5=Null,$p6=Null,$p7=Null,$p8=Null){
    for ($i=1; $i<9; $i++){
        $varName = "p$i";
        if (isset($$varName)){
            echo $varName." = ".$$varName."<br>\n";
        }
    }
}   

myFunc( "1", "2", Null, Null, Null, Null, Null, "eight" );

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.