Jak powinien wyglądać dobry commit?

Dzisiejszy wpis będzie skierowany do osób zaczynających swoją przygodę z systemami kontroli wersji (VCS). Mimo że porady będą bazowane na systemie git, większość z nich można z powodzeniem zastosować także dla jego alternatyw.

Rozmiar commitu

Jest to rzecz, z którą - według moich obserwacji - początkujący mają największy problem. Nie istnieje bowiem idealna ilość zmian w jednym commicie, którą możemy się kierować za każdym razem. Myślę, że commit o dobrym rozmiarze najprościej jest zdefiniować słowem samodzielny. Co takiego mam przez to na myśli?

  • zmiany w commicie powinny stanowić działąjącą całość, nie powinno się commitować kodu, który generuje na przykład błąd parsera
  • commit powinien obejmować jedną funkcjonalność. Ponownie, nie da rady zdefiniować jak dużo obejmuje jedna "funkcjonalność". Spróbuj jednak postąpić w ten sposób - wyobraź sobie, że commit, który masz zaraz wyślesz, będzie musiał zostać cofnięty (np. komendą git revert). Czy robiąc to, pozbędziesz się tylko jednego kroku, czy też będziesz musiał w osobnym commicie powtórzyć część z dokonanych wcześniej zmian (które właśnie hipotetycznie cofnąłeś). Jeżeli zachodzi druga sytuacja, to commit jest za duży.

Opis commitu

Bądźmy szczerzy, każdy lubi czasem popuścić wodze fantacji wpisując wiadomość commitu. Najczęściej jest to danie upustu frustracji, która towarzyszyła tworzeniu danego kodu. Powstały nawet specjalne strony jak whatthecommit.com. Warto jednak poświęcić kilka sekund więcej na napisanie wiadomości commitu, aby w przyszłości zaoszczędzić swój czas.

Opis commitu jest wykorzystywany w bardzo wielu sytuacjach - komendach git log, git rebase, git blame, czy ich odpowiednikach w serwisach typu GitHub. Traktuj opis commitu tak, jakbyś musiał go przeczytać i szybko zrozumieć kilka dni później. Staraj się być zwięzłym i rzeczowym - jeżeli nie ze względu na siebie, to na współpracowników.

Kolejną sprawą jest możliwość podzielenia commitu na krótki opis główny i dłuższą (opcjonalną!), bardziej szczegółową część, która nie jest pokazywana w niektórych sytuacjach. Wspiera to oryginalny klient gita (np. komenda git log --abbrev-commit) i np. GitHub (w widoku listy commitów pokazywana jest tylko krótka wiadomość, a reszta rozwija się po kliknięciu). Git oddziela streszczony opis commitu od jego pełnej treści za pomocą jednej pustej linii.

Oto skrótowy, kontretny opis Twojego commitu

Tutaj możesz zawrzeć długi opis, w którym przykładowo omówisz przyczyny
wprowadzenia danej zmiany i jej konsekwencje dla projektu. Może być to
przydatne szczególnie dla Twoich współpracowników.

Na koniec kilka dodatkowych (częściowo subiektywnych, lecz popartych obserwacjami) zaleceń dotyczących formy samej wiadomości:

  • żadna z linii w opisie commita nie powinna przekraczać 72 znaków (konsola ma domyślnie 80 znaków szerokości)
  • rozpocznij opis od wielkiej litery
  • na końcu pierwszej linii commitu nie stawiaj kropki
  • użyj trybu rozkazującego (zwłaszcza w języku angielskim; powód - git używa takiego samego trybu dla wiadomości generowanych przez siebie, na przykład "Merge a from remote b")

Weryfikacja commitu

Przed zatwierdzeniem dowolnego commitu, przejrzyj go - najlepiej dwa razy. Służy do tego oczywiście diff, czyli wykaz wszystkich zmian poczynionych w ramach danego commmitu. Generalnie do jego wyświetlenia służy komenda git diff (trudne, prawda?), ale oczywiście jest haczyk. Domyślnie nie pokazuje ona zawartości plików właśnie dodanych do repozytorium, a jedynie zmiany w przestrzeni roboczej (przed wykonaniem git add).

Metodą uniwersalną jest wydanie komendy git add . (lub git add . --all dla gita 1.x - wszystko, aby uwzględnić też pliki właśnie usuwane z repozytorium) a następnie git diff --cached. Po tych dwóch poleceniach dostaniemy pełną listę zmian, zarówno w dodawanych, zmienianych, jak i usuwanych plikach - pozwala to zaoszczędzić naprawdę wielu pomyłek w kodzie.

Łączenie (squashowanie) commitów

Łączenie kilku commitów w jeden, zwłaszcza po ich wysłaniu do zdalnego repozytorium (origin), zaburza poniekąd historię zmian i może prowadzić do tego, że system kontroli wersji nie będzie spełniał swojej roli. Zachodzą jednak sytuacje, w których może być to przydatne, a nawet wymagane przez innych developerów. Najczęściej dzieje się tak w wypadku Pull Requestów lub ich odpowiedników z serwisów innych niż GitHub.

