Lekcje komputerowe

Biblioteka PHP do pracy z API Yandex.Money. Demony - kolejki wiadomości Zła wiadomość php

3,3 tys

Wyświetlanie komunikatów użytkownikowi to dość częsta akcja, którą powinna wykonywać aplikacja internetowa. Może się to zdarzyć podczas przetwarzania formularzy, mogą to być komunikaty o błędach, komunikaty informujące o konieczności rejestracji, gdy użytkownik próbuje uzyskać dostęp do zastrzeżonej części witryny i w wielu innych przypadkach.

Bardzo często tworzenie i wysyłanie wiadomości jest rozdzielane na różne żądania HTTP. Z reguły wygodnie jest skorzystać z przekierowania po przetworzeniu formularzy (by uniknąć problemów z przyciskami Wstecz i Odśwież), ale jednocześnie naturalnym momentem tworzenia wiadomości jest właśnie moment przetworzenia formularzy i wykonania czynności towarzyszących To. Dlaczego? Wyobraź sobie, że tekst wiadomości powinien wyglądać mniej więcej tak: „Liczba zamówionych sztuk produktu «Podkładka pod mysz» została pomyślnie zmieniona z 7 na 12.” Po przekierowaniu, być może na zupełnie inną pod względem funkcjonalnym stronę, ustalenie, co zostało zrobione wcześniej, będzie dodatkowym problemem.

Najczęściej komunikaty wyświetlają się w żądaniu POST przetwarzającym formularz - to niedobrze, słowa „ta strona jest nieaktualna” psują życie (gdy użytkownik zdecyduje się spróbować przycisku Wstecz).

Ktoś korzysta z przekierowania, rezygnując z przyjaznych wiadomości.

Jednocześnie istnieje prosty i oczywisty sposób na poprawę życia. Mimo oczywistości, z jakiegoś powodu nigdy nie widziałem, żeby ktoś z tego korzystał - przynajmniej gdy przeglądałem źródła innych osób.

Mamy więc problem – wiadomość musi „żyć” w różnych żądaniach. Potrzebujemy mechanizmu, który przeniesie tekst wiadomości na stronę, która ma go wyświetlić. Pewnie pamiętaliście już o sesjach.

Tak, generalnie masz rację. Inne metody, np. poprzez zmienną globalną, nie pozwalają na zapisanie danych w przypadku użycia przekierowania (przypis Maxima Naumenko). Poza tym zazwyczaj dbam o to, aby każdy ekran w aplikacji miał możliwość, wraz z innymi informacjami, wyświetlenia komunikatów, które zostały wygenerowane na poprzednich ekranach. Jest to wygodne, ponieważ nie trzeba przygotowywać osobnych ekranów do wyświetlania komunikatów, a użytkownik nie musi ponownie klikać myszką. Ale tak naprawdę projektant musi się tu zastanowić - wyróżnić obszar, w którym pojawią się komunikaty.

Pomysł jest bardzo prosty i można go wdrożyć za pomocą kilku klas.

Pierwszą rzeczą, która przychodzi na myśl, jest utworzenie klasy Message, która w rzeczywistości reprezentowałaby wiadomość na naszym prostym diagramie klas. Wiadomość musi mieć możliwość zapisania się w sesji, a także wyświetlenia na ekranie.

