Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Obsługa wielu parametrów metod w PHP - użyteczna klasa Params, Bardzo prosta ale użyteczna klasa ułatwiająca życie programisty PHP.
implico
post
Post #1





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 16.11.2012
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Witajcie ponownie!

Tym razem, w ramach rozbudowy firmowego bloga, chcielibyśmy podzielić się bardzo prostą, ale równie użyteczną klasą pozwalającą na wygodną obsługę parametrów funkcji, które zanadto się "rozrosły".

Przykładowo, przypuśćmy że mamy taką oto funkcję/metodę:

  1. function load(address, async, useCache = false, debug = false, user = NULL, timeout = 0)
  2. {
  3. ...
  4. }


Aby ją wywołać, zamierzając zmienić np. tylko jeden domyślny parametr timeout, musimy przebrnąć przez wszystkie parametry:
  1. load('http://www.implico.pl/', true, false, false, NULL, 100);


Prosiłoby się użycie rozwiązania znanego z JavaScript, gdzie wystarczy przekazać jako jedyny parametr odpowiedni obiekt.

Z pomocą przychodzi nasz klasa Params. Dzięki niej wywołanie ma postać:
  1. load(new Params( array('address' => 'http://www.implico.pl/', 'async' => true, 'timeout' => 100) ));


Więcej o klasie i jej użyciu tutaj:
http://www.implico.pl/klasa_params_wygodna...od_w_php,8.html


P.S. Jeśli istnieje już podobne, być może lepsze rozwiązanie - dajcie znać.
Go to the top of the page
+Quote Post
2 Stron V   1 2 >  
Start new topic
Odpowiedzi (1 - 19)
hind
post
Post #2





Grupa: Zarejestrowani
Postów: 142
Pomógł: 24
Dołączył: 30.03.2009
Skąd: Rokitno Szlacheckie

Ostrzeżenie: (0%)
-----


w czym te rozwiązanie jest lepsze od ValueObject lub po prostu tablicy ?
Go to the top of the page
+Quote Post
implico
post
Post #3





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 16.11.2012
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Sądzę że zgrabniej i szybciej jest zapisać konstruktor klasy niż tworzyć nowy obiekt. Poza tym automatycznie obsługiwane są wymagane parametry i wartości domyślne, nie trzeba powielać kodu w każdej metodzie - patrz pełny opis na naszej stronie.

Ten post edytował implico 6.02.2013, 10:06:02
Go to the top of the page
+Quote Post
!*!
post
Post #4





Grupa: Zarejestrowani
Postów: 4 298
Pomógł: 447
Dołączył: 16.11.2006

Ostrzeżenie: (0%)
-----


Takie coś też zapewni automatyczną zmianę parametrów
  1. load(array('async' => true, 'timeout' => 100));


I nie potrzeba dodatkowej klasy. Kwestia przyzwyczajeń do budowy i zarządzania nimi wink.gif


--------------------
Nie udzielam pomocy poprzez PW i nie mam GG.
Niektóre języki programowania, na przykład C# są znane z niezwykłej przenośności (kompatybilność ze wszystkimi wersjami Visty jest wiele warta).
Go to the top of the page
+Quote Post
nospor
post
Post #5





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Ale co tu oceniać? Dwie metody na krzyz: set i get... pierwszy lepszy średnio nierozgarniety programista coś takiego stworzy.
Jak już napisano: tablica wystarczy. Zaś ta klasa jedynie ułatwia przypisywanie domyślnych wartosci.

Kontr klasa, zdecydowanie krótsza i moim zdaniem zdecydowanie bardziej wygodniejsza w użyciu
  1. class Params {
  2.  
  3. public static function Get($array, $name, $default = null){
  4. if (array_key_exists($name, $array))
  5. return $array[$name];
  6. return $default;
  7. }
  8. }