Powodem, dla którego w tej sytuacji możemy użyć squashowania (dosł. zgniatania) commitów jest zachodzący workflow. Zmiany są wykonywane w obrębie naszego własnego repozytorium (forka) i wysyłane jako propozycja zmian dla jakiegoś projektu. Bardzo często ludzie zarządzający tym projektem będą mieli do nas pewne uwagi i wskazówki, w związku z czym do Pull Requesta dołączają kolejne commity. Warto je na końcu połączyć, bo Pull Request z założenia powinien obejmować jedną funkcjonalność, a więc często być też jednym commitem (jak pisałem na początku artykułu). Kilka różnych metod squashowania commitów znajdziecie w tym wątku na SO.

Zakończenie

Mimo, że opisałem tutaj całkiem sporo założeń i może się wydawać, że teraz wysłanie dobrego commita miałoby zajmować wieczność i oznaczać sprawdzanie każdego punktu z listy, to nie ma czym się przejmować. Większość z wniosków wyciągniętych w artykule jest bardzo logiczna i nie powinna być dla Was niczym nowym, a reszta szybko wejdzie w nawyk. Należy brać poprawkę na dozę subiektywizmu zawartą w tym tekście.

WordPress Cleaner – optimize your database

Back in the old days I've written a very simple script to remove posts' revisions from WordPress database. It was published on my GitHub, but it was broken due to syntax error in SQL query... and it was a good thing because it might actually remove important content from your database.

And yet, the time has come. I sat down and rewrote whole script from scratch. Turned it into modular WordPress cleaner, improving performance of your installation by removing tons of garbage from your database. It is now able to remove following kinds of junk:

  • post revisions (disabled by default)
  • auto drafts
  • spam comments
  • unapproved comments
  • orphan commentmeta
  • orphan postmeta
  • transient options
  • akismet commentmeta

Look how the script performs on production database of my website (using default settings).

WordPress Cleaner

You can grab it from GitHub repository. Feedback and contributions are welcome!

What will PHP 7 bring us?

New major version of PHP is under active development since over a year (including non-public rewrite called phpng) and obviously number of changes still increases. Therefore, I have decided to point out most of important things we can expect.

For this article, I will split them between new features and actions aimed at improving language consistency and cleaning up some rubbish accumulated over the past years.

The name

Short explanation to begin with. The next version after PHP 5 will be PHP 7. The main reason is the fact that PHP 6 already existed and while it never reached stable state, there are many books and resources refering to its name. It was assumed that skipping this number will allow to avoid potential confusion.

Performance

The most notable change is huge speed improvement. Guys from Zend are doing awesome job refactoring Zend Engine and looking for new ways to make code execution faster. It results in even 50% boost in real-life applications, not in synthetic benchmarks.

New features

It should be noted that new major version almost certainly will not bring us highly-desired changes such as renaming functions to end with haystack, needle vs needle, haystack problem once and for all. While it is technically possible, PHP developers don't want to ruin their users' trust breaking too much BC and became another Python 3 (if you know what I mean).

OK, enough talking, let's get down to the facts:

  • Abstract Syntax Tree - this change is under the hood and don't have direct impact on userland code. However, it makes parsing code easier, more flexible and less error prone (it is obvious simplification of the subject, but you probably won't care about the details at this moment).
  • Null Coalesce Operator - new operator ?? (known from some other languages) is introduced. The easiest explanation would be $id = isset($_GET['id']) ? $_GET['id'] : 0; written as $id = $_GET['id'] ?? 0;. Check the original RFC for more details.
  • Unicode Codepoint Escape Syntax - introduces syntax to escape Unicode codepoint (e.g. \u{202E})
  • Closure::call() method has been added - it is a feature known from JavaScript (or rather ECMAScript), which allows to bind variables to closures at call-time
  • Error call to a member function of a non-object is now catchable
  • unserialize() allows to either completely prohibit restoring objects or restrict the objects being restored to a whitelist of objects

