Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wyjątki dla błędnych URLi - dobra metoda?
Forum PHP.pl > Forum > PHP
pitbull82
Witam

Powszechnie mówi się, że wyjątki powinno stosować się do obsługi nieprzewidzianych sytuacji. Czy Waszym zdaniem powinno się je zastosować do obsługi błędnych URLi?

Mam taką sytuację, że u mnie błędne URLe są/będą wykrywane na różnym poziomie:

  1. router - analizuje składnię urla i jeśli nie w stanie znaleźć w nim pożądanych elementów, jeśli znajdzie jakieś duplikaty parametrów lub kolejność parametrów jest nieprawidłowa ustawia url przekierowania i rzuca wyjątek
  2. dispatcher - sprawdza czy na podstawie danych z routera jest w stanie wywołać odpowiedni kontroler i akcję - jeśli nie ustawia url przekierowania i rzuca wyjątek
  3. konkretny kontroler sprawdza czy nie ma nadmiarowych parametrów/czy ma wszystkie wymagane parametry/czy parametry mają poprawne wartości - jeśli nie ustawia url przekierowania i rzuca wyjątek


Wszystkie wyjątki łapie frontcontroller i uruchamia przekierowanie. Teoretycznie można by to zrealizować bez wyjątków, ale wydaje mi się że tak jest przejrzyściej. Pytanie tylko czy to trochę nie nadużycie wyjątków, bo przecież w każdym z 3 poziomów jestem w stanie stwierdzić że URL jest niepoprawny i po prostu uruchomić przekierowanie zamiast rzucać wyjątek i nakładać to zadanie na front controllera. Jak uważacie?

Pozdrawiam
thek
To zależy jak bardzo aplikacja ma być "elastyczna" i "idiotoodporna". Zanalizuję po kolei jak Ty dla róznych elementów.
1. Router - duplikaty i zamieniona kolejność to tak naprawdę nie błąd. Aplikacja bez problemu to obsłużyć potrafi. No chyba, że dla Ciebie to istotny element SEO-friendly linków, ale wtedy robisz canonical, 301 lub z automatu zmieniasz kolejność zanim do dispatchera poślesz. Sprawa ma się inaczej z brakiem parametru. To już błąd i zmusza aplikację do jakiejś reakcji. Tutaj wyjątek jest rozsądnym rozwiązaniem.
2. Dispatcher - Tutaj raczej sprawa jasna. Może zrobić link - OK, nie może - powinien poinformować aplikację, że coś nie halo. Wyjątki więc ładnie się wpasowują w koncepcję.
3. Kontroler. Też różnie - podobnie jak w routerze. Nadmiarowe parametry - ignoruje, ale nie wyświetla by nie mówić wiele userowi, który może strzelać z nazwami parametrów by znaleźć "nieudokumentowane" wink.gif Brak wymaganych parametrów powinien być sygnalizowany - kontroler i tak się wysypie, więc sens rzucenia wyjątku jest. Jeśli niepoprawna wartość to informujemy usera o ograniczeniu, parametr ignorujemy i działamy tylko na prawidłowych. Jeśli byki dopowadzą do niedoboru parametrów postępujemy jak dla ich braku. Tak więc wyjątki są tu Ok.
pitbull82
Jest tak jak napisałeś, wszystkie restrykcje są typowo pod kątem SEO i braku indeksowania nadmiarowych URLi - w wielu aplikacjach jest tak, że jak ktoś się uprze to może z urlami robić co chce i strona "zadziała" a przy podlinkowaniu się zaindeksuje, co sprytna konkurencja może wykorzystać powodując duplicate content w obrębie witryny dlatego chciałbym wymusić że albo url jest idealnie taki jakiego się spodziewam albo 301 na url taki jaki moim zdaniem jest prawidłowy.

