Wideokursy #2: Kurs PHP Mirosława Zelenta

Zwykle nie mam w zwyczaju wracać do rzeczy, które już oceniłem, a które nie zmieniły się znacząco od tamtego czasu. Tym jednak razem postanowiłem zrobić wyjątek i ponownie przyjrzę się wideokursom pana Mirosława Zelenta, a dokładnie – 3. odcinkowi kursu PHP.


Przygotujcie się na długi wpis (bo to też i bardzo długi filmik – aż 2 godziny!) i ciut inny niż pozostałe…

  • Zacznijmy od samej długości. 2 godziny to jednak zdecydowanie za długo, zwłaszcza na filmiki przekazujące dużą dawkę wiedzy. Attention span kogokolwiek w przypadku takich materiałów jest o wiele mniejszy – i mogę to powiedzieć także z własnego doświadczenia. Nie bez powodu nawet wykłady akademickie trwają tylko 90 minut, a i tak po 60 mało kto kontaktuje… Dlatego myślę, że tego typu filmiki lepiej podzielić na 2.
  • 4:30 – podkatalogi na serwerze lubią być kłopotliwe. Osobiście poświęciłbym na początku jeden odcinek bardzo solidnej konfiguracji XAMPPa, gdzie można omówić tworzenie virtual hostów. To pozwoli nam na tworzenie oddzielnych projektów, które nie będą w żaden sposób na siebie wpływać (przy podkatalogach można mieć spore problemy z sesjami czy ciastkami). Idealnie byłoby omówić Vagranta i/lub Dockera, ale nie przesadzajmy – nie ten level. Natomiast virtual hosts są wręcz stworzone do takich rzeczy i warto tę technikę przedstawić.

    Mechanizm virtual hosts jest bardzo prosty, zarówno w działaniu, jak i omawianiu. Wystarczy skopiować już istniejący plik Apache’a i zmienić raptem dyrektywę ServerName – tyle. Następnie trzeba taką samą nazwę dodać do naszego systemowego pliku hosts i (jeśli korzystamy z Windowsa) opróżnić cache DNS-a. Cały proces trwa w porywach 5 minut, a dostarcza o wiele większej swobody niż zaproponowane rozwiązanie z podkatalogami. Dzięki niemu można choćby konfigurować całkowicie inaczej poszczególne strony (np. inna wersja PHP).

  • 4:45 – tu taka mała dygresja: lepiej używać kodowań z rodziny utf8_*_mb4, gdyż są bardziej zgodne ze standardem Unicode. Więcej info można znaleźć na stronie phpbestpractices.org.
  • 5:28 – i znów kolejna dygresja: nazwy zmiennych mimo wszystko powinny być po angielsku. Rozumiem, że w przypadku nauki polskie nazwy zmiennych są lepsze, ale angielskie są standardem – co prawda nie narzuconym, ale tzw. de facto standardem, z powodu swej popularności. Zatem lepiej od razu wpajać nawyk pisania po angielsku.
  • Inną dygresją w tym miejscu powinny być systemy szablonów. A czemu, to najlepiej wyjaśnia porneL.

    Prawda jest taka, że obecnie PHP jest wykorzystywany do skomplikowanych architektonicznie aplikacji internetowych, w których praktycznie odchodzi się od tradycyjnego modelu aplikacji internetowej (czyli skryptu na serwerze, który wszystko ogarnia). Dzisiaj tworzy się bardziej skomplikowane architektury, w których często dodatkowo jest jakieś API. Tym sposobem użytkownik komunikuje się z naszym serwerem, a on – z serwerem API. To przesunięcie architektoniczne sprawia, że konieczne stało się dostosowanie samych aplikacji internetowych do tych zmian. I tutaj pojawia się magiczne słówko, które w świecie Uniksa znano od zawsze, a które do webdevu zawędrowało całkiem niedawno: modularyzacja. To od razu pociąga za sobą enkapsulację, czyli prosty fakt, że każdy moduł jest całkowicie niezależny i samowystarczalny. A przynajmniej powinien – dla swojego i aplikacji dobra.

    Tego typu myślenie pociąga za sobą daleko idące konsekwencje. Modularność wymusza zmiany w całej aplikacji. Jedną z tych zmian jest wydzielenie logiki do sensownych modułów (czyli, w przypadku PHP, de facto klas), a tym samym: odseparowanie jej od sposobu prezentacji treści. Osobiście, gdybym tworzył kurs PHP, takie założenie oddzielenia logiki od prezentacji byłoby najważniejszym punktem 1. lekcji i dążyłbym niezmiennie do tego, by jak najszybciej wpoić tego typu zasadę moim uczniom.

    Czemu niemieszanie wartsw jest całkowicie fundamentalną praktyką, opisałem w swoim artykule o Progressive Enhancement. Co prawda dotyka on sfery frontendu, lecz dokładnie te same zasady obowiązują też w backendzie (gdzie są nawet bardziej istotne!).

  • Kolejna dygresja: na temat semantyki HTML-a wypowiedziałem się dostatecznie dużo w moim poprzednim artykule na temat wideokursów MZ. Tutaj, niestety, nic się nie zmieniło. I ponownie – semantyka jest podstawą jeśli chodzi o HTML. Łączy się bowiem bezpośrednio z kwestiami dostępności i użyteczności.
  • 6:25 – a tutaj mamy kolejny powód, dla którego system szablonów to konieczność: redundancja kodu, związana z kopiowaniem kodu HTML do kolejnego pliku PHP. Wystarczy pomyśleć co by się stało, gdyby nagle ktoś zadecydował (i oby to nie był klient!), że zmieni się Bootstrapa na inny framework. Przy dużej stronie to byłoby syzyfowe zajęcie. A tak wystarczy zmienić szablon i już.
  • 6:52 – jest to złe z punktu widzenia UX! Użytkownik jest przyzwyczajony do tego, że ma tylko jedno konto w danym serwisie. Jeśli nagle wchodzi na stronę i widzi, że może się zarejestrować, to… po prostu zgłupieje. Większość osób prawdopodobnie od razu spróbuje założyć konto i będzie jedynie wkurzona, gdy okaże się, że ktoś już użył jej nicku (i mogę się założyć, że o wiele mniej osób sprawdzi czy nie są przypadkiem zalogowani).

    Inną kwestią jest to, że w przypadku gier przeglądarkowych tego typu działanie to proszenie się o kłopoty. Multikonta przesyłające sobie nawzajem surowce to raczej nie to, co chcemy oglądać jako administratorzy.

    Natomiast nie można zakładać, że użytkownik zawsze trafi na stronę główną, gdzie odpowiednie przekierowanie jest! Strony WWW są przykładem hipertekstu, zatem nieuporządkowanego zbioru leksji. Tym samym strona główna jest tylko konwencją UI, nie zaś – faktycznym tworem. Wystarczy, że użytkownik wyszuka naszą stronę w historii i kliknie. Nie mamy żadnej gwarancji, że tym samym trafi na stronę główną. Dokładniej omówiłem to przy okazji omawiania nagłówków na stronie Lexy.

  • 7:15 – w przypadku tytułów stron należy najpierw podać tytuł podstrony, a dopiero później, opcjonalnie, tytuł całej witryny. Ma to duże konsekwencje jeśli chodzi o dostępność i użyteczność. Wystarczy sobie posłuchać w jaki sposób czytnik JAWS czyta tytuły stron, by zrozumieć, że jest to naprawdę ważne.
  • 7:46 – tego typu praktyka, mimo że dozwolona przez specyfikację HTML5, jest naganna. form jest deklaratywnym sposobem tworzenia żądań HTTP, a one wymagają URI. Dla zachowania spójności i czytelności ten atrybut powinien tam być.
  • 8:42 – tę jedną rzecz tłukę od lat, ale za każdym razem trzeba to powtarzać:

    KAŻDE POLE FORMULARZA, KTÓRE NIE JEST PRZYCISKIEM, MUSI MIEĆ TEKSTOWĄ ETYKIETĘ!!!

    KAŻÐE!! Największym błędem jest to, że specyfikacja HTML5 zezwala na niedołączanie tej etykiety. A etykieta ta jest niesamowicie istotna i jest kluczowym elementem dostępności na stronach WWW – być może nawet ważniejszym niźli dobrze skonstruowany [alt].

    Tłumaczyłem to już wielokrotnie, było omawiane na wszelkie możliwe sposoby, wspominają o tym wszyscy… A label jak nie było, tak nie ma… Naprawdę, wystarczy kilkanaście minut pracy z JAWS, żeby uzmysłowić sobie jak bardzo w ten sposób krzywdzimy osoby z niepełnosprawnością. Zresztą użyteczność też cierpi. Wszystko cierpi…

    Kwestiami dostępności zajmuję się na co dzień (to jest część mojej pracy) i ze zdziwieniem stwierdzam, że w przypadku polskiego web community świadomość tych kwestii jest przerażająco niska. To, co na Zachodzie jest całkowicie normalne, u nas zbywa się najczęściej śmiechem czy niezrozumieniem. Dlatego zasady WCAG powinny być biblią dla każdego webmastera.

  • 9:53 – od maili jest obecnie [type=email]. Warto stosować, bo załatwia nam od razu walidację po stronie klienta i dostarcza lepszego UX użytkownikom (np. wyświetla specjalną „e-mailową”, z małpą, klawiaturę na urządzeniach mobilnych).
  • 12:21 – bardzo miło, że pojawił się label dla checkboxa, ale… to nie wystarcza. Jego opis sugeruje, że jest on wyłącznie dodatkiem do użyteczności (zaznaczalna etykietka), co niestety jest zbyt dużym uproszczeniem…
  • 19:07 – akurat ostatnio toczyłem dyskusję na temat przycisków. Warto się zastanowić, czy na pewno chcemy w praktycznie wszystkich aspektach gorszy (i nie, wsparcie dla IE6 to nie zaleta) input[type=submit] od button.
  • 22:03 – zagadka: a co jeśli ktoś nie wysłał żądania naszym formularzem? Skrypt nie ma być ściśle związany z konkretnym interfejsem (a co jak dodamy kiedyś aplikację mobilną?), on po prostu ma odbierać żądania HTTP.

    Co więcej, algorytm wysyłania formularzy dokładnie określa jakie pola i pod jakimi warunkami są wysyłane. Dlatego próba stwierdzenia, czy formularz został wysłany na podstawie sprawdzenia istnienia konkretnego pola jest po prostu ułomna. Lepiej sprawdzić jakiej metody HTTP użył klient (specjalnie piszę „klient”, bo to nawet nie musi być przeglądarka!):

    if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
    	// mamy formularz
    }

    Tego typu sprawdzenia nie da się oszukać i robi dokładnie to, co chcemy (sprawdza, czy dane zostały przesłane odpowiednią metodą, a zatem – czy żądanie HTTP zostało sformułowane w sposób, w jaki zażyczyliśmy sobie deklarując to w kodzie HTML; isset natomiast sprawdza, czy dana rzecz została przesłana – co nie jest tym, co chcemy sprawdzić).

  • 23:29 – formularze nie muszą być przesyłane w całości, co jest zapisane w specyfikacji HTML5, w algorytmie, który podlinkowałem powyżej. Jakby ktoś nie wierzył, że ten algorytm działa: zaznaczone, ale wyłączone checkboxy nie są wysyłane.
  • 24:16 – nie do końca, bo isset zwróci fałsz też dla zmiennych, które zawierają null. isset sprawdza czy zmienna ma nadaną wartość (null zwraca fałsz, bo jest odpowiednikiem undefined w JS, czyli braku wartości). Puste pola formularza przesyłają się jako puste ciągi tekstowe – stąd isset działa poprawnie. Jaka jest zatem różnica między isset a empty? empty sprawdza, czy wartość danej zmiennej nie jest pusta, nie zaś – czy jest ustawiona.
  • 26:01 – częściej spotykaną praktyką w moim odczuciu jest tworzenie tablicy z błędami i sprawdzenie po przeprowadzeniu walidacji, czy tablica ta jest pusta. Jeśli tak, to znaczy, że wszystko jest ok. Jeśli nie, wyświetlamy odpowiednie błędy. Odpada nam zabawa z flagą.
  • 27:54strlen całkowicie nie działa przy czymkolwiek z UTF-8, dlatego też powinno się używać mb_strlen. Jest to jedna z dobrych praktyk.
  • 29:06 – akurat w tym wypadku można po prostu wygenerować formularz z tego, co przyszło nam POST-em (zwłaszcza, że nie przechodzimy do żadnego innego pliku!). Chyba nigdy nie miałem potrzeby używania sesji do generowania tego typu błędów.
  • 34:38 – tu aż się prosi, by powiedzieć: testy automatyczne! Chyba nie widziałem jeszcze w Polsce żadnego kursu, który by je omawiał choćby powierzchownie. A tego typu podejście do nauczania byłoby bardzo dobre. Im szybciej nauczy się developera testowania, tym szybciej jego kod stanie się mniej podatny na błędy i lepiej zaprojektowany.
  • 37:59 – tym sposobem dla nicku zawsze wyświetli się tylko jeden komunikat, co nie jest zbyt dobre z punktu widzenia UX (trzeba poprawiać 2 razy zamiast 1!). Zamiast tego warto albo wyświetlić oba komunikaty, albo przygotować taki komunikat błędu, który omawiałby wszystkie przypadki i dostarczał odpowiedniej pomocy użytownikowi.
  • 42:23 – z sanityzacją e-maili trzeba uważać. Z jednej strony usunie nam brzydactwa typu spacje, z drugiej: uwali poprawne maile IDN, np z ęą@gmail.com zrobi @gmail.com! Bardzo podobnie jest z walidacją maili, gdzie wszelkie maile ze znakami narodowymi są odrzucane jako niepoprawne. Ostatnio toczyłem dyskusję na ten temat i wygląda na to, że – na chwilę obecną – najsensowniejszym rozwiązaniem jest użycie funkcji idn_to_ascii.
  • 43:01 – ta lista nie uwzględnia standardu RFC6530, który zezwala na znaki narodowe w e-mailach. Co więcej: część domenowa zezwala także na adresy IP. Trzeba się nieźle napocić, żeby napisać dobrego regexa/walidatora dla maili i wiadomo to nie od dziś.
  • 47:42 – nie ma sensu ograniczać długości hasła; zwłaszcza, że obecnie mówi się o „wyrażeniach hasłowych”, które mogą mieć zdecydowanie więcej niż 20 znaków! Dla nas to nieistotne, bo funkcja hashująca zawsze zwraca określoną liczbę znaków.
  • 50:19 – osobiście uważam, że z punktu widzenia UX ten komunikat powinien być wyświetlany pod polem na powtórzenie hasła (bo w gruncie rzeczy to jego dotyczy błąd!).
  • 51:39 – ta bezkolizyjność to niestety pobożne życzenie… Czasami się zdarza, że dwa hasła wygenerują te same hashe. Na szczęście jest to rzadkie zdarzenie.
  • 57:16 – sól jest doklejana do hasła, nie hasha. Nie ma sensu doklejać jej do hasha. To, że jest widoczna na jego początku, to po prostu konwencja zapisu – Modular Crypt Format.
  • 1:24:18 – bardzo dobrze, że małkpę zastąpiono wyjątkami. Szkoda, że zrobiono to wyjątkowo źle…

    Nie powinno się rzucać całkowicie generycznymi wyjątkami! Sam PHP ma sporo wbudowanych typów wyjątków. Już tylko ich używając można napisać bardzo sensowną obsługę błędów z rozróżnianiem ich typów. Obecnie przedstawiony kod błędnie zakłada, że wszystkie wyjątki dotyczą obsługi bazy danych. W przypadku stosowania konkretnych rodzajów wyjątków można konstruować nawet stopniową obsługę wyjątków:

    try {
    	// Dziwny kod
    } catch ( NetException $e ) {
    	echo 'Coś z netem';
    } catch ( APIException $e ) {
    	echo 'Coś z API';
    } catch ( Exception $e ) {
    	echo 'Coś, ale nie wiem co…';
    }

    W tego typu kodzie od razu widzimy jaki błąd dostajemy i możemy dzięki temu odpowiednio pokierować dalej działaniami aplikacji.

    Co więcej, bardzo często blok try/catch używany jest do złapania i obsłużenia wyjątku w bardzo elegancki sposób. Niemniej coraz częściej błędy, które nie muszą być obsłużone, łapie się globalnie.

    I tak na sam koniec: moduł mysqli ma wbudowaną obsługę wyjątków. Wystarczy ją włączyć, wywołując przed połączeniem z bazą jedną funkcję:

    mysqli_report( MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT );

    Tym samym rzucanie własnych wyjątków jest niepotrzebne – mysqli samo to robi, nawet w przypadku połączenia!

  • 1:27:00 – nie musimy rzucać wyjątku, bo mysqli robi to za nas! W tym wypadku obsługiwany jest wyjątek rzucony przez sam konstruktor mysqli, nie zaś – ten, który zadeklarowano w kodzie. Jest on całkowicie redundantny i nie ma prawa pełnić swojej funkcji. Gdy dochodzi do błędu połączenia, on sam nie jest już wykonywany (wykonanie przechodzi do bloku catch). mysqli_report informuje mysqli o tym, jak ono ma raportować błędy, nie o tym jak my raportujemy błędy.
  • 1:28:53 – jeśli dane w zapytaniu pochodzą od użytkownika, używa się prepared statements. Kropka. To jedna z tych praktyk, z którymi po prostu się nie dyskutuje.

    Podkreślałem to wielokrotnie i jest to ogólnie znana dobra praktyka. Tylko tego typu rozwiązania – stosowane zawsze! – pozwalają nas uchronić przed SQL injection, zarówno 1., jak i 2. stopnia.

    Czemu prepared statements są tak dobre? W skrócie: oddzielają strukturę zapytania od danych (hej – to prawie jak logika i prezentacja w PHP!). Tym samym dane są przesyłane do serwera SQL oddzielnie niż zapytanie i sklejane bezpośrednio przez niego. To praktycznie uniemożliwia jakiekolwiek niepożądane działania i dodatkowo włącza możliwość ciekawych optymalizacji zapytań już po stronie samej bazy.

  • Przy okazji krótka dygresja: kod prawie zawsze powinien opierać się na abstrakcjach. Jeśli coś jest zbyt konkretne, to prawdopodobnie powinno być czymś opatulone. Tak jest też w przypadku obsługi baz danych. Gdybyśmy chcieli w tym momencie zmienić silnik bazy danych, musielibyśmy de facto przepisać cały skrypt i pozmieniać mysqli na moduł odpowiedni dla innej bazy. Z tego też względu standardem jest PDO, które dostarcza warstwy abstrakcji uzgadniającą implementacje poszczególnych relacyjnych baz danych. To minimalny poziom abstrakcji, jaki jest używany przy bazach danych. Żeby różnice między bazami zatrzeć praktycznie całkowicie, używa się jeszcze wyższych warstw abstrakcji, jak Doctrine czy Propel. Obecnie tak low-levelowe APIs jak mysqli widzi się praktycznie wyłącznie w… kursach. W rzeczywistym świecie stosowany jest co najmniej PDO i to na niego powinien być położony główny nacisk.
  • 1:32:17 – jeśli ustawi się poziom raportowania mysqli na MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT zamiast na MYSQLI_REPORT_STRICT, to wówczas wszystkie tego typu wyjątki są rzucane automatycznie.
  • Inna rzecz, że sprawdzanie unikalności e-maila i loginu, oprócz istnienia w kodzie, powinno mieć także odzwierciedlenie w strukturze danych – czyli odpowiednie pola powinny mieć klucz UNIQUE.

    Czy 3. odcinek kursu PHP jest odpowiedni do wprowadzenia takiego konceptu? Nie. Z prostej przyczyny: powinien się on ukazać w kursie MySQL. I to już w momencie projektowania bazy danych dla użytkowników! Bazy relacyjne indeksami i relacjami stoją i tego typu rzecz jest de facto podstawowa przy obcowaniu z bazami danych.

    Taki indeks chroni nas przed przypadkiem, gdy dane do bazy są wkładane także poza procesem rejestracji (np. ręcznie) i dlatego po prostu trzeba go mieć.

  • 1:42:00 – nie ukrywam, że to właśnie następująca tutaj wypowiedź nakłoniła mnie do napisania tego artykułu.

    Zrobię teraz coś, co na tym blogu (chyba) wcześniej mi się nie zdarzyło: trochę prywaty. Programowaniem dla Sieci zajmuję się od 10 lat, obecnie jest to też moja praca zarobkowa. Od roku jestem administratorem dość sporego forum webmasterskiego, a od 5 lat się na nim udzielam. Udzielam się też na kilku innych forach. Na co dzień rozmawiam z ludźmi, którzy dopiero zaczynają swoją przygodę z webdevem. Równocześnie na co dzień mam kontakt z ludźmi, którzy zjedli na tym swoje zęby. I widzę przepaść w sposobie myślenia pomiędzy jednymi i drugimi. Widzę to zarówno jako człowiek, który codziennie stara się pomagać ludziom na forach, jak i człowiek, który dzieli się z innymi swoją wiedzą.

    Nigdy nie negowałem, że nauka to proces. To dość oczywiste. Jednak nie można zapominać o specyfice technologii internetowych. One zmieniają się na pniu – żadna z nich nie jest stabilna. JS, który jest moim „prymarnym językiem”, nieustannie się zmienia. Co roku mają wychodzić nowe wersje. PHP też nagle przysiadł i coraz szybciej się rozwija. Web to niespokojny superwulkan, który często lubi wybuchać i topić w lawie wszystko to, co do tego czasu udało się wypracować. Tutaj dobre praktyki zmieniają się średnio co miesiąc. Nie ma tu miejsca na przestarzałe praktyki. Wszystko nieustannie brnie do przodu.

    Sieć dąży do tego, by jej ekosystem stał się jak najbardziej dojrzały. To oznacza, że technologie webowe stają się coraz bardziej abstrakcyjne. Wystarczy spojrzeć jak bardzo rozbuchane w tym względzie stały się Symfony czy Angular, gdzie abstrakcji jest tak dużo, że można się w niej utopić – i to bez szans na ratunek. Z jednej strony dostajemy dostęp do coraz niższych low-levelowych cudów, z drugiej – każdy od razu otaczany jest odpowiednią warstwą abstrakcji, by wszystko zawsze było SOLID-ne.

    To wszystko związane jest – co już wspominałem – ze zmianą paradygmatu architektonicznego Sieci. To, co od dawna było w „lepszych” językach, dotarło i do Sieci. I zaczyna ją mocno transformować. Gdy dzisiaj mówi się o JS, mówi się o małych, niezależnych modułach. Gdy mówi się o PHP – mówi się o potężnym, obiektowym języku. I to należy przyjąć do wiadomości.

    Jasne, pokazywanie starszych technik w ramach nauki jest dobre… w teorii. Mamy teraz hype na programowanie. Ludzie nie myślą, oni kopiują kod z tutoriali – często bardzo nieudolnie. Można spokojnie tłumaczyć, powoływać się na taksonomię Blooma, wyjaśniać, przekonywać… ale to po prostu nie działa. Ludzie chłoną wiedzę jak gąbka, zapominając ją później wycisnąć, by zrobić z niej coś sensownego. Z tego też względu nauczanie starszych praktyk w kontekście technologii webowych jest szkodliwe. Jeśli już takie praktyki się przekazuje, należy je przekazać w odpowiednim kontekście – obok, nie zaś zamiast, nowych.

    Dzisiaj Sieć to nie są proste strony, lecz aplikacje o bardzo skomplikowanej architekturze – zarówno na poziomie frontu, jak i backu. Dlatego tego typu kursy muszą poruszać się w sferze abstrakcji, przekazywać ogólniki, uczyć obiektowego myślenia. Bo w chwili, gdy stworzy się w nich jakikolwiek kod, mają obowiązek – dla dobra Sieci – stać się nieaktualnymi wówczas, gdy powstanie lepsza technika. I to nie jest dla nich ujma. Natomiast jest to wielka chluba dla Sieci, bo znów posunęła się naprzód.

    Jeśli zaakceptuje się przejście od tworzenia dokumentów do tworzenia aplikacji i fakt, że Sieć w końcu wydoroślała, wówczas dostrzeże się również, że pewne wzorce architektoniczne (jak np. oddzielenie logiki od prezentacji) sprawdzają się także w małej skali. I dlatego właśnie takie wzorce powinny być nauczane. I dopiero na nich można konstruować bardziej konkretne kursy – z zaznaczeniem, że należy dbać o ich aktualność. Bo w tej branży bardzo łatwo stać się anachronicznym dziadkiem, prawda YUI?

