Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> problem z parametrami public static
zephyr7
post
Post #1





Grupa: Zarejestrowani
Postów: 71
Pomógł: 1
Dołączył: 3.11.2005

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


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....
Go to the top of the page
+Quote Post
thek
post
Post #2





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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 (IMG:style_emoticons/default/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.
Powód edycji: [thek]: @bottom: A ja Ci "synu" błogosławię żeś wybrał ścieżkę dobra. Idź i nie grzesz więcej :D
Go to the top of the page
+Quote Post
zephyr7
post
Post #3





Grupa: Zarejestrowani
Postów: 71
Pomógł: 1
Dołączył: 3.11.2005

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


Faktycznie! Baran ze mnie!

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

(już biorę się za czytanie)
Go to the top of the page
+Quote Post
Crozin
post
Post #4





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


Skorzystaj z ReflectionMethod. Swoją drogą nie powinieneś najprawdopodobniej korzystać tutaj z metod statycznych.
Go to the top of the page
+Quote Post
zephyr7
post
Post #5





Grupa: Zarejestrowani
Postów: 71
Pomógł: 1
Dołączył: 3.11.2005

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


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
Go to the top of the page
+Quote Post
thek
post
Post #6





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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 (IMG:style_emoticons/default/winksmiley.jpg) Defaultem jedynie potraktowałem jeśli masz więcej parametrów, bo wtedy nastąpi obcięcie ich do wymaganych 5 (IMG:style_emoticons/default/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.
Go to the top of the page
+Quote Post
Crozin
post
Post #7





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


A patrzyłeś w ogóle na mój post? To podpowiem: metoda invokeArgs()
Go to the top of the page
+Quote Post
thek
post
Post #8





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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ś (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/winksmiley.jpg)

PS: Zapomniałem dodać, że 5 to oczywiście wartość jakaś dowolna, która określa liczbę parametrów funkcji.
Go to the top of the page
+Quote Post
Crozin
post
Post #9





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


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.
Go to the top of the page
+Quote Post
Athlan
post
Post #10





Grupa: Developerzy
Postów: 823
Pomógł: 12
Dołączył: 18.12.2005

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


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().
Go to the top of the page
+Quote Post
rodia
post
Post #11





Grupa: Zarejestrowani
Postów: 21
Pomógł: 5
Dołączył: 29.07.2008

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



  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.


Ten post edytował rodia 27.12.2010, 16:11:16
Go to the top of the page
+Quote Post
thek
post
Post #12





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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 (IMG:style_emoticons/default/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ć.
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 20.12.2025 - 14:13