Cleanups

  • mysql_* functions are no longer available by default, because ext/mysql has been removed from core and will be moved to PECL
  • ext/ereg (ereg_* functions) has been removed and will be migrated to PECL as well
  • Uniform Variable Syntax - variable syntax in PHP 7 is more consistent and allows for more advanced expressions. This change introduces some backwards compatibility breaks in edge cases, but they can be avoided by using curly braces, so the code is parsed the same way in PHP 5 and 7. Click on the link to check real-life examples.
  • Some inconsistences in handling integers on different platforms are fixed (more details)
  • String support for list() has been removed as it has been introduced unintentionally and might cause unexpected results (more details)
  • Alternative PHP tags, namely <%, <%= (ASP tags) and <script language="php">, are removed
  • Support for multiple default clauses in switch has been removed
  • Support for comments indicated with # in INI files has been removed
  • $is_dst parameter of the mktime() and gmmktime() functions has been removed
  • Support for assigment of new by reference has been dropped (write $obj = new ClassName instead of $obj =& new ClassName)
  • e (eval) modifier for preg_replace() has been removed. preg_replace_callback() should be used instead
  • PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT driver option has been removed - more general PDO::ATTR_EMULATE_PREPARES should be used instead
  • CN_match and SNI_server_name stream context options are removed
  • Scoped calls of non-static methods from incompatible $this context are no longer supported (more details)
  • Support for string category names in setlocale() has been dropped (use LC_* constant instead of e.g. 'LC_ALL' string)
  • Support for unsafe CURL uploads has been removed
  • Following php.ini directives have been removed: iconv.input_encoding, iconv.output_encoding, iconv.internal_encoding, mbstring.http_input, mbstring.http_output, mbstring.internal_encoding and xsl.security_prefs
  • Following functions are removed: dl (only on fpm-fcgi SAPI), set_magic_quotes_runtime, magic_quotes_runtime, set_socket_blocking, mcrypt_generic_end, mcrypt_ecb, mcrypt_cbc, mcrypt_cfb, mcrypt_ofb, datefmt_set_timezone_id and IntlDateFormatter::setTimeZoneID

Conclusion

Personally, I find all changes mentioned above as a very good message for everyone interested in PHP development. More consistent language means less quirks to remember and allows to write code more effeciently.

Moreover, I think it's a great starting point for potential new features. Focusing on cleanup, internal and userland as well, is very important aspect, as the new major version is probably the only oportunity to do this in next about ten years.

Note: it is my first article written in English, so I would be very glad for being forgiving (in linguistic aspect, not meritorical, of course!) and pointing out eventual language mistakes.

Strony na Facebooku a kwestia jakości

Uprzedzam od razu, wpis szczególnie odkrywczy nie będzie. Łatwość tworzenia i promowania miejsc do dzielenia się swoją treścią ze światem powoduje, że zabierają się do tego zadania również osoby, nazwijmy to... mniej rozgarnięte. Tak było, jest i będzie, bo samemu portalowi na rękę jest generowanie jak największej ilości treści - o czym już pisałem - jej jakość nie ma wielkiego znaczenia.

Od pewnego czasu mam jednak wrażenie, że kilka zjawisk występuje na praktycznie każdym "fanpejdżu", a ponadto, nasila się. Ze swoich obserwacji mogę wymienić kilka zabiegów, które są powszechne i bardzo denerwują.

Czytaj dalej

Liczby nie kłamią

Od samego początku miałem założenie, że strona sobak.pl ma być moją wizytówką w sieci - całkiem logiczne i szczwane, nieprawdaż? ;) Aby jednak tak się stało, przydało by się prezentowała ona trochę danych o mojej osobie i była punktem wyjścia do dalszej eksploracji. Dlatego w dniu wczorajszym do Sobakowego Bloga dołączyła strona stats.sobak.pl. Jest to agregator kilku mniej lub bardziej interesujących statystyk związanych z moją działalnością w sieci. W chwili pisania tego skryptu pobiera i prezentuje w jednolity sposób dane pochodzące z tego bloga, a także serwisów Forumweb.pl, Wikipedia, PHP.net i Twitter.

Skrypt ma budowę modułową, aby w przyszłości łatwo móc rozszerzać go o integrację z większą ilością witryn. Cały kod źródłowy jest dostępny publicznie na Githubie. Sugestie poprawek lub pull requesty są mile widziane.

Co do samej treści serwisu - statystyki może niezbyt piękne, w paru miejscach wręcz żenujące (ah, ta aktywność na Twitterze...), jednak jednemu zaprzeczyć się nie da... liczby nie kłamią ;)

Wpis w portfolio dla tego projektu znajduje się w tym miejscu.

phpBB żyje i chyba ma się dobrze

Kto z was nie kojarzy phpBB? Myślę, że większość postawiła na nim swoje pierwsze forum. Skrypt swego czasu bardzo popularny, co w pewnym okresie było już dziwne, ze względu na jakość jego kodu. No właśnie... własne dziwaczne szablony budowane na czymś podobnym do komentarzy HTML, pluginy, które wymagają modyfikacji plików źródłowych skryptu i ogólnie niezbyt dużo nowatorskich rozwiązań. To właśnie sprawiło, że skrypt ten stopniowo był wypierany przez darmowe rozwiązania takie jak MyBB, SMF czy płatne IPB albo vBulletin.

Sam też się tym skryptem nie interesowałem, od dawna nie miałem potrzeby postawienia żadnego forum dyskusyjnego. Dziś rano trafiłem jednak przypadkiem na podsumowanie zmian nadchodzących w phpBB 3.1. Trzeba przyznać im jedno - widać, że mają plan i stopniowo dążą do jego realizacji.