Może zabrzmię jak szalony idealista, ale większość mojej działalności w Sieci jest ukierunkowana na to, by ta Sieć stała się lepsza. Dlatego mam taką obsesję na punkcie semantyki i dostępności. Dlatego jak obłąkany powtarzam o modularności i komponentyzacji Sieci. Dlatego niczym szaleniec oddzielam logikę i prezentację w PHP. I czytam RFC, specyfikacje, PSR, blogi znawców…

Ale równocześnie wiem, że dbanie o Sieć wymaga, by ograniczać innych. By nie pozwalać im na popełnianie tych samych błędów, które ja sam popełniłem. By nie tłumaczyć łagodnie i wyjaśniać cierpliwie, ale strzelić w ryj, gdy jest potrzeba. Bo inaczej semantyczna, dostępna Sieć dla wszystkich stanie się już tylko piękną legendą.

I dlatego będę narzekał. Zawsze wtedy, gdy coś nie jest takie, jakie być powinno. Bo Sieć jest wspólnym dobrem, lecz mało kto wie jak naprawdę należy o nią dbać… Nowe pokolenie webdeveloperów trzeba właściwie wychować.

A do tego trzeba twardej ręki.

9 myśli na temat “Wideokursy #2: Kurs PHP Mirosława Zelenta”

  1. Świetny artykuł. Szczególnie jak czytałem ostatnie akapity to aż łezka się w oku zakręciła.
    Pozdrawiam i tak trzymaj.

  2. Chyba macie skopane tabowanie po formularzu dla komentarzy. Check out this ^.^

    A co do artka – lubię czytać artykuły, które nie dość, że bawią, to jeszcze stanowią kopalnię wiedzy praktycznej.

  3. Witam

    Ja bym chętnie zobaczył pod lupą jakikolwiek z kursów PHP, Javascript czy Jquery ze strony eduweb pl. Wszyscy je tak zachwalają, tyle „podobno” ludzi je zakupiło ale ciekawi mnie czy na pewno są takie dobre.

    Pozdrawiam

  4. „PHP też nagle przysiadł i coraz szybciej się rozwija. ” – To zdanie nieco brzmi jakby zatrzymał się i jednocześnie zaczął się rozwijać.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *