Front-end a back-end, czyli jak wystylizować tekst w PHP

Po lewej serwer z logo PHP, po prawej ekran, nad nimi strzałka wskazująca z serwera na ekran

Czasem zdarza mi się widzieć pytania typu:

Tutaj przez echo wyświetlam tekst. Co zrobić, aby był podkreślony?

albo:

W PHP pobieram dane z bazy i wyświetlam je w formie tabeli, jak mogę ją wystylizować?

lub nieco bardziej skomplikowane:

Potrzebuję, aby w JavaScript odczytać zmienną z PHP, w jaki sposób to zrobić?

TL;DR to nie jest sprawa PHP. Po stronie PHP możemy po prostu zapisać, aby wygenerował odpowiedni kod HTML/CSS/JS, który później da efekt, jakiego oczekujemy.

Na początek należy wyjaśnić, że PHP jest językiem backendowym. Jest to takie trochę zaplecze strony, które odpowiada za różnego rodzaju akcje niewidoczne bezpośrednio dla użytkownika. Jego kod jest wykonywany przez specjalny interpreter na serwerze. Bez dostępu do źródeł nie da się go nawet podejrzeć. Natomiast języki jak HTML, CSS czy JavaScript to front-end - definicja struktury strony, wyglądu, interakcji z użytkownikiem. Kod we wspomnianych językach dostaje jawnie Twoja przeglądarka internetowa i wykonuje go po swojej stronie. Są to więc dwie niezależne części witryny.

Kod pisany w JavaScript może również służyć za back-end! Dzięki środowisku Node.js z powodzeniem język ten jest używany po stronie serwerowej i nie tylko. W tym wpisie skupimy się jednak na jego frontendowej części.

Znamy już różnicę między językami, teraz wypadałoby powiedzieć co - w bardzo dużym uproszczeniu - dzieje się, gdy próbujesz na przykład wejść na tego bloga:

  1. Wpisujesz adres/klikasz link w swojej przeglądarce internetowej.
  2. Twoja przeglądarka (klient) wysyła zapytanie do mojego serwera: Mój człowiek chce zobaczyć co jest pod adresem waluk.pl/blog.
  3. Mój serwer (komputer) z zainstalowanym odpowiednim oprogramowaniem serwera www (może to być Apache, Nginx lub inne) przyjmuje to zapytanie, obsługuje je w jakiś sposób i następnie zwraca odpowiedź: Ok, rozumiem co z tym zrobić, masz tutaj moją odpowiedź.
  4. Przeglądarka otrzymuje odpowiedź, obsługuje ją po swojej stronie i wyświetla Tobie.

Tak naprawdę w punkcie 2. przeglądarka nie wie, co dostanie w odpowiedzi. Z kolei w kroku 3. to serwer decyduje co i skąd zwróci przeglądarce. A co i skąd może? To już zależy od jego konfiguracji. W standardowym wariancie serwer www po prostu szuka pliku o podanej przez przeglądarkę nazwie. Jest ustawiony na przykład: dla domeny waluk.pl szukaj plików w katalogu /var/www (albo dla XAMPPa - szukaj w katalogu C:\xampp\htdocs). Dostał od przeglądarki zapytanie na adres waluk.pl/blog/post.html? No dobra, w takim razie sprawdza, czy ma plik /var/www/blog/post.html. Jak jest, to go zwraca, jak nie to generuje jakiś komunikat o błędzie. Jednak można skonfigurować serwer tak, aby po otrzymaniu zapytania powiedział: Dobra, dla tego adresu muszę uruchomić plik /var/www/index.php w interpreterze PHP i dać klientowi (przeglądarce) to, co zwróci mi PHP. Przeglądarka finalnie nie wie, co dokładnie się tam zadziało, dostaje tylko odpowiedź - wynik.

Wróćmy więc do sedna pytań z początku. Myślę, że jeśli zrobisz plik index.html i w nim umieścisz kawałek kodu:

<p>To jest moja świetna strona.</p>

