Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: problem z parametrami public static
Forum PHP.pl > Forum > PHP > Object-oriented programming
zephyr7
Próbuję napisać coś na wzór frameworka,
mam funkcję, która wywołuje:

$uri[0]::$uri[1](); //np. pages::view();

jak przekazywać dodatkowe parametry?

Jeśli mój url wygląda tak: pages/view/1/2

funkcja powinna wywołać:

$uri[0]::$uri[1]($uri[2],$uri[3]);

jak poradzić sobie ze zmienną liczbą parametrów?


Do głowy przychodzi mi tylko coś takiego:


$params="";
for ($q=2;$q<count($uri)-1;$q++){
$params.='$uri['.$q.'],';
}
//usuwa przecinek.... no comment....
$params=strip_tags(substr($params,0,-1));
eval ('$uri[0]::$uri[1]('.$params.');');


będę wdzięczny za bezlitosną krytykę i pomysły, jak można napisać to po ludzku....
thek
Podziel string po stosowanym rozdzielaczu w adresie, czyli / a co do zmiennej liczby parametrów funkcji, to jak widzę nie uważałeś podczas czytania manuala winksmiley.jpg Lepiej obadaj func_get_args
Dzięki temu możesz ręcznie odbierać tyle parametrów w funkcji ile chcesz. Taki nieco kulawy rodzaj przeciążania funkcji w PHP mających tę samą nazwę, ale inną liczbę parametrów.
zephyr7
Faktycznie! Baran ze mnie!

Przecież gdzieś to widziałem, w którymś z tutoriali!

(już biorę się za czytanie)
Crozin
Skorzystaj z ReflectionMethod. Swoją drogą nie powinieneś najprawdopodobniej korzystać tutaj z metod statycznych.
zephyr7
No, zagwozdka normalnie...

chciałbym tylko wywołać metodę z tyloma parametrami, ile mam w URI...

func_get_args z tego co wiem, zwraca już istniejące argumenty.

Kiedy mam w URL 2 parametry (pomijając uri[0] i [1], czyli kontroller i metodę)

chciałbym wywołać funkcję podając dwa parametry, np. $uri[0]::$uri[1]($uri[2],$uri[3]), co daje, np. page::view(2,3)

wtedy w kontrolerze mógłbym odwołać się prosto, np. function index($id,$page)...

chodzi tylko o tą przeklętą zmieniającą się liczbę argumentów
$uri[0]::$uri[1]($uri[2],$uri[3])

jeśli będę miał 1 parametr, np. pages/view/2
a funckja wywołana będzie jak wyżej, powstanie błąd "undefined index"

Mógłbym ewentualnie (co chyba jest jeszcze gorszym pomysłem)

podawać ciąg parametrów i zerować te, których nie ma w URL, np. pages/view/2

for($q=2;$q<count($uri)-1;$q++){
if (!isset($uri[$q]))$uri[$q]=0;
}

$uri[0]::$uri[1]($uri[2],$uri[3]....$uri[20])

kretyńskie, prawda?

a swoją drogą, proste i bez kombinowania.

Przecież nikt nie potrzebuje więcej, niż np. 5-10 parametrów w url
thek
Pokombinuj z func_num_args i switch. Skoro jakaś metoda obsługuje ściśle określoną liczbę parametrów maksymalnie, to brakujące musisz ustawić na elementy "neutralne" (czyli albo false, albo 0 ) by wychwycić ich brak. Jak?
Przypuśćmy możesz w funkcji maksymalnie obsłużyć 5 parametrów. Jeśli będzie ich mniejsza ilość - uzupełniasz je poprzez false, jeśli równa - ok, jeśli większa - ignorujesz te powyżej. Jak by to mogło wyglądać?
  1. function test() {
  2. $args = func_get_args();
  3. switch( func_num_args() ) {
  4. case 0:
  5. $args[0] = false;
  6. case 1:
  7. $args[1] = false;
  8. case 2:
  9. $args[2] = false;
  10. case 3:
  11. $args[3] = false;
  12. case 4:
  13. $args[4] = false;
  14. case 5:
  15. break;
  16. default:
  17. $args = array_slice($args, 0, 5);
  18. }
  19. //tu robisz co chcesz już na tablicy $args
  20. }
Switch jest tu najważniejszy, ponieważ on modyfikuje tak listę parametrów, by uzupełnić brakujące parametry poprzez false. Zwróć uwagę na brak break aż do case 5. To ważne, ponieważ dla 5 parametrów jedynie nastąpi wyjście ze switcha. A co jeśli jest parametrów mniej, jak choćby 3? Ano tabela $args uzupełni $args[3] (4 parametr) na false i przejdzie do case 4 (dlatego brak break!) i uzupełni $args[4](5 parametr) na false oraz przejdzie do case 5 i dopiero tu wyskoczy ze switcha winksmiley.jpg Defaultem jedynie potraktowałem jeśli masz więcej parametrów, bo wtedy nastąpi obcięcie ich do wymaganych 5 smile.gif Zrobiłem coś więc o charakterze "normalizatora" liczby parametrów.