Korzystanie:
  1. function test($params){
  2. echo Params::Get($params, 'raz');
  3. echo Params::Get($params, 'dwa');
  4. echo Params::Get($params, 'trzy','wartosc domyslna dla trzy');
  5. }
  6.  
  7. test(array('raz' => 'razzzzz', 'dwa'=> 'dwaaaaa'));
  8.  



--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
pyro
post
Post #6





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Moim zdaniem cudowanie na siłę. Poczytajcie o zasadzie KISS i stosujcie się do niej. Taka klasa mogła by mieć sens dla funkcji, w której jest 30 parametrów, ale czy widzieliście kiedyś taką funkcję?

@nospor, twoja klasa sprawia, że wymaganie parametry tak naprawdę nie są wymagane, więc pozwolę sobie nanieść drobną modyfikację

  1. class Params {
  2.  
  3. public static function Get($array, $name, $default = null){
  4. if (array_key_exists($name, $array))
  5. return $array[$name];
  6.  
  7. if(!is_null($default))
  8. return $default;
  9.  
  10. trigger_error('Required parameter not set for: '.$name, E_USER_ERROR);
  11. }
  12. }


Niestety tab mi nie działa w forumowym textarea closedeyes.gif


--------------------
ET LINGUA EIUS LOQUETUR IUDICIUM
Go to the top of the page
+Quote Post
nospor
post
Post #7





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




@pyro bo ja nie zakładałem, że coś jest wymagane. Jak chcesz takiego założenia, to musisz dodać czwarty parametry $required=false, bo tak Twoja poprawka teraz to wymusza na użytkowniku zawsze wymagalnośc parametru, a wcale tak być nie musi wink.gif


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
pyro
post
Post #8





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Cytat(nospor @ 6.02.2013, 12:55:52 ) *
@pyro bo ja nie zakładałem, że coś jest wymagane. Jak chcesz takiego założenia, to musisz dodać czwarty parametry $required=false, bo tak Twoja poprawka teraz to wymusza na użytkowniku zawsze wymagalnośc parametru, a wcale tak być nie musi wink.gif


@nosporku, sama konstrukcja i pojęcie "funkcji" w programowaniu z założenia może mieć obowiązkowe lub opcjonalne parametry, więc wypadałoby to uwzględnić.

Poza tym co wymusza? Nic nie wymusza

  1. function some_func($params)
  2. {
  3. Params::Get($params, 'name1'); // wymagany parametr
  4. Params::Get($params, 'name2', 'default value'); // opcjonalny parametr, w $params nie ustalono tej wartości, więc zostaje przypisana domyślna wartość
  5. // problem może być dla funkcji w której wartość domyślna ma być NULL, ale na to też jest rozwiązanie.
  6. }


Poza tym jak już wspomniałem - według mnie w ogóle tworzenie takiej klasy to bezsens. No chyba, że używana jest funkcja z 30 parametrami, ale czy natknęliście się kiedyś na taką funkcję?

Poza tym idąc dalej tokiem myślenia, klasę tą można przerobić tak, że nie trzeba podawać w metodzie Params::Get argumentu $params

Ten post edytował pyro 6.02.2013, 13:09:18


--------------------
ET LINGUA EIUS LOQUETUR IUDICIUM
Go to the top of the page
+Quote Post
implico
post
Post #9





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 16.11.2012
Skąd: Kraków

Ostrzeżenie: (0%)
-----


@*!*: takie coś wcale nie zapewni żadnej automatycznej zamiany parametrów. Myślę że to aż nazbyt oczywiste, ale co w przypadku, jeśli chciałbyś zmienić jeden parametr? Znowu trzeba przepisywać pozostałe.