Obsługując wyjątki w front controllerze zyskuję dodatkowo możliwość np. logowania takich urli bo z punktu widzenia logiki aplikacji chyba ani router ani ewentualny response nie powinien się tym zajmować?
thek
Myślę, że najbezpieczniej jest mimo wszystko puścić "pokręcony" url z adnotacja w stronie o canonical. Dzieki temu mimo iż strona zostanie złapana w sieć, to nie sprawi problemu z duplikatem, gdyż wskaże prawidłowy url robotowi. Dzięki temu nie będziesz zmuszony modyfikować kolejności parametrów, ale podasz je w prawidłowej i uniknesz redirecta niepotrzebnego. Jaki będzie efekt po kolei?
Router - usunie duble parametrów, ustawi kontroler, metodę i parametry,
Dispatcher - przekaże do kontrolera i jego metody żądanie z parametrami lub wywali, że takiego kontrolera brak (wyjątek)
Kontroler - wywoła metodę z odpowiednimi parametrami rozpoznanymi. Sygnalizuje błędne parametry, metody czy brak wymaganych parametrów. Przy wrzucaniu znanych sobie parametrów sprawdza zgodność kolejności parametrów i ewentualnie ustawia canonical.

Zauważ jak prostą logiką pozbyłem się niepotrzebnie 301 nadmiarowych i uodporniłem na duplicate content za jednym zamachem. 301 na prawidłowy adres to bowiem nie jedyne rozwiązanie. Stosuj je jedynie gdy faktycznie tak musi być i koniec. Sprawiasz bowiem, że masz więcej żądań niepotrzebnie. 301 powinno być stosowane gdy masz brak danych koniecznych w danym elemencie. Przykładem jest choćby to co robiłem niedawno podczas przepinania ze starej na nową wersję serwisu. W starej wersji w linku był id i kompletnie inna forma SEO niż na nowym. Wymuszało to na mnie dorwanie się do bazy by na podstawie ID pobrać wymagane dla nowego SEO-linku dane. Tego ani router, ani dispatcher nie wykonują, więc musiałem iść aż do kontrolera, który to zrobił i wywołał właściwe 301 ostatecznie. Ale to są jedne z nielicznych przypadków gdzie tak powinno się robić.
pitbull82
Z jednej strony masz rację, bo rzeczywiście w mojej metodzie wywołanie przekierowania to odpalenie co najmniej kilku klas bazowych, wczytanie configów a wszystko tylko po to żeby wykonać ostatecznie przekierowanie.

Jednak w przypadku nowego serwisu mogę założyć, że wszystkie urle na stronie będą poprawne i żadne linki zewnętrzne nie będą prowadzić do nieistniejących urli (nowa domena). Dokładając do tego, że mimo wszystko osób eksperymentujących z urlami i próbujących zaszkodzić stronie będzie niewiele (raczej grubo mniej niż 1%) obciążenie będzie stosunkowo niewielkie. Do tego z tego co poczytałem właśnie rel="canonical" ma takie sobie opinie, mimo wszystko ludzie radzą raczej 301, sam osobiście rel="canonical" nigdy nie stosowałem, a 301 wielokrotnie.

thek
Akurat o ładowanie klas to bym się mało martwił wink.gif I tak większość FW ładuje przy byle drobiazgach tyle klas, że głowa boli. Jedna w tę czy tamtą to żadna różnica.

Co do canonical to jest to z tego co kojarzę wynalazek google, więc z nim na bank będzie działać, ale już inne wyszukiwarki niekoniecznie muszą go respektować i stąd pewnie te różne opinie. Co do domen to szczerze mówiąc zawsze podpinam narzędzia webmastera. Czemu? Bo nigdy nie wiesz czy domena aby nie była już w użyciu i coś nie jest pod nią zaindeksowane mimo wszystko. W ten sposób można na starcie albo mieć przewalone do odkręcania rzeczy (ban w przeglądarce po jakimś black-SEO), albo raj na ziemi (porobić 301 na już zaindeksowane url i przejąć ich siłę). Akurat to ostatnie to na dniach będę robił, bo szef wykupił jedną używaną domenę i już przeglądaliśmy jakie linki możemy "przejąć" wink.gif