Jeżeli byłeś użytkownikiem phpBB interesującym się jego rozwojem, to pewnie nie raz słyszałeś o mitycznym phpBB 4. Nie potrafię policzyć ile lat temu pojawiły się pierwsze pogłoski na ten temat - myślę, że około siedmiu. Tymczasem twórcy, wydaje się, że słusznie, odrzucili koncepcję przepisania całego silnika na raz, wybierając stopniowe zmiany. Zaczęli jednak naprawdę solidnie, zdecydowanym krokiem wchodząc w drugą dekadę XXI wieku. Oto krótkie podsumowanie tego, co przynoszą nam dotychczas wydane wersje phpBB 3.1 - do trzeciej bety.

Nowe możliwości

  • Rozszerzenia - bum, z grubej rury wchodzi system rozszerzeń niewymagających modyfikacji plików źródłowych. Niemalże obowiązkowa zmiana, choć przyznam się, że nie spodziewałem się takiej zmiany z wersji 3.0 na 3.1
  • AJAX - nie da się ukryć, brak przeładowania w paru miejscach jest bardzo przydatny
  • Powiadomienia - prawdopodobnie to Facebook wpłynął na to, że ten sposób komunikacji z użytkownikiem stał się tak popularny. Trzeba przyznać, że jest to bardzo wygodna metoda. Niektóre fora, np. forumweb same implementowały mechanizm powiadomień. Miło, że znalazło się to w standardzie
  • Gravatar - nie ma co się rozpisywać. Też praktycznie standard, też wielu ludzi to modyfikowało i też dobrze, że jest wbudowane
  • Responsive Design - zarówno wbudowany motyw phpBB Silver2 i szablon panelu administracyjnego są responsywne

Zmiany pod maską

  • Przestrzenie nazw i autoloading - słusznie pachnie to erą PSR i composera - phpBB zostało członkiem PHP-FIG
  • Dependency Injection - konsekwenetne zastosowanie tego wzorca, o którym piszą autorzy, z pewnością uporządkowało trochę kod źródłowy
  • Routing - myślę, że spokojnie możemy spodziewać się nice URLs w standardzie (aktualizacja: w standardzie się nie znajdą, ale ich zaimplementowanie powinno być łatwe z poziomu rozszerzenia - takie jest stanowisko autorów)
  • Composer - podstawa przy korzystaniu z komponentów. Jakich? Już w następnym punkcie.
  • Twig - mogę tylko odetchnąć z ulgą. Miałem wątpliwą przyjemność "bawić" się z ich poprzednim wynalazkiem
  • Przyciski tekstowe - mała zmiana, ale postanowiłem o niej napisać, bo bardzo denerwowała mnie niegdyś konieczność podmiany obrazków w celu spolszczenia "New topic" itd. Teraz jest to oczywiście tekst odpowiednio ostylowany w CSS

To naprawdę tylko przegląd najważniejszych opcji. Dodano wiele innych rzeczy takich jak chowanie tematów zamiast ich usuwania, logowanie poprzez oAuth (np. Facebook, Google), czy liczne poprawki dla CSS szablonów.

Muszę przyznać, że jestem pod wrażeniem tego jaki krok wykonała ekipa z phpBB. Niewykluczone, że ich produkt z powrotem odbije kawałek rynku, który kiedyś zajmował. Jak myślicie?

Raport z PHP.net

Witajcie,

pierwszy kwietnia już za nami, czas na kilka sprostowań. Przepraszam kilku rozczarowanych, uspokajam zaniepokojonych (Comandeer ;)). Wczorajszy wpis był wyłącznie żartem (czy dobrym, to już nie mi oceniać). Z PHP się nie rozstaję... wręcz przeciwnie. Od pewnego czasu zastanawiałem się nad dołączeniem do jakiegoś projektu Open Source, nawet dla zabicia czasu (jasne, przecież mam go tak dużo ^^). Nie powiem, że z PHP łączy mnie jakaś szczególna więź emocjonalna, ale jako, że z tego wytworu środowiska Open Source korzystam najczęściej, wybór padł właśnie na niego.

Uspokajam od razu wszystkich przerażonych. Nie, nie zostałem developerem parsera PHP, tak więc gorzej niż jest teraz raczej nie będzie, a już na pewno nie z mojej winy. Nie znam C, natomiast lubię sobie czasem pogrzebać przy stronach internetowych. Postanowiłem w jakiś sposób to wykorzystać - no i się udało :) Po pokazaniu, że co nieco potrafię (raportowanie bugów i przede wszystkim wysyłanie pull requestów na githubie) oraz złożeniu odpowiedniego wniosku zostałem developerem PHP.net. W zakresie WWW rzecz jasna.