@nospor: "Ale co tu oceniać? Dwie metody na krzyz: set i get... pierwszy lepszy średnio nierozgarniety programista coś takiego stworzy."
A jednak nikt z Was nie stworzył rozwiązania ekwiwalentnego, z obsługą parametrów wymaganych i sensowną obsługą wartości domyślnych. Zaproponowane przez Ciebie rozwiązanie w ogole nie obsługuje parametrow wymaganych i takie sprawdzenie, nawet po odpowiednich przeróbkach, nie jest możliwe bez odwołania się do zmiennej (trzeba zawsze sprawdzić jej wartość, inaczej klasa nie wykryje braku zmiennej wymaganej). Dodatkowo chcąc odwołać się dwukrotnie do zmiennej o wartosci domyślnej, należałoby ją przedtem przypisać do jakiejś zmiennej, aby nie dublować kodu. Poza tym łatwiej odwołać się do np. $par->get('raz'), niż do Params::Get($params, 'raz').

@pyro: zapewniam Cię, że funkcja jest przydatna również nawet w przypadku 5 parametrów. Ciekawe, @nospor twierdzi że to parę metod na krzyż, z kolei Ty każesz stosować KISS (Keep It Simple, Stupid) - taki paradoks. Mimo wszystko sądzę, że rozwiązanie jest proste zarówno w obsłudze, jak w implementacji.
Niestety Twoje rozwiązanie nie zapewnia obsługi parametrów wymaganych, a jedynie wymaga wprowadzenia parametru domyślnego. Raczej miałeś na myśli dodanie parametru, np. isRequired i sprawdzanie tego warunku w 7. linijce. Ale to również ma wadę - jak wspomniałem "takie sprawdzenie, nawet po odpowiednich przeróbkach, nie jest możliwe bez odwołania się do zmiennej (trzeba zawsze sprawdzić jej wartość)".

Ogólnie chodziło o stworzenie EKWIWALENTU (czyli PEŁNEJ funkcjonalności) zapewniającej obsługę parametrów z uwzględnieniem wymagalności i wartości domyślnych, a nie proponowanych przez Was półśrodków. Proszę Was jeszcze o przemyślenie kwestii.
Go to the top of the page
+Quote Post
nospor
post
Post #10





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
@nosporku, sama konstrukcja i pojęcie "funkcji" w programowaniu z założenia może mieć obowiązkowe lub opcjonalne parametry, więc wypadałoby to uwzględnić.
Tak, tylko że ja nie widzę sensu tego uwzględniania smile.gif
Ale jak już chcesz uwględniać rób to dobrze. Nie możesz uwazac, ze dajac null w default to oznacza ze jest to parametr wymagany. A co jesli nie jest to parametr wymagany? jak bedzie to ok, jak nie bedzie to ok? Jak mam to zapisać? Dajac 0 zamiast null? No ale 0 moze byc wartoscią a nie oznaczeniem, ze parametr nie jest wymagany. Dlatego wlasnie pisze, ze trzeba dopisac jeszcze $required smile.gif

Cytat
Zaproponowane przez Ciebie rozwiązanie w ogole nie obsługuje parametrow wymaganych
Jak juz pisalem: wystarczy dopisac parametr $required. Ja tego nie zrobilem, bo uwazam to za totalnie zbędne.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
pyro
post
Post #11





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Cytat(nospor @ 6.02.2013, 13:12:34 ) *
Tak, tylko że ja nie widzę sensu tego uwzględniania smile.gif
Ale jak już chcesz uwględniać rób to dobrze. Nie możesz uwazac, ze dajac null w default to oznacza ze jest to parametr wymagany. A co jesli nie jest to parametr wymagany? jak bedzie to ok, jak nie bedzie to ok? Jak mam to zapisać? Dajac 0 zamiast null? No ale 0 moze byc wartoscią a nie oznaczeniem, ze parametr nie jest wymagany. Dlatego wlasnie pisze, ze trzeba dopisac jeszcze $required smile.gif


Tak, ale to już zresztą zaznaczyłem:

Cytat(pyro)
// problem może być dla funkcji w której wartość domyślna ma być NULL, ale na to też jest rozwiązanie.


Można przypisać $default jakąś konfiguracyjną daną i potem po niej sprawdzać albo jak już wspomniałeś, dodać parametr $isRequired.