to rozumiesz, że przeglądarka dostanie taki oto kod i pokaże Ci ten tekst. Nie jest to wielkie zaskoczenie.

Identyczna sytuacja jest z kodem, który przeszedł przez interpreter PHP. Jeśli finalnie do przeglądarki trafi powyższy kod, to nie ma znaczenia jak PHP (czy inny język backendowy) go wygenerował. Możesz więc zrobić tak:

<?php
echo '<p>To jest moja świetna strona.</p>';

…albo też tak:

<?php
$strongText = 'świetna strona';
echo '<p>To jest moja ';
echo $strongText;
echo '.</p>';

Efekt nadal będzie ten sam. Do przeglądarki trafi taki kod jak ze zwykłego pliku index.html.

Jak więc podkreślić tekst w PHP? Cóż… tak samo, jak i bez PHP. Najlepiej dodać odpowiednią klasę CSS, tak jak się to deklaruje w HTML, której później nadasz odpowiednie style. Z punktu widzenia PHP użycie stylu inline czy znacznika <u> jednak także nie będzie problemem, dopóki nie spowoduje błędu składni. Można zrobić:

<?php
echo '<p class="text">To jest tekst</p>';

aby do przeglądarki trafiło <p class="text">To jest tekst</p>, ale można także:

<?php
echo '<bla bla=bla bla bla">To jest tekst />';

i wtedy dokładnie taki kod trafi do przeglądarki. Co ona z tym zrobi i czy ten kod w zapisie HTML jest poprawny, to już nie jest problem PHP. On w tym momencie po prostu zwrócił jakiś tekst, w gestii przeglądarki jest, aby sobie z tym coś zrobiła.

Rzecz jasna, przeważnie sytuacje są bardziej skomplikowane. Kod HTML generowany jest przez PHP na podstawie różnych warunków. Serwer jest konfigurowany na różne opcje, na przykład, aby najpierw sprawdził, czy dany plik istnieje na dysku, bo często PHP nie przetwarza wszystkiego. Jeśli mamy na serwerze www zwykły obrazek, to przeważnie nie za bardzo jest sens, aby go wysyłał do PHP - po prostu serwer od odeśle go przeglądarce. Jednak taka potrzeba może się pojawić przykładowo, gdy obrazki ma móc pobrać wyłącznie osoba zalogowana, a sesjami zarządza PHP. To wszystko jest kwestią konfiguracji. Powinieneś jednak z tego wpisu zrozumieć, że PHP może tylko decydować o tym, co wygeneruje po swojej stronie, ale nie interpretuje tego jako kod HTML, tylko jako tekstową odpowiedź.

Zmienna PHP w JavaScript?

Mam wrażenie, że jeszcze częściej pojawia się problem przekazania wartości z PHP do JS, również przez niezrozumienie działania.

Ktoś próbuje zrobić coś takiego:

<?php
$text = 'Tekst';
?>

console.log($text);

…co oczywiście nie może się udać, bo jak już wiemy, JS wykona się dopiero w przeglądarce. Najpierw na serwerze uruchomi się interpreter PHP, będzie miał zmienną $text, z którą nic się nie zadzieje, po czym przeglądarka dostanie w odpowiedzi tylko, że ma wykonać console.log($text);. To rzecz jasna nie będzie poprawne, $text nie będzie znane w JavaScripcie.

Jeśli bardzo potrzebne jest przekazanie wartości w taki sposób, to można zrobić przykładowo:

<?php
$text = 'Tekst';
echo 'const text = "' . $text . '"';
?>

console.log(text);

Nie jest to najpiękniejsza opcja, ale będzie działać - przeglądarka dostanie do wykonania kod:

const text = "Tekst";

console.log(text);

W tej sytuacji PHP wypisał więc kod JS tworzący zmienną z daną wartością. Przy okazji zwróć uwagę na dodatkowe cudzysłowy - apostrofy przerywają ciąg PHP, a cudzysłowy są już wewnątrz niego i trafią do finalnego wyjścia. Oczywiście można to także zapisać przy użyciu interpolacji, z użyciem cudzysłowów.