To, co niedawno pisałem o PHP, odnosi się po części także do ich infrastruktury sieciowej. Wiele elementów nie było modernizowanych od dawna i bardziej przypominają zeszłe stulecie niż rok 2014. Stosunkowo duże pole do popisu, nawet dla osób z tak niewielkimi umiejętnościami jak moje. Teraz kilka konkretów, co udało mi się zrobić od 16 marca, kiedy to zaakceptowano mój wniosek.

  • Swoje wysiłki skupiłem przede wszystkim na modernizacji strony doc.php.net, czyli zestawu narzędzi dla twórców i tłumaczy manuala PHP. Ciężko wymienić wszystkie rzeczy, które zmieniłem. Jako, że strona, poza nielicznymi poprawkami, nie była aktualizowana od 10 lat, zacząłem od uprzątnięcia tego, co nie jest i nie będzie już używane. Myślę, że łącznie wyszło gdzieś z 10.000 linii kodu na minus. Nie zawsze więcej znaczy lepiej ;) Pierwotny interfejs poza tym, że nie przystawał do dzisiejszych standardów, był niesamowicie przerośnięty. Podczas zmieniania strony, mimo, że przejechałem ją wzdłuż i wszerz, nadal potrafiłem się zgubić. Opracowałem koncepcję tego, jak chciałbym, żeby strona wyglądała docelowo, dostałem wolną rękę od innych developerów i ruszyłem z pracami. Nie chce mi się opisywać całości, więc pozwolicie, że całość zilustruję screenem z przed i po modernizacji.
  • Wiele małych poprawek do wielu z podserwisów PHP: qa.php.net, news.php.net czy bugs.php.net
  • Zamknąłem kilkanaście bug reportów dotyczących WWW i dokumentaji
  • Zaangażowałem się troszeczkę w polskie tłumaczenie manuala. Zaktualizowałem i przetłumaczyłem kilkadziesiąt plików, choć generalnie temat jest już martwy
  • Przyłożyłem rękę do standardyzacji kilku rzeczy pomiędzy różnymi tłumaczeniami dokumentacji

Lista może nie jest zbyt imponująca, ale nie chodzi o to, aby przebudować wszystko co tylko się da. Jak widać, wciąż jest wiele rzeczy, które można na PHP.net poprawić i pomoc im się przydaje. Sam też czerpię z tego jakąś satysfakcję i naukę. Wrzucam tę informację na bloga w ramach sprostowania wczorajszego wpisu i pokazania, że jeszcze nie umarłem. Prawdopodobnie nie jest to zbyt porywająca lektura, no ale o czymś pisać trzeba ;)

Pozdrawiam.

Hello, better world!

Czas leci. Zmienia się wszystko co nas otacza. Kwestią indywidualną jest to, czy dostosujemy się do zachodzących procesów, czy będziemy stać w miejscu i biernie się temu przyglądać.

Informatyka jest dziedziną wiedzy, w której tempo rozwoju widać szczególnie wyraźnie. Co i rusz spotykamy się z technologicznymi nowinkami - a to nowy procesor mniejszy niż kiedykolwiek, a to czytnik e-booków w kształcie parówki, który w razie potrzeby możemy zjeść. Nie inaczej sprawa ma się w kwestii programowania. Ewolucja nie dotyka każdego języka w jednakowym stopniu, ale ogólnopojęta dziedzina wciąż wykształca nowe rozwiązania. Inne zaś odchodzą w niepamięć.

Czytając ten wstęp nietrudno jest domyślić się, o czym będzie dalej. Trudno mi za to o tym napisać, bo nie jest to prosta decyzja. Dotychczas wiedziały o niej tylko dwie osoby, jednak ze względu na to, że prowadzę publicznie dostępne zapiski ze swojej działalności w internecie, czas podzielić się tym ze wszystkimi, którzy mogą być zainteresowani. Niniejszym wrzucam to stwierdzenie do internetu i niechaj w nim zostanie: porzucam PHP.

Zmiana technologii jest naprawdę ciężką kwestią, zwłaszcza dla osoby tak przyzwyczajonej jak ja. Zdaję sobie jednak sprawę z ograniczeń tego języka. Przemyślałem to dokładnie i uważam, że czas podjąć konkretne kroki. Liczę, że cząstka doświadczenia zdobytego w PHP przyda mi się w nowej technologii. Ruby.

Dlaczego właśnie ten język? Powodów jest bardzo wiele: począwszy o spójnego i uporządkowanego API (którego w PHP chyba nie dożyję), przez szerokie możliwości, po zwyczajną estetykę kodu.