--------------------
ET LINGUA EIUS LOQUETUR IUDICIUM
Go to the top of the page
+Quote Post
implico
post
Post #12





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 16.11.2012
Skąd: Kraków

Ostrzeżenie: (0%)
-----


@pyro: Niestety, chyba nie do końca rozumiesz ideę klasy nospora.

"Params::Get($params, 'name1'); // wymagany parametr"

Zawsze zwróci błąd.
Go to the top of the page
+Quote Post
pyro
post
Post #13





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Może gdzieś popełniłem błąd, bo nie jestem u siebie i nie mam gdzie tego sprawdzić, ale według mnie:

  1. funtion some_func($params)
  2. {
  3. Params::Get($params, 'name1'); // Wartość wymgana
  4. Params::Get($params, 'name2', 'default value'); // Wartośc opcjonalna
  5. }
  6.  
  7. some_func(array('name1'=>'some value')); // Nie podano name2


Nie zwróci błędu.

Cytat(implico @ 6.02.2013, 13:10:24 ) *
@pyro: zapewniam Cię, że funkcja jest przydatna również nawet w przypadku 5 parametrów. Ciekawe, @nospor twierdzi że to parę metod na krzyż, z kolei Ty każesz stosować KISS (Keep It Simple, Stupid)


Zasada KISS dotyczy nie tylko uproszczania niezbędnego kodu, ale także pozbycia się nadmiernego, zbędnego kodu.



Cytat(implico @ 6.02.2013, 13:10:24 ) *
Niestety Twoje rozwiązanie nie zapewnia obsługi parametrów wymaganych, a jedynie wymaga wprowadzenia parametru domyślnego.


Nie wymaga, bo dla parametrów obowiązkowych zanim jest sprawdzane wartości domyślnej wywoływane jest return.


Cytat(implico @ 6.02.2013, 13:10:24 ) *
@pyro: zapewniam Cię, że funkcja jest przydatna również nawet w przypadku 5 parametrów. Ciekawe, @nospor twierdzi że to parę metod na krzyż, z kolei Ty każesz stosować KISS (Keep It Simple, Stupid) - taki paradoks. Mimo wszystko sądzę, że rozwiązanie jest proste zarówno w obsłudze, jak w implementacji.


Niestety nie wziąłeś pod uwagę np. dokumentacji, bo IDE zazwyczaj mają podpowiadanie parametrów dla user-made functions, a przy takim rozwiązaniu dla stworzonej funkcji jedyne co może się pokazać to...

Cytat
array $params - a list of parameters for the function


W dużych projektach takie coś jest naprawdę problematyczne.


Ten post edytował pyro 6.02.2013, 13:25:03


--------------------
ET LINGUA EIUS LOQUETUR IUDICIUM
Go to the top of the page
+Quote Post
ano
post
Post #14





Grupa: Zarejestrowani
Postów: 435
Pomógł: 40
Dołączył: 16.02.2003
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Czemu nie po prostu:
  1. function f(array $params) {
  2. $default = array('a' => 1, ...); // słownik domyślnych wartości
  3. $params = array_merge($default, $params);
  4. }


Bardzo często stosowane gdy np musimy przechowywać wiele "opcji" w klasie.


--------------------
Linkedin | ...
Go to the top of the page
+Quote Post
viking
post
Post #15





Grupa: Zarejestrowani
Postów: 6 380
Pomógł: 1116
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Poza tym można też po prostu http://php.net/manual/en/function.func-get-args.php. A to tutaj przedstawione to przecież zwykły rejestr.


--------------------
Go to the top of the page
+Quote Post
mstraczkowski
post
Post #16





Grupa: Zarejestrowani
Postów: 273
Pomógł: 52
Dołączył: 3.02.2013
Skąd: Przemyśl

Ostrzeżenie: (0%)
-----


Moim zdaniem już samo pisanie tak wieloparametrowych funkcji/metod jest złą praktyką

A tworzenie "hooków", aby sobie to ułatwić to już całkiem herezje

