Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Źródło parametrów żądania
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
Cysiaczek
Ciężko zdefiniować ten problem, bo jest dość zakręcony. Postaram się przedstawić w miarę jasno o co chodzi. Zacznę od listingu.

Plik obcięty ze zbędnych tagów. Przedstawia definicję akcji i ich podstawowe relacje.
actions.xml
  1. <index>
  2.      <subactions>
  3.            <showCategory />
  4.            <showNews />
  5.      </subactions>
  6. </index>
  7.            
  8. <showNews></showNews>
  9. <showCategory></showCategory>

Załóżmy, że wywołujemy żądanie o postaci index.php?action=index
Parser czytając ten plik XML odczyta subakcję i stworzy ciąg akcji do uruchomienia w postaci

showCategory
showNews
index

W przedstawionej kolejności zostaną te akcje wykonane. (np metodą execute())

Gdzie problem? Ano. np, index.php?action=index&id=3
Intencją programisty jest, że $id odnosi się do akcji showCategory, która na jej podstawie wybiera kategorię z bazy danych.
Niech teraz akcja showNews również wymaga przekazania jakichś argumentów, np. $category oraz $id. Nie może po prostu odczytać $id, bo ten jest pobierany przez inną akcję i może nie zawierać tego, co chcemy, a nawet na pewno nie zawiera.

Ktoś może powiedzieć, że w takim razie najlepiej stworzyć łańcuch
index.php?action=index?categoryId=7&newsId=5
Od razu odpowiem, że takie rozwiązanie jest kalekie, i w ogóle nie wchodzi w grę, bo związuje akcję z konkretną nazwą klucza, którą potem trzeba wszędzie powtarzać.

Ktoś inny może podsunąć pomysł ustawiania parametrów żądania przez poprzednią akcję. Owszem. Wiele frameworków robi to i czasami również zaleca uruchomienie, bądź wręcz uruchamia kolejna akcję. Można wówczas taki bajer zrobić
W ciele akcji showCatagory
  1. <?php
  2. setNextActionParams("1", "kolejny", "etc"); // albo jakoś inaczej, to nieistotne
  3. ?>


Co jednak, jeśli te akcje mogą zostać uruchomione w różnych kontekstach?
np. Stwórzmy nową akcję.
  1. <showMostPopularCategory>
  2.      <subactions>
  3.            <showCategory />
  4.      </subactions>
  5. </showMostPopularCategory>


Jak widać, uruchomienie index?action=showMostPopularCategory również wykona akcję showCategory. Niniejszym jakakolwiek ingerencja w parametry akcji showNews nie ma sensu, bo tej akcji nie ma w łańcuchu.
Podobnie rzecz się będzie miała z innymi akcjami, a dochodzą jeszcze nieograniczone wręcz możliwości kombinowania układów akcji.

Rodzi się konkretne pytanie - w jaki sposób przekazać w takim układzie parametry żądania? Akcja nie ma pojęcia, w jakim kontekście jest uruchamiana, wiec musi liczyć na to, coś ustawi to za nią, albo sama musi znaleźć te parametry... : \

Jeśli ktoś spotkał się z podobnym problemem, to będę wdzięczny za podzielenie się przemyśleniami oraz posiadanymi linkami do artów itp.

Dzięki wszystkim, którzy w ogóle dobrnęli do końca tego posta

Pozdrawiam.
Turgon
Zastosuj wersje skrócone np. cid,nid. Tak ja robiłem. Wracając do tego wybierając showMostPopularCategory, to dodaje do tagu parametr określający, że chcesz to pobrać. Możesz też się pobawić w inteligentne rozpoznawanie źródła wywołania. Choć ciekawym pomysłem byłoby samo uczenie się systemu ;] Jednak to za dużo zabawy.
Wracając do pierwszego wymagaj by akcja wiedziała, która z nich może skorzystać z tych danych.
arecki
Cytat(Cysiaczek @ 19.01.2007, 19:44:45 ) *
Gdzie problem? Ano. np, index.php?action=index&id=3
Intencją programisty jest, że $id odnosi się do akcji showCategory, która na jej podstawie wybiera kategorię z bazy danych.
Niech teraz akcja showNews również wymaga przekazania jakichś argumentów, np. $category oraz $id. Nie może po prostu odczytać $id, bo ten jest pobierany przez inną akcję i może nie zawierać tego, co chcemy, a nawet na pewno nie zawiera.

