ďťż
Podstrony
|
telcocafeMam pytania na temat działania profesjonalnych skryptów jak Wordpress, IPB etc.:Mam takowy skrypt: Strona z formularzami (index.php) gdzie podajemy nick, mail, treść komentarza -> Plik przetwarzający dane (process.php), który w razie braku np. maila przekierowuje na index.php?error=1, a jeśli wszystko w porządku to np. do index.php?ok=ok Czy da się zrobić przekierowanie z process.php do index.php z danymi POST? Wtedy nie mamy wszystkich błędów zapisanych jak na dłoni w linku, który można sobie przecież dowolnie zmieniać. Owszem można przez sesje i ciastka, ale to rozwiązanie niezbyt ładne. Wie ktoś jak to wygląda np. w Wordpressie? przedewszystkim nie stosuje się autoryzacji przez ustawienie zmiennej np. ok na ok czy inne true. W zasadzie 90% mechanizmów autoryzacji opiera się na sesji i ciastkach. Dlaczego uważasz że sesje są nieeleganckie? W sumie to tylko zmiana nazwy zmiennej z $_POST na $_SESSION. To chyba oczywiste, że nie robię autoryzacji przez $_GET. Chodzi mi o przesyłanie kodów błędów w linku, error=1 wyświetli błąd o id 1, ok=ok wyświetli jedynie potwierdzenie i nie zrobi nic poza tym. Mogę w process.php zapisywać błędy do sesji, index.php by je wyświetlał i kasował. Chyba, że są jakieś lepsze rozwiązania, których przez ten temat szukam ;) Użytkownik Ghoost edytował ten post 24 maj 2009, 16:02 A co za problem że ktoś zobaczy jaki masz komunikat błędu pod ID 1 czy 2? Formularz jest wysyłany, walidowany i jeżeli ok to przekierowanie na listę komentarzy z wiadomością że dodany, a jeżeli wystąpiły błędy to powracasz do formularz z danymi wprowadzonymi przez usera i podajesz gdzie i jakie są błędy. Do tego nie trzeba przekierowywać na stronę z błędem. Po prostu widok np. formularza do szablonu przekazuje wtedy info o błędach. Jeżeli wystąpił błąd systemowy to wtedy następuje zazwyczaj wyświetlenie ogólnej strony błędu z informacją że coś się popsuło, ale ekipa pracuje nad zbadaniem sprawy (najłatwiej robi się to poprzez obsługę wyjątków, które w PHP nie są niestety powszechne.) Nie ma problemu, że ktoś zobaczy, ale gdy pojawi się np. kilka błędów to w linku powstaje chaos. A w sesjach to by było zrobione po cichu, bez zaśmiecania linku. Dodatkowo przy odświeżaniu nie pojawi się po raz kolejny błąd, ponieważ się za pierwszym razem wykasuje z sesji. Właśnie jestem ciekaw jak to się robi w Wordpressie i innch CMS, a tam dobrnąć do jakiejś funkcji jest skomplikowane, więc liczę na Waszą pomoc :| Jak masz wiele pól w formularzu to nie masz przekierowania na jakiś link gdy występuje problem, tylko masz ten sam i obok pól wyświetlają się określone komunikaty błędów - błędy, które użytkownik może "usunąć" poprawnie wypełniając formularz. Gdy np. nie udało się zapisać do bazy danych z dobrze wypełnionego formularza to można zrobić tak jak przy walidacji formularza - zwrócić do szablonu treść błędu, lub jeżeli błąd jest poważniejszy i wymaga interwencji admina - przekierować na domyślną stronę z komunikatem typu "coś się wysypało". Po prostu jak stosujesz wzorzec MVC takie sprawy nie stanową problemu. Przykład widoku (kontrolera) w Django: class AddCharacterForm(forms.ModelForm): class Meta: model = Character fields = ('name', 'gender', 'level', 'user') @login_required def add_character(request): form = AddCharacterForm() if request.POST: form = AddCharacterForm(request.POST) if form.is_valid(): form.save() return HttpResponseRedirect('/ice/') return render_to_response( 'ice/add_character.html', {'form': form}, context_instance=RequestContext(request)) Po wejściu na daną stronę pojawi się formularz taki jak w szablonie ice/add_character.html. Jeżeli formularz zostanie wysłany system zwaliduje go i jeżeli poprawny - przekieruje dalej, a jeżeli nie jest poprawny - pojawi się ten sam szablon z wprowadzonymi danymi oraz informacjami przy błędnie wypełnionych polach. Użytkownik Riklaunim edytował ten post 24 maj 2009, 20:27 MVC pod PHP to jednak coś strasznego, proste strony oparte np. na cakePHP potrafią parsować się kilka sekund, wykonując przy okazji masę zbędnych zapytań do bazy. Ten język jednak służy do czegoś innego ;) Python i Dijango to trochę inna sprawa, ale tutaj poprostu użył bym jakiegoś kodowania błędów, aby przekazać je w pojedynczej zmiennej. Dodatkowy plus jest taki, że możesz utworzyć oddzielny plik z komunikatami błędów w postaci kod => tekst i includować go gdzie trzeba. Nie używam MVC, takie rzeczy są pod większe projekty. Obecnie mam w pliku komunikaty błędów w stylu kod -> tekst jak napisał someone. Chodzi mi o najlepszy sposób, żeby z pliku walidującego przekazać ewentualne błędy do np. index.php Można przez index.php?error=1 (ale nie mam pomysłu jak przekazać kilka błędów przez GET), można do sesji, przekierować do indexu, który wyświetli błąd i wyczyści sesję. Da się jakoś wysłać żądanie POST z przekierowaniem? Trochę poszukałem ale podobno to jest niemożliwe w PHP. można napisać to w ten sposób, że jedna zmienna przekazuje kilka błędów jako np. sumę komunikatów. Np. nadajesz komunikatom id będące kolejnymi potęgami dwójki, suma tych cyfr będzie zawsze unikalna dla konkretnego zestawu błędów (poprawcie jeśli się mylę ;) ) i dość łatwo rozłożyć ją na czynniki. Można je łączyć na wiele sposobów ten to tylko jeden z pomysłów, chociaż ja osobiście zastosował bym tablicę w sesji z identyfikatorami pól oznaczonych jako błędne i przy każdym elemencie np.(oczywiście kod czysto ideowy) echo in_array($input_id,$invalid_inputs)?$input.$msg:$input; a na końcu unset i z głowy. MVC pod PHP to jednak coś strasznego, proste strony oparte np. na cakePHP potrafią parsować się kilka sekund, wykonując przy okazji masę zbędnych zapytań do bazy. Ten język jednak służy do czegoś innego ;) Głupoty piszesz. Jest wiele frameworków w PHP wykorzystujących ten wzorzec - zarówno publiczne i nie i jakoś nie parsują się kilku sekund, ani nie wykonują zbędnych zapytań, chyba że im powiesz żeby określone zapytania wykonywały. Jakoś nie stwierdziłem wykonywania tajemniczych zapytań CI, czy też "zbędnych" zapytań nie wykonuje firmowy framework obsługujący serwis z 500 tysiącami użytkowników ;) Nie używam MVC, takie rzeczy są pod większe projekty. Jeżeli robisz forum, lub inny skrypt nie będący księgą gości to zastosowanie frameworka w niczym nie zaszkodzi a i znacząco pomoże oferując gotową strukturę kodu, jak i różne pomoce. Obecnie mam w pliku komunikaty błędów w stylu kod -> tekst jak napisał someone. Chodzi mi o najlepszy sposób, żeby z pliku walidującego przekazać ewentualne błędy do np. index.php Można przez index.php?error=1 (ale nie mam pomysłu jak przekazać kilka błędów przez GET), można do sesji, przekierować do indexu, który wyświetli błąd i wyczyści sesję. Da się jakoś wysłać żądanie POST z przekierowaniem? Trochę poszukałem ale podobno to jest niemożliwe w PHP. Próbujesz zastosować najmniej pasujące rozwiązanie (i utrudniasz sobie życia jak się da ;))... Poczytaj sobie książki np. o użyteczności stron internetowych ("Nie każ mi myśleć") bo obsługa błędów formularza i ogólnie formularzy to trywialne zagadnienie zarówno od strony kodu jak i zachowania. Można lub i nie stosować MVC, ale tak czy siak implementacja obsługi błędów wynikłych z wprowadzonych przez użytkownika danych NIE WYMAGA przekierowywania na stronę, która powie np. że login jest już zajęty. Skrypt ma pokazać wypełniony formularz i komunikaty błędu obok niezwalidowanych pól. Oddzielną stronę błędu - błędu niezależnego od użytkownika wyświetla się wtedy, gdy aplikacja natrafi na błąd czy też wyjątek. Wtedy w niektórych implementacjach stosuje się różne strony błędy ?error=jakiśtam, czy też po prostu stosuje się jedną stronę błędu (nie wyświetlającą szczegółów tak przy okazji). Wiadomości o powodzeniu operacji można wyświetlać tą samą metodą co walidacja formularza, czy też przekierowanie przez wiadomość (jak np. na tym forum), lub bezpośrednie przekierowanie i wyświetlenie wiadomości dla tego użytkownika bazując np. po sesji obsługiwanej poprzez bazę danych / czy cookie. (W Django są "wiadomości systemowe" działające właśnie w oparciu o sesje frameworka). Po prostu jak chcesz coś zrobić dobrze to nie da się tego zrobić bazując na "poradach dla początkujących", tylko należy zastosować konwencję - sprawdzone i funkcjonujące rozwiązania. Frameworki i rozwiązania w ich okolicy stworzono po to żeby nie myśleć jak zapewnić walidację formularza, tylko żeby od razu ten formularz implementować. Użytkownik Riklaunim edytował ten post 25 maj 2009, 09:48 Głupoty piszesz. Jest wiele frameworków w PHP wykorzystujących ten wzorzec - zarówno publiczne i nie i jakoś nie parsują się kilku sekund, ani nie wykonują zbędnych zapytań, chyba że im powiesz żeby określone zapytania wykonywały. Jakoś nie stwierdziłem wykonywania tajemniczych zapytań CI, czy też "zbędnych" zapytań nie wykonuje firmowy framework obsługujący serwis z 500 tysiącami użytkowników. Pisałem konkretnie o cakePHP z którym mam (wątpliwą) przyjemność pracować. Z reguły wczytuje model na którym pracujemy plus kilka modeli zależnych, co przy średniej wielkości projekcie oznaczało czasem połowę bazy, z czego wykorzystywało się np. login usera z jednego modelu i zawartość jego koszyka z drugiego. Do tego wystarczy, że potrzebujesz jakiegoś helpera załóżmy AJAX, w jednym widoku, a zostanie wczytany przy każdym widoku danego kontrolera. Pod koniec dość pokaźnego projektu, przy wyświetlaniu nowego pustego widoku(który de facto jeszcze nic nie robił), framework generował ponad setkę zapytań mySQL. No i zależy jeszcze na czym ten framework uruchamiasz, przy szybkim sprzęcie nie jest to tak widoczne, ale przy słabszym serwerze, ten narzut frameworka wynosi czasem kilka sekund. Przyszło mi też pracować z dedykowanym frameworkiem na którym stoją portale jednej z dość dużych polskich firm(myślę że 500.000 userów spokojnie ;) ). To już zupełnie inna historia, ale też nie było to czyste MVC. Kontrolery, praktycznie nie występowały, a raczej częściowo w widoku, a częściowo w modelu. Zresztą ogólnie konwencja została potraktowana dość luźno(mimo to łatwiej mi było pracować w tym środowisku niż w sztywnym jak kij cake'u). Kiedy robiłem niewielką stronę dla siebie wolałem dołączyć kilka własnych klas (obsługa mySQL itp.), a resztę dopisać w strukturalnym PHP. Czas kodowania był zbliżony. Obciążenie sprzętu było kilkakrotnie niższe(mówimy o niewielkiej stronie). To trzeba używać lepszego frameworka od Cake ;) A jak się pyta jak działają profesjonalne fora to odpowiedź prosta - używają nowoczesnych technologii i rozwiązań. Można przez index.php?error=1 ... przekierować ... Po co przekierowywać? Jeżeli wystąpi błąd krytyczny lub trzeba wyświetlić tylko informację / komunikat, po prostu wyświetl szablon komunikatu zamiast szablonu całego forum. W systemie CMS robię to tak: http://pastebin.pl/8366 Na pewno można rozwiązać lepiej wyświetlanie błędów i dołączanie szablonów. Gdy wystąpią błędy w formularzu, wyświetl go ponownie. W przeciwnym wypadku na 90% użytkownik utraci dane, które wpisał. Niestety większość serwerów wciąż wysyła nagłówki No-Cache, chociaż wyślesz z poziomu PHP "Cache-Control: public". Błędy wyświetlaj obok pól formularza albo nad formularzem. To zależy od Twojej inwencji. W programowaniu strukturalnym można to zrobić tak:if($_POST) { $dane = array( pola formularza przygotowane do zapisania w bazie danych ); try { $db->beginTransaction(); //jeżeli wykonujesz wiele operacji w bazie if( ...istniejący element... ) { $q = $db->prepare(' zapytanie UPDATE do bazy '); } else { $q = $db->prepare(' zapytanie INSERT do bazy '); } $q->execute($dane); /* wyświetl komunikat - nie podaję kodu, bo to zależy od skryptu */ return 1; //Wszystko w porządku - zakończ wykonywanie pliku } catch(PDOException $e) { /* wyświetl komunikat o błędzie, ale nie zatrzymuj wykonywania skryptu */ } } elseif( ...edycja elementu... ) { /* pobierz element z bazy, a gdy nie istnieje, wyświetl błąd i zakończ ten plik */ } else { $dane = array( domyślne wartości ); } /* teraz tworzymy potrzebne informacje, przekazujemy $dane do szablonu i wyświetlamy go */W obiektowym może być trochę inaczej, ale należy zawsze pokazać formularz z wypełnionymi danymi, gdy wystąpi błąd. Dane użytkownika są cenne. Gdy utraci swoją wypowiedź, którą pisał kilka godzin, na pewno będzie sfrustrowany. Polecenie return w tym przypadku nie kończy wykonywania skryptu, lecz jedynie wykonywanie pliku. Zakładam, że jest on dołączany przez główny kontroler. Code Igniter w testach szybkości bije pozostałe popularne frameworki. Za nim stoi Zend Framework. Użytkownik Ferrari edytował ten post 25 maj 2009, 14:48 To trzeba używać lepszego frameworka od Cake Jak to mówią do szefa przychodzisz ze swoją opinią, a wychodzisz z jego :Tongue: Nie mam na to wpływu niestety :) Może kiedyś przyjdzie mi pracować z lepszym frameworkiem i zmienię zdanie. Użytkownik someone edytował ten post 25 maj 2009, 15:01 Code Igniter w testach szybkości bije pozostałe popularne frameworki. Za nim stoi Zend Framework. Tyle że CI nie wszystko może, tak żeby czepiać się szybkości, ale jak na potrzeby zwykłego programisty starcza. Jeżeli masz do zrobienia duży projekt to wybierasz najlepszy funkcjonalnością framework i technologie -- i nie obchodzi cię w tym przypadku milisekundy spowolnienia generowane przez framework bo i tak duża aplikacja będzie skalowana w poziomie na kilku serwerach aplikacyjnych i kilku bazodanowych dla przykładu. Ach, i weź z takimi pogadaj :( Nie używam frameworków, systemów szablonów, ani nie jest mi potrzebna obsługa wyjątków. Czy bez tego rozwiązanie mojego problemu jest niemożliwe? Strona, którą projektuję jest małym projektem (ale to nie żadna księga gości), więc nie korzystam z systemów szablonów (co nie znaczy, że mam php i html całkowicie wymieszane). Ma ktoś jakiś inny pomysł na rozwiązanie problemu? (nie dam się przekonać na system szablonów ani framework - przynajmniej nie przy tym skrypcie) No to będziesz rzeźbił i gdyby ktoś miał to oceniać to byłoby 0/10... ale tak na poważnie - do obsługi formularza i wyświetlania błędów NIE jest potrzebny framework ani NIE są potrzebne przekierowania i dziwne POSTy z przekierowaniem na różowe ananasy :P. Sposób obsługi formularzy był tu przedstawiony kilka razy. Jest to proste i nie wymaga kosmicznych technologii. Jeżeli wystąpi błąd, po prostu prześlij do użytkownika ponownie formularz z wypełnionymi danymi i wyświetl błędy. Pokazałem, jak to zrobić. Gdzie wyświetlisz błędy, to już należy do Twojej inwencji. Możesz je zapisywać na przykład w tablicy $error lub w inny sposób. Zawsze lepiej, gdy błędy są wyświetlane obok źle wypełnionych pól, choć łatwiej pokazać je nad formularzem. Staraj się tak zaprojektować skrypt, aby do kodu HTML wstawiać konkretne wartości, czyli:ZAMIAST ZANIECZYSZCZAĆ KOD: <input value="<?= ($_POST) ? htmlspecialchars($_POST['xxx'], 2, 'UTF-8') : (nowy ? ... : ...) WSTAW KONKRETNĄ WARTOŚĆ <input value="<?= $wpis['nazwa_pola'] ?>"> JEŻELI W BAZIE PRZECHOWUJESZ WARTOŚCI, KTÓRE MOGĄ ZAWIERAĆ KOD HTML: <input value="<?= htmlspecialchars($wpis['nazwa_pola']) ?>">Dla htmlspecialchars dodaj trzeci argument o wartości 'UTF-8', jeżeli używasz kodowania UTF-8. W CMS-ie stworzyłem własną funkcję clean(), która wywołuje htmlspecialchars, opcjonalnie skraca ciąg znaków i usuwa wulgaryzmy. Co będzie zawierać $wpis - to zależy już od kodu PHP. Podobnie z błędami. Wszystko przygotuj w logice skryptu, a w warstwie prezentacyjnej wstaw konkretne wartości. Żadnych przekierowań header('Location: error.php?id=999'); Są one niepotrzebne. Użytkownik Ferrari edytował ten post 26 maj 2009, 21:49 @Ferrari: tu chodziło o zakodowanie danych między plikiem walidującym a plikiem wyświetlającym formularz. Co do metody to przykładowo masz błędy o ID przypisanych na zasadzie 2 - zły mail 4 - za krótkie hasło 8 - zajęty login 16 - za długi post w ten sposób masz 2+8+16 = 26, czyli formularz.php?error=26 i wyświetlone trzy błedy. w formularzu rozbijasz to sobie odejmując kolejno największą możliwą liczbę, wyświetlasz odpowiadajacy jej bład, i tak aż do wyzerowania zmiennej. Można tak zrobić, ale Ferrari ma rację, że trzeba pokazać z powrotem wszystkie wpisane dane, a tego przez GET nie prześlę. Można by przekazać formularz ale to tylko jeśli korzystamy z szablonów. Chyba najlepszym rozwiązaniem będzie przekierowanie formularza nie do oddzielnego pliku, tylko do np. index.php?zrob=nowypost Nie będzie przekierowań, ale najwyżej zastosuję klasę, którą odpalę jeśli pojawi się zmienna $_GET['zrob'] i zajmie się wszystkim. Macie lepsze pomysły? ;) Zrobić to tak jak należy - nie pasuje - nie pytaj jak to zrobić. Obrazowy przykład: http://extjs.com/dep...rm/dynamic.html - dodatkowa walidacja na poziomie JS (pod żadnym pozorem nie zastępująca walidacji po stronie serwera). Użytkownik Riklaunim edytował ten post 27 maj 2009, 10:32 IMO najwygoniejsza jest wstępna walidacja za pomocą ajaxa/js, wtedy dopóki ktoś umyślnie nie wpisze złych danych, napewno nie wyśle złego formularza. W takim wypadku problem przywracania danych do pól ma mniejsze znaczenie. Ferrari mi pomógł znaleźć wg. mnie lepsze rozwiązanie: Formularz (w pliku index.php) przekierowuje na ten sam index.php (można dla porzadku z jakimś parametrem GET) if($_POST) { if(strlen($email)>100) $error[]='błąd'; //Walidacja } Taką tablicę $error można odczytać np. nad formularzem i wyświetlić wszystkie błędy. Lepiej bez szablonów zrobić się raczej nie da :) Ale tracisz dane wpisane przez użytkownika. O tym też pomyślałem, ale nie napisałem ;) if($_POST) { $u = array( 'e-mail' => $_POST['e-mail']), ); if(strlen($email)>100) $error[]='błąd'; //Walidacja } i <input value="<?php echo $u['e-mail'] ?>" /> Wie ktoś jak skrócić "<?php echo ?> do wstawiania zmiennych? widziałem taki kod <?=$x?> - można tam wstawiać tylko stałe i zmienne? czy tekst też? Jest to gdzieś w manualu PHP? <?= działa identycznie jak <? echo lub <?php echo, jednakże w php.ini musi być włączone short_open_tag A co do zmiennych z $_POST: if (isset(costam)) { ... } else { $_POST['pierwszepole'] = (empty($_POST['pierwszepole'])) ? '' : $_POST['pierwszepole']; } Użytkownik Petermechanic edytował ten post 27 maj 2009, 21:57 Po co przypisywać domyślne wartości do zmiennych $_POST? Nie lepiej tak:if($_POST) { $tablica = array(... tutaj przygotowujesz dane z POST ...); /* UWAGA! W razie błędu bazy danych nie można przerwać wykonywania skryptu, lecz należy wyświetlić błąd! */ } elseif(... wyrażenie, które zwróci true, jeżeli user edytuje element ...) { $tablica = // kod, który pobierze dane do tej tablicy } else { $tablica = array( /* domyślne wartości */ ); } // Teraz już można powstawiać do kodu HTML odpowiednie pola tablicy $tablica // Pamiętając, że żadna wartość NIE może zawierać kodu HTML, gdy wstawiamy ją do value="" // Należy użyć funkcji htmlspecialchars() przy obróbce danych POST albo przy wstawianiu wartości do formularza Użytkownik Ferrari edytował ten post 28 maj 2009, 13:42 Ferrari, i tak - i tak będzie dobrze. Kwestia użycia zmiennych, po co tworzyć tablicę $tablica, skoro $_POST zostanie stworzone przy przesłaniu formularza? :) |
|||
Sitedesign by AltusUmbrae. |