Argumentu o czytelności nie muszę chyba rozwijać - dużo materiałów mówi o PHP w tym zakresie, kilka skromnych sam napisałem. Jeżeli chodzi o możliwości. Korzystając z Ruby otrzymuję technologię przystosowaną zarówno aplikacji sieciowych jak i desktopowych. Mój obszar zainteresowań jest chyba jasny, tak więc Ruby on Rails już jakiś czas temu zawitał na moim dysku, jednak nie porzucam nadziei, że nauka technologii bardziej uniwersalnej niż pehap pozwoli mi na (choćby skromne) wejście w świat aplikacji okienkowych. Ostatnia cecha, estetyka kodu: Ruby, jako język nowszej generacji, nie czerpie swojej składni z C. To pozwala nam pozbyć się irytujących klamerek i umożliwia chociażby method-chaining ("Test".upcase.reverse). Wszyscy, którzy mnie znają, wiedzą, że w kwestii spójności wyglądu kodu jestem pedantem. Pisałem o tym minimum raz. To jedna z wielu rzeczy, które Ruby da mi w standardzie - nie będę musiał walczyć z językiem o ładny kod i wyszarpywać mu go z paszczy - co najwyżej to on zawalczy ze mną, jeżeli postanowię rozwiązać coś nieodpowiednio.

Tyle o powodach... i co tu więcej mówić. Intensywna nauka trwa już jakiś czas, za kilka dni chcę się pochwalić pierwszym prostym projektem. Mam swoją drogą nadzieję, że całkowicie nowa gałąź wiedzy do zgłębienia, rozrusza jakoś ten blog. Jednocześnie informuję, że rozwój wszystkich dotychczasowych projektów napisanych w PHP (a innych nie ma ;)) został zatrzymany. Nie był to jakiś istotny dorobek, tak więc myślę, że spokojnie przeżyjecie, a ja nie mam czasu na dalsze inwestowanie go w PHP.

Pozdrawiam Was z nowego, lepszego świata!

-- edit (02.04.2014) --
Pierwszy kwietnia już za nami - sprostowanie dostępne tutaj ;)

PHP – jest nadzieja

Dzisiejszy artykuł chciałbym poświęcić rozwojowi PHP - jako projektu samego w sobie. Będzie trochę historii, ale postaram się skupić głównie na tym co się zmienia i zmienia się na lepsze. Zapraszam do czytania.

PHP to język z dosyć długą historią - pierwsza wersja powstała w roku 1994. Często jednak rozumie się to jako wadę, a nie powiedzmy źródło doświadczenia wśród jego deweloperów. Różnorakie nieprzemyślane rozwiązania wymyślone i nagromadzone jeszcze w zeszłym stuleciu potrafią być bagażem po dziś dzień.

O PHP krąży nieprzypadkowo obiegowa opinia, że jest to język prawie tak ciężko reformowalny jak kościół katolicki w średniowieczu. Ma to oczywiście uzasadnienie: deweloperzy boją się wszelkich zmian zrywających kompatybilność wsteczną, bo jej zapewnienie buduje zaufanie ludzi tworzących w danej technologii. Nikt przecież nie chciałby przepisywać swoich aplikacji co dwa miesiące, prawda? W PHP doszło to jednak do bardzo wysokiego poziomu - latami starano się o wiele potrzebnych zmian, poprawek i rozliczeń z przeszłością. Prace nad ostatnią wersją major, czyli PHP5 zostały rozpoczęte jeszcze w 2002 roku. Stabilna wersja ukazała się na początku 2003. Znacząco poprawione zostały między innymi wszystkie rzeczy związane z programowaniem zorientowanym obiektowo. Można powiedzieć, że PHP wykonało susa do przodu i dogoniło ówczesną epokę pod wieloma względami.

Niewiele później, w okolicach wydania PHP 5.1, czyli w roku 2005 środowisko PHP zaczęło snuć plany na kolejną dużą wersję - hucznie zapowiadano rychłe nadejście PHP6, które miało poprawić rzeczy nie ruszane praktycznie od początku istnienia projektu - ujednolicić API, wprowadzić pełne wsparcie dla UTF-8 i poprawić wiele nieeleganckich i przestarzałych rozwiązań. Początkowy zapał jednak w miarę szybko osłabł, a tempo rozwoju dodatkowo osłabiły podzielone opinie wśród programistów samego języka - wielu z nich uważało, że planowane zmiany są zbyt radykalne oraz, że wymagają zbyt dużego nakładu czasowego. PHP6 szybko stało się martwym projektem, którego w zasadzie nikt na oczy nie widział, a jego rozwój został oficjalnie zawieszony w roku 2010.

Czas płynął, inne technologie dynamicznie się rozwijały, powstawały coraz bardziej nowoczesne rozwiązania. Dlatego ekipa PHP również postanowiła się pozbierać i wprowadzić część z rozwiązań planowanych na 6.x we wcześniejszych wersjach. Tak pojawiło się PHP 5.1 wprowadzające PDO, PHP 5.2 (listopad 2006) dodające wbudowane wsparcie dla formatów takich jak ZIP czy JSON oraz poprawiające zarządzanie pamięcią.