Jeśli tak Ci zależy na tej zgodności to stwórz sobie "ścieżki", które określą Ci poprawną kolejność parametrów. Jeśli masz tak, że parametry są zawsze w określonej i niezmiennej (par1, par2, par3, par4) niezależnie od braku lub obecności jakiegoś to problem jest prosty, gdyż tylko ustawiasz według niej i koniec. Gorzej gdy konieczne jest trzymanie się nie tak znów oczywistych schematów, a więc par 3 może wystąpić tylko jeśli poprzedza go par2, a par4 może wystąpić po par2 lub po par3, ale nie po par1, choć może jednakże wystąpić samodzielnie. W takich przypadkach musisz kombinować jak szybko określić, które z parametrów są na podpuchę i z jakich możesz utworzyć realne ścieżki. Ja podam Ci taki, który teraz mi przyszedł do głowy jako możliwa implementacja:
1) wybieramy system binarny bo z niego ładnie maseczki zrobimy dla bitowych funkcji Boole'a
2) w schematach możliwych kombinacji określonemu parametrowi przypisujemy zawsze tę samą pozycję co utworzy nam wiele masek. Te wzorce w postaci masek możemy na sztywno zapisać gdzieś, by nie przeliczać za każdym razem.
3) z parametrów otrzymanych przez żądanie robimy w identyczny sposób jego schemat,
4) używamy funkcji AND dla każdej pary schemat+wzorzec. Jeśli wynik tej funkcji pokrywa się z maską wzorca z punktu 2) to mamy pełne trafienie.
W wyniku przejścia przez wszystkie maski możemy otrzymać wiele trafień. Dlatego dla optymalizacji wygodnie uszeregować maski z 2) od razu w kolejności od najbardziej oczekiwanej do najmniej, czyli zapewne od tej mającej najwięcej parametrów występujących do tych mających najmniej.

Przykład:
Przewiduję 4 parametry w kolejności: państwo, miasto, ulica, strona_paginacji, a więc wzorzec ABCD i stosuje system dwójkowy
Ustalam, że ich ważność i wzorce to: ABD(1101), BCD(0111), ACD(1011) , AB(1100), BC(0110), BD(0101) , CD(0011), AD(1001), B(0100), A(1000), C(0010)
Dostałem z żądania państwo, miasto i ulicę, czyli A, B i C, więc mam wzorzec 1110. Teraz po kolei jadę funkcją AND po znanych mi wzorcach:
1101 & 1110 = 1100 => nie to
0111 & 1110 = 0110 => nie to
1011 & 1110 = 1010 => nie to
1100 & 1110 = 1100 => trafiony!

Wiem dzięki temu gdzie przekierować, bo odczytam prosto, że to AB. Tak więc państwo, miasto tylko mi były potrzebne, zaś ulica była zbędna.
To jedna z możliwych implementacji poprawności i jest ich ogrom, zależny od pomysłowości piszącego smile.gif Myślę, że sam wymyślisz własne rozwiązanie.
Mogłem też olać hierarchię i przepuścić funkcję AND przez wszystkie wzorce, nawet losowo, ale zapisać czy wzorzec trafił czy nie. Wygrałby w tym wariancie przykładowo wzorzec z najwyższą wartością. Dobra metoda gdy mamy możliwość pracy z systemem wieloprocesorowym bo zrównoleglamy zadanie. Zróbcie sprawdzenie na 4 prockach to każdy dostanie po 3 kombinacje do sprawdzenia. Jeśli kombinacji są dziesiątki, to sekwencyjne sprawdzanie ma dużą szansę wykonać się wolniej. Zwłaszcza z mniej popularną kombinacją.
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.