Czy moje funkcje PHP powinny akceptować tablicę argumentów, czy powinienem jawnie żądać argumentów?

W aplikacji internetowej PHP, nad którą pracuję, widzę funkcje zdefiniowane na dwa możliwe sposoby.

Podejście 1:

function myfunc($arg1, $arg2, $arg3)

Podejście 2:

// where $array_params has the structure array('arg1'=>$val1, 'arg2'=>$val2, 'arg3'=>$val3)
function myfunc($array_params)

Kiedy należy stosować jedno podejście nad drugim? Wydaje się, że jeśli wymagania systemowe ciągle się zmieniają, a zatem liczba argumentów dla myfunc wciąż się zmienia, podejście 1 może wymagać dużej konserwacji.

Author: John Parker, 2010-01-22

7 answers

Jeśli system zmienia się tak często, że użycie indeksowanej tablicy jest najlepszym rozwiązaniem, powiedziałbym, że jest to najmniejszy z twoich zmartwień. :-)

Ogólnie funkcje / metody nie powinny przyjmować zbyt wielu argumentów (5 plus lub minus 2 jest maksimum) i powiedziałbym, że należy trzymać się argumentów named (a najlepiej type). (Indeksowana tablica argumentów ma sens tylko wtedy, gdy istnieje duża ilość opcjonalnych danych - dobrym przykładem jest konfiguracja informacje.)

Jak mówi @ Pekka, przekazanie tablicy argumentów może być również bólem do udokumentowania, a zatem dla innych osób / siebie w ciągu " n " miesięcy do utrzymania.

Update-ette...

Nawiasem mówiąc, często wspominana książka Kod kompletny bardzo szczegółowo omawia takie zagadnienia - jest to świetny Tom, który Gorąco polecam.

 28
Author: John Parker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-26 21:03:01

Używanie tablicy params (zastępczej dla tego, co w innych językach nazywa się "nazwanymi argumentami") jest świetne-lubię go używać sam - ale ma dość duży minus: argumenty nie są dokumentowalne przy użyciu standardowej notacji phpDoc w ten sposób, a zatem Twoje IDE nie będzie w stanie dać Ci wskazówek, Gdy wpiszesz nazwę funkcji lub metody.

 17
Author: Pekka 웃,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 21:10:50

Uważam, że użycie opcjonalnej tablicy argumentów jest przydatne, gdy chcę nadpisać zestaw domyślnych wartości w funkcji. Może to być przydatne przy konstruowaniu obiektu, który ma wiele różnych opcji konfiguracyjnych lub jest po prostu głupim kontenerem informacji. To jest coś, co odebrałem głównie ze świata Ruby.

Przykładem może być konfiguracja kontenera dla filmu na mojej stronie internetowej:

function buildVideoPlayer($file, $options = array())
{
  $defaults = array(
    'showAds' => true,
    'allowFullScreen' = true,
    'showPlaybar' = true
  );

 $config = array_merge($defaults, $options);

 if ($config['showAds']) { .. }
}

$this->buildVideoPlayer($url, array('showAds' => false));

Zauważ, że początkowa wartość $options jest pusta array, więc podanie jej w ogóle jest opcjonalne.

Ponadto, dzięki tej metodzie wiemy, że $options zawsze będzie tablicą i wiemy, że te klucze mają domyślne wartości, więc nie musimy stale sprawdzać is_array() lub isset() podczas odwoływania się do argumentu.

 12
Author: Bryan M.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-22 01:18:17

Przy pierwszym podejściu zmuszasz użytkowników swojej funkcji do podania wszystkich potrzebnych parametrów. drugi sposób nie możesz być pewien, że masz wszystko, czego potrzebujesz. Wolałbym pierwsze podejście.

 4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 21:14:26

Istnieją plusy i minusy każdej ze stron.

  • Jeśli jest to prosta funkcja, która jest mało prawdopodobne, aby zmienić, i ma tylko kilka argumentów, to chciałbym je wyraźnie określić.

  • Jeśli funkcja ma dużą liczbę argumentów lub może się wiele zmienić w przyszłości, wtedy przekazałbym tablicę argumentów z kluczami i użyłbym jej. To również staje się pomocne, jeśli masz funkcję, gdzie trzeba tylko przekazać niektóre z argumentów często.

An przykład, kiedy wybrałbym tablicę zamiast argumentów, dla przykładu, byłoby gdybym miał funkcję, która utworzyła pole formularza. możliwe argumenty, które mogę chcieć:

  • Typ
  • wartość
  • klasa
  • ID
  • style
  • opcje
  • is_required

I może będę potrzebował tylko kilku z nich. na przykład, jeśli pole to type = text, nie potrzebuję opcji. Nie zawsze mogę potrzebować klasy lub wartości domyślnej. W ten sposób łatwiej jest przejść w kilka kombinacji argumentów, bez podpisu funkcji z argumentami ton i przechodzenia przez null cały czas. Również, gdy HTML 5 staje się standardem wiele wiele lat od teraz, mogę chcieć dodać dodatkowe możliwe argumenty, takie jak włączanie lub wyłączanie Auto-complete.

 3
Author: GSto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 21:19:55

Jeśli parametry, które podajesz mogą być logicznie pogrupowane, możesz pomyśleć o użyciu obiektu parametru (refaktoring , Martin Fowler, p295), w ten sposób, jeśli chcesz dodać więcej parametrów, możesz po prostu dodać więcej pól do swojej klasy parametrów, a to nie zepsuje istniejących metod.

 3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 22:21:06

Wiem, że to stary post, ale chcę podzielić się moim podejściem. Jeśli zmienne są logicznie połączone w typie, można je pogrupować w klasę i przekazać obiekt z nich do funkcji. na przykład:

      class user{
           public $id;
           public $name;
           public $address;
           ...
      }

I wywołanie:

      $user = new user();
      $user->id = ...
      ...

      callFunctions($user);

Jeśli potrzebny jest nowy parametr, możesz po prostu dodać go do klasy i podpis funkcji nie musi się zmieniać.

 0
Author: Aris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-26 12:13:57