Kolejną wersją z piątej gałęzi, która ze względu na wprowadzone zmiany mocno zapadła w pamięci wielu programistów, była oznaczona numerkiem 5.3. Została ostatecznie wydana 30 czerwca 2009 roku i wprowadzała takie nowości jak przestrzenie nazw, domknięcia (clousures), mysqlnd (natywny driver MySQL) oraz poprawiająca obsługę modelu obiektowego.

Po tym kolejnym podgonieniu konkurencji, rozwój PHP ponownie jakby zamarł. Część środowiska nadal liczyła na szybkie ukończenie wersji 6 (której rozwój nie został wtedy jeszcze oficjalnie zdementowany), ale dla wielu stało się widoczne, że przez kilka kolejnych lat nie udało się wprowadzić praktycznie żadnych istotnych ulepszeń. Konkurencja gnała do przodu, a deweloperzy PHP grzęźli w wewnętrznych konfliktach.

Przełom nastąpił około roku 2012, czyli stosunkowo niedawno. Wtedy, po prawie 3 latach przerwy pojawiło się PHP 5.4 Można uczciwie powiedzieć, że próbowano znaleźć złoty środek między kompatybilnością z poprzednimi wydaniami i rozliczeniem się z błędami przeszłości.

  • usunięto często (i słusznie) krytykowane magic quotes, register globals oraz safe mode
  • usunięto składnię break/continue $var
  • usunięto między innymi funkcje import_request_variables(), session_is_registered(), session_register() i session_unregister()
  • wersje sqlite starsze niż 3 zostały wyrzucone do PECL
  • domyślnie wyłączono obsługę <? jednocześnie na stałe umożliwiając użycie składni <?=zmienna?> niezależnie od konfiguracji
  • wprowadzono uproszczoną składnię dla tablic ($array = [1, 2, 3])
  • umożliwiono array dereferencing (echo explode(' ', 'raz dwa')[1])
  • analogicznie pozwolono na zapis typu echo (new foo)->bar())
  • dodano wsparcie dla $this w domknięciach (clousures)
  • dodano traitsy
  • dodano wbudowany serwer developerski
  • duże poprawki wydajności

Ilość i "ciężar" wprowadzonych zmian, który jak na PHP był naprawdę duży odbił się szerokim echem. Był to głównie odbiór pozytywny, zazwyczaj ludzie cieszyli się, że pewne złe rozwiązania zostaną w końcu wyeliminowane siłowo. Przyspieszenie rozwoju nie było tak chwilowe jak poprzednio i już 20 czerwca 2013 pojawiło się wydanie 5.5. Tym razem zdecydowano się na następujące ulepszenia i kolejne rozliczenia z ciężarem dawnych wersji.

  • usunięto powodujące zagrożenie funkcje php_logo_guid(), php_egg_logo_guid(), php_real_logo_guid(), zend_logo_guid()
  • zdeprecjonowano wszystkie funkcje mysql_*
  • zdeprecjonowano flagę /e dla preg_replace()
  • zdeprecjonowano pewne funkcje z modułów mcrypt i intl
  • dodano generatory
  • dodano obsługę bloku finally
  • dodano nowe API dla hashowania
  • dodano wsparcie dla list() w foreach
  • dodano obsługę wyrażeń skalarnych w empty()

Lista zmian nie jest kompletna, tak jak dla PHP 5.4 skupiłem się na tym co najistotniejsze z punktu widzenia tego artykułu. Rozwój nadchodzącej wersji 5.6 obserwuję już na bieżąco i piszę już z własnych obserwacji takich miejsc jak GitHub oraz lista malingowa deweloperów PHP. Planowane/ukończone są obecnie następujące zmiany:

  • trzykrotne zmniejszenie zużycia pamięci dla danych POST
  • wbudowany debugger phpdbg
  • obsługa wyrażeń skalarnych dla const (podobnie jak wcześniej dla empty())
  • variadic functions i argument unpacking dzięki operatorowi ...
  • operator potęgowania (**)
  • obsługa uploadu plików większych niż 2GB
  • obsługa przestrzeni nazw dla funkcji
  • poprawki dla SSL i mcrypt
  • ustawienie domyślnego kodowania w php.ini dla funkcji takich jak htmlspecialchars()

Poza samymi zmianami w języku widać też zmianę podejścia w środowisku twórców. Podam na dzisiejszym przykładzie: kilka dni temu jeden z deweloperów zaproponował zmiany w rozszerzeniu mcrypt, które miały by bardziej rygorystycznie pilnować podawania soli dla haseł (jej brak miałby skutkować warningiem, a nie przemilczaniem błędu i obejściem jak jest obecnie). Mimo początkowego hałasu podniesionego o przerwanie kompatybilności wstecznej, zmiana została dziś dodana do gałęzi 5.6, mimo, że niedługo nadchodzi już wersja beta. To jedno wydarzenie pokazuje dosyć istotny postęp - niektóre zmiany, głównie związane z bezpieczeństwem, nawet takie które zepsują kilka skryptów, przechodzą po prostu łatwiej.