(...ciach...)

  1. <showMostPopularCategory>
  2.      <subactions>
  3.            <showCategory paramname="id"/>
  4.      </subactions>
  5. </showMostPopularCategory>


(...ciach...)

Rodzi się konkretne pytanie - w jaki sposób przekazać w takim układzie parametry żądania? Akcja nie ma pojęcia, w jakim kontekście jest uruchamiana, wiec musi liczyć na to, coś ustawi to za nią, albo sama musi znaleźć te parametry... : \


W sumie to ustawienie gdzie ma być odczytywany parametr id to spokojnie możesz zrobić w pliku XML'owym. Tam możesz sobie zdefiniować nazwę parametry i do której akcji się tyczy. A wartość to już chyba bez problemu da się odczytać.
Cysiaczek
Trochę pomyślałem przez noc. Pogadałem z Athlanem na IRC i coś w końcu się urodziło, choć dalej nie jestem zadowolony :/
Skoro akcja nie wie, skąd będą przychodziły do niej dane, to wymaga jedynie mechanizmu ich pozyskania (abstrakcyjnego)
Posłuży temu metoda getParam("paramName"); Pierwotnie dane te miały być pobierane z rejestru żądania, który zawiera różniez inne użyteczne dane.
Źródło danych jak mówi arecki faktyczne najlepiej zdefiniować w pliku XML.
  1. <showCategory params="request:param1=id, param2=page; showNews: param3=jakas_zmienna" />

Nie wnikajcie w nazwy akcji, ani to, co robią, bo to tylko przykład

Pominę szczegóły implementacyjne.
Funkcja... nazwijmy ją paramSourceRetriver() powinna odczytać, że argumenty o nazwach param1 oraz param2 znajdują się w rejestrze żądania, natomiast param3 winna zostać pobrana z danych wyjściowych akcji showNews.
Te dane wyjściowe to cokolwiek, co mamy jako wynik przetwarzania akcji, który może też pobrać np. widok.
Wydaje mi się, że dzięki temu jestem w stanie wytworzyć wiele rożnych kontekstów użycia akcji.

Dalej pozostaje problem przysłowiowej już $id z URL'a, bo trzeba będzie wprowadzić dla tego konkretnego żądania parametry $catId oraz $newsId, choć nie związujemy już akcji z konkretnym łańcuchem polecenia, co jest postępem.

Co o tym myślicie? Może jednak bredzę... : /

Pozdrawiam
nasty
Cześć!

Problem ten jest trochę egzotyczny tongue.gif . Ale nasuną mi się pomysł który jest używany przez .NET, może trochę w inny sposób ale tez może zaradzić temu konkretnemu przypadkowi. Mówię tu o delegate, jest to w .NET używane jako sygnatura metod.

W Twoim problemie możesz zrobić następująco:
Dla każdej z akcji zdefiniować sygnaturę, czyli jak wygląda request do nich, np.:
showCategory ma sygnature: id=[int]&costam=[bool]
i jak się akcja wywoła to sprawdza czy URL w zapytaniu odpowiada jej zdefiniowanej sygnaturze jak tak to tak, nie to nie trzeba smile.gif
tak wiec domyślam się ze showNews będzie miało trochę inną sygnaturę niż showCategory i jak zostanie akcja showNews odpalona i url nie będzie się zgadzał to nie będzie brało wartości od niego.
Możesz też odrejestrowywac/usuwać/kasować/kak zwal tak zwal/ te zmienne które już zostały wykorzystane przez akcje i masz pewność ze nigdzie indziej tego nie będziesz używał. To możesz zrobić definiując w pliku konfiguracyjnym nazwy zmiennych które są wyłączne dla danej akcji i które są odrejestrowywane/usuwane/kasowane/kak zwal tak zwal/ po jej wykonaniu.