PS: Oczywiście uzycie switch ma sens jedynie dla małej liczby akceptowanych parametrów. Przy dużej można użyć do tego celu jak powyżej -> pętli.
Crozin
A patrzyłeś w ogóle na mój post? To podpowiem: metoda invokeArgs()
thek
Crozin... na nic fleksja się nie zda, skoro błąd będzie na poziomie samej funkcji wywołanej w refleksji. Skoro będzie ona przyjmowała kilka parametrów, a nie dostanie nawet jednego to co będzie? Nie widziałem by refleksja to obsługiwała poprzez uzupełnienie nie istniejących jakoś winksmiley.jpg Ona też dostaje określoną listę parametrów i musi ona być kompletna. Jedyne co możesz zrobić to za jej pomocą pobrać liczbę argumentów funkcji i uzupełnić brakujące false'ami. Moim zdaniem dobre jest to do jakiegoś systemu kontroli, wbicie w helper czy cuś, ale na szybko można to prosto rozwiązać poprzez wariację na switch czy w pętli na zasadzie:
  1. $args = func_get_args();
  2. if( func_num_args() < 5 ) {
  3. for($i=func_num_args(); $i < 5; $i++) {
  4. $args[$i] = false;
  5. }
  6. } else if( func_num_args() > 5 ) {
  7. $args = array_slice($args, 0, 5);
  8. }


Można też zamiast for użyć choćby
  1. $args = array_merge( $args, array_fill( func_num_args(), 5-func_num_args(), false ));
Cudować można na wiele sposobów winksmiley.jpg

PS: Zapomniałem dodać, że 5 to oczywiście wartość jakaś dowolna, która określa liczbę parametrów funkcji.
Crozin
Cytat
Skoro będzie ona przyjmowała kilka parametrów, a nie dostanie nawet jednego to co będzie?
To błąd będzie. A jeżeli jakiś argument ma być opcjonalny, to... niech będzie opcjonalny:
  1. public function doSth($a = null)


Swoją drogą, jeżeli już ma być coś uzupełniane wartościami domyślnymi (sic!) to powinny to być NULLe, nie FALSE.
Athlan
Ja tylko się zastanawiam, dlaczego nie użyjecie do przekazania tych parametrów jednej tablicy. Rozwiązanie jest o tyle elastyczne, że można w przyszłości oddzielić argument przekazujący parametry url'a od dodatkowych argumentów (np. flag, etc). Poza tym to nieco szybszy sposób, łatwo się na tym operuje, dane masz takie same, jak w przypadku func_get_args().
rodia

  1. function hello()
  2. {
  3. $num = func_num_args();
  4. $args = func_get_args();
  5.  
  6. foreach ($args as $arg)
  7. echo $arg.'<br>';
  8. }


Powyższe rozwiązanie odbiera zmienną ilość argumentów, jednak problemem jest wywołanie tej funkcji z różną ilością argumentów - bo ciężko jest to już zrobić z automatu.

Czy nie lepiej mając URL w postaci jak autor pisał:
  1.  
  2. $url = 'a/b/c/d';


zamienić to na tablicę i wywolać funkcję przetwarzającą URL?
  1. executeURL(explode('/', $url));


a funkcja ta przyjmowałaby zawsze tylko jeden argument, którym byłaby tablica o dowolnej ilości parametrów z URLa
  1.  
  2. function executeURL($args)
  3. {
  4. foreach ($args as $arg)
  5. echo $arg.'<br>';
  6. }
  7.  


Pozdrawiam, R.
thek
Podejść na rozwiązane tego problemu jest masę. Najwygodniejsza jest tablica. Potem kombinowanie z func_get_args. Co do NULL bądź innych wartości to zależne to od tego co funkcja robić ma. Ja chciałem tylko zwrócić Ci Crozin uwagę, że wbijanie tam refleksji pasuje jak pięść do oka winksmiley.jpg Nie po to ten mechanizm wymyślono by kontrolował liczbę parametrów funkcji czy tego typu "manewry". Są prostsze rozwiązania tego problemu. Do problemu zmiennej liczby parametrów tak naprawdę tylko 2 sposoby są sensowym rozwiązaniami: func_***_arg(s) i tablice/obiekty. Przy czym to drugie jest elastyczniejsze, gdyż możemy jeszcze się bawić.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.