Jeśli funkcja zaczyna posiadać sporą ilość parametrów to pierwszy sygnał, aby zadać sobie pytanie czy to nie jest odpowiedni moment, aby utworzyć klasę zamiast pisać kolejne i kolejne parametry .

Takie wieloparametrowe funkcje w większości (nie zawsze) są już tak rozbudowane, że spokojnie mogą stać się jakimś osobnym libem

A jeżeli już to zazwyczaj projektuje się funkcje/metody w taki sposób, aby móc łatwo zarządzać ich parametrami

Przykładowo dlaczego flagi true/false są parametrami przed integerem który na pewno będzie używany częściej niż wspomniane flagi, które z kolei w 90% mogą mieć wartość domyślną ?

Ten post edytował mstraczkowski 13.02.2013, 03:47:05


--------------------
Jeżeli moja wypowiedź Ci pomogła użyj przycisku
Go to the top of the page
+Quote Post
hind
post
Post #17





Grupa: Zarejestrowani
Postów: 142
Pomógł: 24
Dołączył: 30.03.2009
Skąd: Rokitno Szlacheckie

Ostrzeżenie: (0%)
-----


@mstraczkowski: mówisz o pisaniu klasy, ale co w przypadku gdy konstruktor przyjmuje pierdyliard parametrów? W tedy tylko tablica lub ValueObject
Go to the top of the page
+Quote Post
pyro
post
Post #18





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Cytat(hind @ 13.02.2013, 08:46:16 ) *
@mstraczkowski: mówisz o pisaniu klasy, ale co w przypadku gdy konstruktor przyjmuje pierdyliard parametrów? W tedy tylko tablica lub ValueObject


Jeżeli konstruktor przyjmuje pierdyliard parametrów, to w 99% przypadków jest to zły konstruktor.


--------------------
ET LINGUA EIUS LOQUETUR IUDICIUM
Go to the top of the page
+Quote Post
hind
post
Post #19





Grupa: Zarejestrowani
Postów: 142
Pomógł: 24
Dołączył: 30.03.2009
Skąd: Rokitno Szlacheckie

Ostrzeżenie: (0%)
-----


zawsze można potem użyć kilkunastu setterów, ale za sto konstruktor nie będzie musiał przyjmować parametrów.
Go to the top of the page
+Quote Post
mstraczkowski
post
Post #20





Grupa: Zarejestrowani
Postów: 273
Pomógł: 52
Dołączył: 3.02.2013
Skąd: Przemyśl

Ostrzeżenie: (0%)
-----


Konstruktor nie służy do ustawiania nie wiadomo jakiej konfiguracji klasy.

Konstruktor powinien przyjmować tylko parametry, które są niezbędne do utworzenia obiektu danej klasy.
Całą resztę można rozwiązać za pomocą setterów, getterów, właściwości (jeżeli ustawiania mają być elastyczne) lub stałe klasy (jeżeli ustawienia klasy są sztywne)

Jeżeli istnieje coś co musi zostać podane zawsze przy tworzeniu obiektu (aby klasa mogła prawidłowo funkcjonować), to wtedy powinno to stać się parametrem konstruktora. Po to, aby w każdej innej metodzie nie sprawdzać czy ktoś za pomocą settera to ustawił i nie rzucać mu wyjątku.

Jeżeli twoja klasa staje się rozbudowana i ilość setterów / getterów cię przerasta można pomyśleć o osobnej klasie konfiguracyjnej dla danej klasy.
Tak jak przykładowo robi to HTML Purifier

Przykładowo:
  1. $oConfig = HTMLPurifier_Config::createDefault();
  2. $oConfig->set('HTML.TidyLevel', 'heavy');
  3.  
  4. $oPurifier = new HTMLPurifier($oConfig);
  5. $sHtml = $oPurifier->purify($sHtml);


Ten post edytował mstraczkowski 13.02.2013, 12:45:51


--------------------
Jeżeli moja wypowiedź Ci pomogła użyj przycisku
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 01:57