A tak na marginesie to radze Ci zajrzeć do frameworku Symfony który podobny problem rozwiązał z poziomu routera, szczególnie zwróć uwagę na pliki konfiguracyjne routera.

Pozdrawiam
Cysiaczek
Trzeba zatem przyjrzeć się .NET, bo te sygnaturki to chyba jest to, choć muszę jeszcze to zbadać : P

Jako przykład wykorzystania tych akcji niech posłużą Pipelines
Jest to jeden ze szczególnych przypadków użycia, gdzie wyjście jednej akcji jest wejściem kolejnej. Taki łańcuch : )

Pozdrawiam.
nasty
Cytat
Trzeba zatem przyjrzeć się .NET, bo te sygnaturki to chyba jest to, choć muszę jeszcze to zbadać : P

hehe, w php to jest do zrobienia i to w bardzo prosty sposób bez przechodzenia na .NET winksmiley.jpg

Chodzilo mi mniej-wiecej o idee, koncepcje tych sygnatur, dlatego wspomnialem o .NET bo tam cos podobnego jest zrobione.

Twój problem bardzo przypomina przeciążanie metod, przynajmniej z tego co zrozumiałem, wystarczy dobrze zidentyfikować dane wejściowe i metoda sama się znajduje.
arecki
Cytat(Cysiaczek @ 20.01.2007, 13:55:26 ) *
Źródło danych jak mówi arecki faktyczne najlepiej zdefiniować w pliku XML.
  1. <showCategory params="request:param1=id, param2=page; showNews: param3=jakas_zmienna" />

Nie wnikajcie w nazwy akcji, ani to, co robią, bo to tylko przykład


Jeżeli już tak to chcesz zrobic to nie lepiej np. tak zdefiniować :
  1. <showCategory>
  2.    <param name="id" from="URL" method="GET"/>
  3.    <param name="cd" from="XML" method="./\test.xml"/>
  4. </showCategory>


Generalnie masz większą możliwość manipulacji i sprawdzania skąd i jakie zmienne możesz czerpać. No i
w parze z tym idzie czytelniejszy zapis i łatwiejsze odczytywanie zmiennych. Nie trzeba nic 'explodować' czy ineczej przetwarzać.

Cytat(Cysiaczek @ 20.01.2007, 13:55:26 ) *
Pominę szczegóły implementacyjne.
Funkcja... nazwijmy ją paramSourceRetriver() powinna odczytać, że argumenty o nazwach param1 oraz param2 znajdują się w rejestrze żądania, natomiast param3 winna zostać pobrana z danych wyjściowych akcji showNews.
Te dane wyjściowe to cokolwiek, co mamy jako wynik przetwarzania akcji, który może też pobrać np. widok.
Wydaje mi się, że dzięki temu jestem w stanie wytworzyć wiele rożnych kontekstów użycia akcji.

Dalej pozostaje problem przysłowiowej już $id z URL'a, bo trzeba będzie wprowadzić dla tego konkretnego żądania parametry $catId oraz $newsId, choć nie związujemy już akcji z konkretnym łańcuchem polecenia, co jest postępem.


Początek już masz więc myślę że możesz o zacząć rozwijać. Ja też myślę o dorobienie do własnego FW możliwości generowania klas i metod potrzebnych do aktualizacji danych z bazy na podstawie definiowanego pliku XML więc dyskusja mi się też przyda smile.gif
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-2024 Invision Power Services, Inc.