class Message ( /** * Treść wiadomości. */ var $content; /** * Konstruktor inicjujący tekst wiadomości. * * @param content treść wiadomości */ funkcja Message($content) ( $this->content = $ treść ; ) /** * Napisz wiadomość do sesji */ funkcja send() ( $_SESSION["session_messages"] = $this->treść; ) /** * Wyprowadź wiadomość na stronę. */ funkcja toPage() ( echo " - " . $this->treść . "
"; } }

Aby uzyskać dostęp do sesji, używana jest zmienna $_SESSION.

Zauważ, że $_SESSION jest tablicą, używamy tylko jednego elementu tej tablicy z indeksem „session_message”.

W tym przypadku mamy do czynienia z „tablicą tablic” – to co przechowujemy w elemencie „session_message” to tablica, jest to lista przesłanych wiadomości (oczywiście może ich być kilka).

Jeśli nie mogłeś znaleźć wątku, czas odświeżyć sekcje podręcznika poświęcone sesjom i tablicom.

Możesz mieć pytanie. Dlaczego potrzebne są tutaj zajęcia? Można byłoby obejść się dzięki dwóm funkcjom. Ale spójrzmy dalej. Być może będziemy musieli utworzyć wiadomości różnych typów (informacje, błędy, ostrzeżenia) i określić odbiorców wiadomości.

Należy pamiętać, że w tej chwili do sesji nie jest wprowadzany sam obiekt, a jedynie tekst wiadomości. OOP pozwala nam później zmienić zachowanie metody send() bez zmiany kodu klienta uzyskującego dostęp do tej metody (na przykład w przyszłości będziemy mogli zapisać do sesji cały obiekt Message, jeśli ma on wiele pól).

Wyobraźmy sobie, że zrobilibyśmy to za pomocą funkcji. Prawdopodobnie mielibyśmy funkcję Message_send($txt), a także funkcję Message_to_page($txt). Teraz musimy dodać możliwość innego zachowania dla różnych typów wiadomości. Zmiana wywołań funkcji: Message_send($txt, $kind), Message_to_page($txt, $kind). Będziesz musiał przeszukać cały kod aplikacji w poszukiwaniu takich funkcji, wprowadzając poprawki.

Można tego uniknąć, przewidując sytuację z wyprzedzeniem, przedstawiając komunikat jako tablicę asocjacyjną: $msg[„txt”], $msg[„kind”], wtedy w wywołaniach funkcji będzie tylko jeden parametr. Czy czujesz, jak to próbuje stać się klasą?

Zatem OOP daje Ci możliwość luksusu nieprzemyślania wszystkiego z wyprzedzeniem.

Kolejna klasa - Inbox - jest przeznaczona właśnie do tego.

class Inbox ( /** * Tablica odebranych wiadomości. */ var $messages = array(); /** * W konstruktorze pobieramy wszystkie otrzymane wiadomości * i usuwamy je z sesji. */function Inbox() ( if (is_array($ _SESSION["session_messages"])) ( $messages = $_SESSION["session_messages"]; $co = sizeof($messages); for ($i = 0; $i< $co; $i++) { $this->wiadomości = nowa wiadomość($wiadomości[$i]); ) ) /* wyczyść tablicę komunikatów */ $_SESSION["session_messages"] = array(); ) /** * Wyświetla zawartość skrzynki odbiorczej na stronie. */ funkcja toPage() ( $co = sizeof($this->messages); if ($co > 0) ( echo "Wiadomość z systemu:
"; ) dla ($i = 0; $i< $co; $i++) { $this->wiadomości[$i]->ToPage(); ) ) )

Wypróbujmy nasz system przesyłania wiadomości.

Stwórzmy bardzo prosty przykład, który odpowie na przesłanie formularza, podając liczbę sekund w bieżącej minucie.

wysłać(); /* przekierowanie do siebie */ header("lokalizacja:"); ) else ( $skrzynka odbiorcza = nowa skrzynka odbiorcza(); $skrzynka odbiorcza->toPage(); ) ?>

Całą pracę z tablicami i sesjami ukryliśmy wewnątrz klas, dzięki czemu ostateczny kod wygląda prosto i pięknie.

Utwórz katalog na swoim serwerze internetowym, następnie utwórz w nim te trzy pliki i wypróbuj skrypt. Należy pamiętać, że nie ma problemów z przyciskami Wstecz i Odśwież.

Teraz wyobraź sobie, że tworzysz złożony portal, w którym z reguły na stronach znajduje się kilka bloków, a każdy z nich może zawierać osobną aplikację.

Natrafiamy tu na dwie trudności:

*Chciałbym, żeby lista wiadomości pojawiała się w konkretnej części strony, a Ty już znalazłeś na to dobre miejsce.
Problem w tym, że trzeba uruchomić komendę $inbox->toPage() dokładnie w momencie, który odpowiadałby pozycji listy wiadomości na stronie. Jeśli będziemy chcieli zmienić położenie tej listy, będziemy musieli wejść w kod, ale nie jest dobrze w tym celu ciągle zmieniać ramkę portalową. Najlepszym rozwiązaniem byłoby wyprowadzenie komunikatów w postaci osobnego modułu, o którym wiemy tylko, że trzeba go podłączyć do frameworka.
Oznacza to, że uwolnij się od ścisłej kolejności uruchamiania modułów. Rzeczywiście, skoro wynik działania Inboxa nie zależy od działania systemu (na tym etapie mamy już wszystkie dane w sesji), to po co ta dodatkowa złożoność?
* Aby zachować wygląd (projekt) listy wiadomości, należy zadbać o kod HTML, który jest zakodowany na stałe w metodach toPage() klas Message i Inbox. Zazwyczaj, aby zmienić projekt, będziesz musiał zmienić kod PHP.

Aby spróbować rozwiązać pierwszy problem, możesz utworzyć bufor przechowujący wynik działania skrzynki odbiorczej.

Być może nadal będziemy mieli kilka podobnych (do Inboksa) rzeczy i musimy stworzyć system buforów. Aby nie mylić, czyje jest czyje wyjście, prawdopodobnie przejdziemy do nazywania buforów. Zapiszemy gdzieś kolejność, według której powinny być wyprowadzane bufory - najlepiej w zewnętrznym pliku, aby ułatwić zmiany.

Ta próba rozwiązania już podsuwa nam pomysł wykorzystania XML jako sposobu przechowywania danych pośrednich. Użycie stylów XSLT pomoże rozwiązać drugi problem.

Nie będę się rozwodzić nad tym, czym jest XML i czym jest XSLT. Jeśli nie jesteś zaznajomiony z tymi rzeczami, dobrym miejscem do rozpoczęcia poszukiwań będzie zvon.org.

Pomysł polega na tym, aby w metodach toPage() wygenerować nie kod HTML, ale strukturę XML. Dokument strony zostanie utworzony jako string z kodem XML (będzie pełnił rolę „bufora”), a na ostatnim etapie skryptu skorzystamy z transformacji XSL.

Najpierw wyobraźmy sobie, jaki powinien być wynik głównej części kodu.

minuta 57 drugie: 45

Co to jest, dość łatwo zgadnąć - dwie wiadomości i formularz. Należy pamiętać, że skrypt PHP wystarczy przygotować taki ciąg znaków - jest to bardzo proste. Co więcej, kolejność głównych tagów jest nieistotna - Możesz umieścić go np. na początku, bo będzie to wygodne dla programisty. Jak to wdrożyć. Możesz, bez zmiany czegokolwiek, użyć buforowania danych wyjściowych, wyprowadzić plik XML zamiast kodu HTML, a na koniec po prostu przechwycić dane wyjściowe w postaci ciągu znaków. Ale wtedy stracimy elastyczność - na przykład czasami chcesz wyprowadzić informacje debugowania bezpośrednio na stronę (za pomocą echa). Jednocześnie programiści PHP pracują nad modułem DOM, który oferuje bardziej zaawansowany sposób tworzenia i przekazywania dokumentów w postaci drzewa. Jeśli będziemy chcieli zaimplementować DOM, będziemy musieli przeprojektować całą aplikację, zmieniając wyjście ciągów znaków na tworzenie elementów DOM. Dlatego wolę przechowywać reprezentację XML obiektów w samych obiektach, sekwencyjnie składając wspólny dokument XML. Nie jest to takie trudne, wymaga jedynie niewielkiej modyfikacji. Zobaczysz, że technika ta nie jest ściśle powiązana z konkretnym sposobem przechowywania danych XML, co pozwoli Ci przy niewielkim wysiłku przejść na korzystanie z modelu DOM. Przede wszystkim zauważ, że każdy z naszych obiektów posiada metodę toPage(). To podobieństwo powinno skłonić nas do zastanowienia się nad wprowadzeniem nowej wspólnej klasy nadrzędnej. Niech każda klasa, która może tworzyć fragmenty dokumentu XML dla strony, dziedziczy po klasie, która zajmie się reprezentacją obiektu XML. Nazwijmy to wyjściowym.

class Outputable ( /** * Kontener XML (string). */ var $output = ""; /** * Podaj zawartość kontenera i wyczyść kontener. * * @return ciąg znaków z danymi XML */ funkcja getOutput () ( $ out = $this->output; $this->output = ""; return $out; ) /** * Dodaj część do zawartości kontenera. * * @param string ciąg znaków do dodania * / funkcja appendOutput($string) ( $this ->output .= $string . "n"; ) /** * Metoda „Abstrakcyjna”. */ funkcja toPage() ( ) )

Metoda toPage() jest pusta - w tym przypadku jest potrzebna jako wskaźnik tego, jak zewnętrzne klasy „matrioszki” powinny komunikować się z klasą wewnętrzną. Moglibyśmy jednak zaproponować tutaj domyślną implementację, gdybyśmy zauważyli, że istnieje wiele obiektów, które wyświetlają się na stronie w ten sam sposób.

Klasy Message i Inbox ulegną niewielkim zmianom - powinny teraz dziedziczyć po Outputable, zmienią się także metody toPage()
Wiadomość.php

class Wiadomość rozciąga się na wyjściu ( /** * Treść wiadomości. */ var $content; /** * Konstruktor inicjujący tekst wiadomości. * * @param content treść wiadomości */ funkcja Wiadomość($treść) ( $this->content = $content; ) /** * Napisz wiadomość do sesji */ funkcja send() ( $_SESSION["session_messages"] = $this->content; ) /** * Wyprowadź wiadomość na stronę. * / funkcja toPage() ( $this->appendOutput(" „.$to->treść.”"); } }

class Inbox Extends Outputable ( /** * Tablica odebranych wiadomości. */ var $messages = array(); /** * W konstruktorze odbieramy wszystkie otrzymane wiadomości * i usuwamy je z sesji. */ funkcja Inbox( ) ( if (is_array ($_SESSION["session_messages"])) ( $messages = $_SESSION["session_messages"]; $co = sizeof($messages); for ($i = 0; $i< $co; $i++) { $this->wiadomości = nowa wiadomość($wiadomości[$i]); ) ) /* wyczyść tablicę komunikatów */ $_SESSION["session_messages"] = array(); ) /** * Wyświetla zawartość skrzynki odbiorczej na stronie. */ funkcja toPage() ( $co = sizeof($this->messages); $this->appendOutput(" "); dla ($i = 0; $i< $co; $i++) { $this->wiadomości[$i]->toPage(); $this->appendOutput($this->messages[$i]->getOutput()); ) $this->appendOutput(""); } }

Zmieniła się metoda wyprowadzania - teraz zamiast bezpośrednio wyprowadzać na stronę, zewnętrzna reprezentacja jest na razie przechowywana w Outputable, który „znajduje się” w każdym z obiektów. Metoda appendOutput() zastępuje konstrukcję echo(). Aby uzyskać wynik obiektu, używana jest metoda getOutput().

Zobaczmy teraz, jaka jest część kodu klienta, co rozwiąże ten sam problem, co poprzednio.
indeks.php

wysłać(); /* bieżąca sekunda */ $msg_sec = nowa wiadomość("sekunda: " .data("s")); $msg_sec->wyślij(); /* przekierowanie do siebie */ header("lokalizacja:"); Wyjście; ) else ( /* przygotowanie listy wiadomości w formacie XML */ $inbox = new Inbox(); $inbox->toPage(); $global_content->appendOutput($inbox->getOutput()); ) $global_content- >dołączWyjście („ "); $xml_string = $global_content->getOutput(); $xh = xslt_create(); $xarg = array(); /* nagłówek dokumentu XML */ $xarg["xml"] = ""."n"; /* treść dokumentu XML */ $xarg["xml"] .= " ". $xml_string. ""; /* szablon XSL */ $xarg["xsl"] = implode("", file("style.xsl")); /* wyświetlenie kodu HTML - wynik transformacji XSL */ echo xslt_process($ xh , "arg:xml", "arg:xsl", NULL, $xarg); /* wyjściowe źródło XML (debugowanie) */ echo "


" .htmlspecialchars($xml_string) ."
"; ?>

Główną innowacją jest obiekt $global_content, którego nazwa mówi sama za siebie. W tym przypadku należy ona do klasy Outputable; w rzeczywistych zadaniach prawdopodobnie utworzyłbyś osobną klasę dla zawartości strony.

Jeśli przyjrzysz się uważnie, zawartość skryptu praktycznie się nie zmieniła - ta sama skrzynka odbiorcza, ta sama funkcja toPage(). Dodano instrukcję wyświetlającą zawartość listy wiadomości w treści strony. Dla urozmaicenia generowane są teraz dwie wiadomości.

Aby zobaczyć wynik wystarczy przygotować szablon XSL.
styl.xsl

Przykład XSLT

wiadomość

Co osiągnęliśmy?

Przede wszystkim można z większą pewnością podejmować się skomplikowanych projektów – zapewniona jest realna niezależność modułów. Kolejność umieszczania wyników na stronie jest teraz kontrolowana za pomocą zewnętrznego szablonu XSL i nie jest uzależniona od kolejności uruchamiania modułów.

W projekcie można zastosować dowolny moduł, który w wyniku swojej pracy generuje dane XML. Swoją drogą to jedna z przewag nad silnikami szablonowymi, w których tworzenie danych polega na sekwencji wywołań metod (przypisanie itp.) konkretnego silnika, dla którego nie ma wspólnego standardu.

Kolejną zaletą jest łatwość debugowania. Jeśli uruchomisz skrypt, zauważysz, że każda strona zawiera dane wyjściowe debugowania — prototyp XML, który znacznie upraszcza debugowanie aplikacji.

Kolejną rzeczą, o której musisz pomyśleć, jest tworzenie obiektów wiadomości. Nie zawsze wygodnie jest używać new bezpośrednio w kodzie klienta. Ale być może jest to temat na osobny artykuł.

Na koniec galop o perspektywach:

* Wyskakujące okna z listą ważnych wiadomości
* „strony nadawców” i „strony docelowe” w wiadomościach
* rejestrowanie komunikatów w bazie danych
* przycisk „pokaż historię moich działań”
* analiza statystyczna działań użytkowników w ramach sesji
* „inteligentni asystenci” w aplikacjach webowych

    Być samowolnym, być samowolnym, być samowolnym, być niekompetentnym. (potoczny). Działać arbitralnie, zachowywać się arbitralnie. Słownik objaśniający Uszakowa. D.N. Uszakow. 1935 1940... Słownik wyjaśniający Uszakowa

    BĄDŹ SAMOWOLNY, och, och; niedoskonały (potoczny). Działaj arbitralnie. Słownik objaśniający Ożegowa. SI. Ozhegov, N.Yu. Szwedowa. 1949 1992… Słownik wyjaśniający Ożegowa

    Niesow. niepereh. rozkład Rób co chcesz, według swojego kaprysu. Słownik wyjaśniający Efraima. T. F. Efremova. 2000... Nowoczesny słownik objaśniający języka rosyjskiego autorstwa Efremowej

    Samowolny, samowolny, samowolny, samowolny, samowolny, samowolny, samowolny, samowolny, samowolny, samowolny, samowolny, samowolny, samowolny z własnej woli, z własnej woli, z własnej woli, ... ... Formy słów

    działać bez pozwolenia- być kłamliwym, aj, aj... Słownik ortografii rosyjskiej

    działać bez pozwolenia- (ja), leniuchuję, piję herbatę, piję herbatę... Słownik pisowni języka rosyjskiego

    Aj, tak; nsv. Razg. Postępować tak, jak chcesz, według własnego uznania, bez pytania kogokolwiek o pozwolenie. S. odwiedza. S. w pracy. Rób swoje w domu. ◁ Samowola, ja; Poślubić Bez samowoly, proszę, inaczej cię zwolnię! ... słownik encyklopedyczny

    działać bez pozwolenia- och, och; nsv.; rozkład Zobacz też samowola Działać według własnego pragnienia, według własnego kaprysu, nie pytając nikogo o pozwolenie. Samovo / lenistwo na imprezie. Samovo/leniwy w pracy. Rób swoje w domu... Słownik wielu wyrażeń