Ostatnio coraz więcej dyskusji toczy się także na temat zmian jakie chciano by zawrzeć w PHP6. Ponownie rozważana jest kwestia pełnego wsparcia dla UTF8 (kto musiał korzystać z funkcji mb_* wie o co chodzi), uporządkowanie API (ujednolicenie nazewnictwa funkcji i tak dalej) i porządkach w Zend Engine. Proponowane szkice zmian można znaleźć między innymi tutaj i tutaj. Jednocześnie głównym kierunkiem rozwoju pozostaje dotychczas wersja 5.7.

Co sądzicie o zmianach ostatnich lat, które zachodzą w PHP? Jest nadzieja? ;) A może cały rumor jaki się podniósł i używanie haseł takich jak "renesans PHP" jest Waszym zdaniem na wyrost? Zapraszam do dyskusji :)

Jekyll – generowanie statycznych stron HTML

Nie, w dzisiejszym wpisie nie chcę Wam opowiedzieć o londyńskim lekarzu zamieniającym się nocą w potwora. Będzie standardowo, czyli o sprawach powiązanych z webmasterką.

Krótki akapit wstępu, bo większość z Was prawdopodobnie nie zna wspomnianego skryptu. Otóż Jekyll jest to narzędzie, które pozwala wygenerować statyczną stronę na podstawie dostarczonych plików. Można to nawet nazwać CMS-em, bo w pewien sposób umożliwia zarządzanie treścią, jednak w sposób odmienny od większości systemów tego typu. Tak jak wspomniałem wcześniej, Jekyll bazuje na plikach utworzonych przez webmastera. Składają się na nie:

  • Szablony - pliki HTML, które definiują układ i kod strony. Tak jak we wszystkich innych skryptach, zawierają one zmienne, pod które będą podstawiane odpowiednie wartości: np. tytuł strony, czy jej treść
  • Pliki z treścią - tutaj rozróżnić możemy wpisy oraz normalne podstrony
  • Pliki nie parsowane - takie jak pliki CSS czy obrazki

Jekyll sparsuje otrzymane pliki i wyrzuci nam całą strukturę statycznych plików, które wrzucamy na serwer i mamy naszą stronę. Odmienia to trochę podejście do tworzenia witryn. Zamiast dynamiki nadawanej za pomocą języków działających po stronie serwera, całą stronę generujemy u siebie na komputerze, a na serwerze trzymamy statyczną witrynę wspieraną co najwyżej przez technologie client-side takie jak JavaScirpt.

Może wydawać się, że takie rozwiązanie to cofnięcie się do średniowiecza, w końcu Web 2.0, to coraz bardziej interaktywne strony internetowe. Z drugiej strony użycie Jekylla pozwala się nam skupić na tworzeniu treści, nie martwiąc się o inne kwestie. Po prostu piszemy treść w naszym ulubionym formacie (takim jak Markdown), a potem wydajemy jedną komendę i mamy gotowego bloga, który w dodatku do działania nie wymaga żadnego specjalnego serwera, bo wystarczy serwowanie odwiedzającym statycznych plików.

Drugą cechą stojącą za rosnącą popularnością tego rozwiązania w ostatnim czasie, jest fakt iż Jeykyll jest automatycznie zintegrowany z GitHub Pages. Jeżeli ktoś nie wie co to, to już spieszę z tłumaczeniem. Jest to metoda serwowania strony WWW przetrzymywanej w systemie kontroli wersji git. Przyznacie, że brzmi to bardzo wygodnie - całość witryny trzymana jest na GitHubie dzięki czemu mamy dokładną kontrolę nad wszelkimi wprowadzanymi zmianami, a Jekyll "magicznie" generuje bloga/stronę na podstawie dostarczonych plików.

Sam myślałem nad zastosowaniem tego hipsterskiego podejścia u siebie na stronie, jednak przeważyło moje przywiązanie do klasycznej dynamiki stron WWW. W momencie kiedy do strony obsługiwanej przez Jekylla trzeba dodać podstawowe elementy interakcji z użytkownikiem, zaczyna się naprawdę mocne kombinowanie. Poza tym nie znam w ogóle Ruby, w którym został napisany Jekyll i wszelkie modyfikacje przychodziły by mi z trudem.

Zaprezentowany skrypt nie jest oczywiście jedynym tego typu. Ze względu na popularność opisanego podejścia, powstały podobnie działające rozwiązania dla wielu innych języków. Z tych napisanych w PHP można wymienić między innymi Phrozn czy PieCrust. Pewne podsumowanie najpopularniejszych static generatorów zawiera strona StaticGen.com.

Co sądzicie o takim, jakby nie patrzeć mocno odmienionym podejściu do tworzeniu blogów. Interesowaliście się kiedyś takimi rozwiązaniami?