Technicznie nic nie stoi na przeszkodzie, aby PHP zwracał tak cały kod JavaScript, budował wielkie pliki i do nich wstawiał potrzebne wartości. W praktyce to byłoby bardzo nieczytelne i przeważnie się nie uda, bo potrzebne mogą być wartości pobrane skądś na bieżąco. Preferowanym rozwiązaniem tego problemu jest najczęściej użycie Ajaxa - wysłanie w tle przez przeglądarkę kolejnego zapytania do serwera. PHP nie wie wtedy o tym, że użytkownik już patrzy na stronę, nie podstawi w żaden czarodziejski sposób tej zmiennej do już istniejącego kodu HTML, a tylko odpowie na osobne zapytanie.

Może to wyglądać tak:

  1. Przeglądarka (klient) wysyła zapytanie pod adres waluk.pl/blog.
  2. Na serwerze www uruchamia się interpreter PHP, który zwraca kod HTML podstawowej strony z 10 pierwszymi wpisami.
  3. Przeglądarka otrzymuje odpowiedź i w kodzie HTML ma informacje, aby dołączyć skrypt JS, który na przykład po kliknięciu przycisku na stronie ma pobrać następne 10 postów.
  4. W momencie wciśnięcia przycisku przeglądarka Ajaxem w tle wysyła kolejne, niezależne zapytanie do serwera www pod inny adres, niech to będzie waluk.pl/posts. Dodatkowo wskazuje nr strony, aby serwer wiedział, od którego posta należy zwrócić kolejne.
  5. Na serwerze uruchamia się interpreter PHP, przygotowuje listę postów w formacie np. JSON, zwraca w odpowiedzi, a JavaScript w odpowiedni sposób umieszcza je na już otwartej stronie.

Żadna zmienna z PHP nie „przeskoczyła” magicznie do JS czy HTML. To osobne byty, które się ze sobą w pewien sposób skomunikowały i wymieniły dane.

HTML w PHP

Warto jeszcze powiedzieć, że na dłuższą metę mieszanie kodu HTML (lub innych języków frontendowych) z PHP gdzieś wewnątrz całej aplikacji nie będzie dobre. Bynajmniej nie chodzi o samą składnię jednego czy drugiego, a o to, że w aplikacji najczęściej trzeba wykonać różne akcje i dopiero na końcu przygotować jakąś odpowiedź. Mieszając to wszystko między sobą, piszemy kod, który będzie bardzo nieczytelny. Nazywane jest to czasem nawet pojęciem spaghetti code, ponieważ jest tak „pokręcone” i zawiłe jak wspomniany makaron…

Makaron spaghetti

Rozwiązaniem na to jest separacja logiki od widoków. Przygotuj osobno kod, który w potrzebny sposób wygeneruje czy dostosuje HTML, a osobno wykonaj jakąś logikę (zapisanie danych do bazy, zalogowanie użytkownika i podobne). Przekaż tylko potrzebne rzeczy z logiki do widoku.

Innym, ładniejszym rozwiązaniem są systemy szablonów. Mamy kilka znanych gotowych rozwiązań, które wystarczy zainstalować i używać. Są one często zintegrowane z frameworkami czy innymi rozwiązaniami.

  • Twig - domyślnie używany na przykład w Symfony
  • Blade - z Laravela
  • Smarty

Nadal w takich plikach pojawią się jakieś warunki, pętle czy inne elementy logiki, ale w tym momencie zostaną one użyte już tylko do wygenerowania samej prezentacji. Dość proste szablony można zobaczyć nawet w kodzie mojego bloga, który jest napisany z użyciem Symfony i Twiga.


Mam nadzieję, że dość jasno, choć z dużymi uproszczeniami, wyjaśniłem ten temat. Czy rola PHP w odniesieniu do kodu HTML jest dla Ciebie zrozumiała?

Zdjęcie spaghetti: Pixabay

Komentarze