Przyjazne adresy URL a wydajność

11 listopada 2011

Jakiś czas temu (kilka lat temu?) ktoś w komentarzu poprosił mnie o wytłumaczenie jak zniwelować dodatkowe obciążenie jakie generuje użycie przyjaznych adresów URL. Zacząłem o tym pisać a potem, z jakiegoś powodu, przerwałem i do tej pory nie znalazło się trochę czasu aby skończyć... Wiele artykułów mi w ten sposób przepadło. Tym razem dokończę dzieła :) A raczej napiszę od nowa bo wcześniej niepotrzebnie się rozpisałem...

Główne założenia: musisz napisać wydajną aplikację z przyjaznymi adresami URL w których nie przekazujesz żadnych identyfikatorów.

Przyjazne adresy to dzisiaj już konieczność. Ale wymagania wciąż rosną i teraz adresy muszą być jeszcze bardziej przyjazne niż kiedyś :) Nie tak dawno każdemu wystarczały adresy w postaci example.com/artykuly/1,jakis-adres/ czyli z przekazanym identyfikatorem zasobu. Te jednak okazały się zbyt brzydkie. Dzisiaj już nie chcemy identyfikatorów, chcemy czystych adresów czyli example.com/artykuly/jakis-adres/.

Oczywiście z punktu widzenia trudności zakodowania takiego rozwiązania, różnica jest niewielka. Jedno małe zapytanie do bazy danych gdzie wyszukamy identyfikator/dane artykułu na podstawie jego adresu. Czas wykonania się kodu też jakoś specjalnie się nie wydłuży. W czasach rozbudowanych frameworków z ich prostymi w użyciu routerami mało kto w ogóle sobie takimi rzeczami zawraca głowę. Być może jednak potrzebujesz ekstremalnej wydajności lub jesteś jej zwykłym fanatykiem (tak jak ja swego czasu :) ). Jest sposób na zlikwidowanie dodatkowego obciążenia.

Kluczem do sukcesu jest fakt, że przekierowanie w .htaccess, którego używasz (zakładam, że używasz bo inaczej nie uzyskałbyś nawet adresu example.com/artykuly/1,jakis-adres/ a co najwyżej jakieś example.com/artykuly.php/1,jakis-adres/) aby mieć przyjazne URL'e, działa tylko wtedy jeżeli nie istnieje fizycznie na dysku katalog/plik odpowiadający wpisanemu adresowi. Innymi słowy, jeżeli w publicznym katalogu głównym naszej aplikacji istnieje katalog artykuly a w nim katalog jakis-adres to żadne przekierowanie z .htaccess nie zadziała tylko Apache zacznie szukać w tym katalogu jakiegoś pliku index do wyświetlenia/uruchomienia.

Od tej wiedzy do sukcesu już krótki odcinek. Wystarczy podczas tworzenia artykułu (ale nie zapomnij potem o edycji i usuwaniu) tworzyć katalogi, które będą odpowiednikami adresów na stronie. W każdym z takich katalogów wystarczy umieścić plik index.php. Jego zawartość może wyglądać tak:

PHP:
  1. <?php
  2. $id = 1;
  3.  
  4. require '../../../start.php';
  5. start($id);

Oczywiście kod jest zupełnie przykładowy, chodzi o samą logikę. W wygenerowanym pliku mamy informację o identyfikatorze. Dzięki temu nie trzeba robić dodatkowego zapytania do bazy danych. Następnie startujemy naszą aplikację i przekazujemy dalej informację o identyfikatorze.

A więc mamy katalog /artykuly/jakis-adres/ w którym znajduje się plik index.php z powyższą zawartością. Działa. Osobiście przenoszę jeszcze wszystkie wygenerowane katalogi do jakiegoś wspólnego miejsca np. katalogu /cache. To wprowadza mi pewien porządek na dysku serwera, zwłaszcza gdy elementów korzystających z tego mechanizmu jest więcej (miałbym wtedy katalogi artykuly, galeria, imprezy itd. co wprowadza niepotrzebny bałagan). Robię to za pomocą .htaccess. Przykład:

CODE:
  1. RewriteRule ^artykuly/([^/]+)/?$ cache/artykuly/$1/

I w ten oto prosty sposób mamy trochę więcej katalogów i plików na dysku ale:
- zyskaliśmy piękne adresy URL
- cały mechanizm nie generuje zbędnego obciążenia
- sposób nie jest zbyt kłopotliwy bo cały cache siedzi sobie w jednym katalogu i nikomu nie przeszkadza
- nasza strona jest o jeden krok bliżej do osiągnięcia sytuacji gdy artykuły są dostępne nawet podczas awarii bazy danych

Podsumowując: gdy ktoś wpisze adres example.com/artykuly/jakis-adres/ to zadziała przekierowanie na katalog /cache/artykuly/jakis-adres/ gdzie wygenerowany plik index.php posiada informację o identyfikatorze tego katalogu, uruchomi naszą aplikację i przekaże jej ID.

Można jeszcze dopisać mechanizm, który zablokuje bezpośredni dostęp do plików cache na serwerze (aby nie działały adresy example.com/cache/artykuly/jakis-adres/). I na tym koniec :)

PS
Pamiętaj aby pilnować przy adresach bez identyfikatorów aby adresy się nie powtarzały.


Domyślne style w Firefox

01 listopada 2011

W Internecie cały czas trwa dyskusja czy strony www muszą wyglądać identycznie we wszystkich przeglądarkach czy może nie powinniśmy skupiać się na robieniu kopii co do każdego piksela i pozwolić na lekkie różnice.

O problemie pisałem już w tekście "Reset styli CSS" gdzie opowiedziałem się za standaryzacją domyślnych ustawień przeglądarek. Czasami po prostu strona musi wyglądać identycznie aby wszystkie efekty, animacje etc. działały jak należy. Dla mnie ta cała dyskusja jest niezrozumiała.

Piszę to wszystko bo ostatnio napotkałem na dziwny problem z przeglądarką Firefox. Tak, o dziwo nie tylko IE w dzisiejszych czasach potrafi coś spartolić :) Otóż FF dodaje do przycisków formularzy (buttom, submit itp.) wewnętrzny margines. Zresztą sami zobaczcie:

CSS:
  1. button::-moz-focus-inner,
  2. input[type="reset"]::-moz-focus-inner,
  3. input[type="button"]::-moz-focus-inner,
  4. input[type="submit"]::-moz-focus-inner,
  5. input[type="file"]> input[type="button"]::-moz-focus-inner {
  6.   padding: 0px 2px 0px 2px;
  7.   border: 1px dotted transparent;
  8. }

Ustawianie własnego padding nic nie pomaga o ile nie użyjemy tego pięknego "::-moz-focus-inner". I skąd webmasterzy mają o tym wiedzieć? :/

W porównaniu do lat gdy zaczynałem zabawę z HTML (chyba rok 1999) mamy teraz piękne czasy. Mimo to nadal nie jest idealnie i mam duże wątpliwości czy kiedyś będzie.

Listę domyślnych styli CSS w Firefox znajdziemy wpisując w okno przeglądarki taki adres: resource://gre-resources/forms.css

Pod tym adresem znajduje się oficjalny arkusz CSS dla elementów języka HTML 4. Natomiast tutaj jest nieoficjalny (oficjalnego nie mogłem znaleźć) kod CSS dla HTML 5.


Optymalizacja plików PNG

25 października 2011

"Tnąc" grafikę do HTML/CSS często też zwracamy uwagę na rozmiary zapisanych plików. I tak na przykład w formacie JPG sprawa jest jasna. Jest to format z kompresją stratną i sami ustalamy gdzie leży granica między rozmiarem a jakością. Pliki GIF używają kompresji bezstratnej (algorytm LZW i jego pamiętne patenty...) ale format ten obsługuje jedynie 256 kolorów więc następuje kwantyzacja kolorów i rozmiary tych plików są niewielkie (co było istotne w latach 80. i 90.). A co z PNG?

PNG powstał jako odpowiedź na GIF i problemy pantentowe. Jest to format kompresji bezstratnej i teoretycznie powinniśmy się spodziewać, że eksport do PNG da zawsze takie same lub przynajmniej bardzo podobne rozmiary plików. W praktyce, podczas zapisywania pliku, następują pewne przekształcenia. Można je wykonać mniej lub bardziej dokładnie co ma wpływ na dwa czynniki: czas generowania się pliku wynikowego i jego rozmiar.

Niestety wiele programów graficznych nie traktuje problemu zbyt poważnie i lecą po linii najmniejszego oporu. Efektem są pliki o zbyt dużych rozmiarach.

Od kilku lat stosuję z powodzeniem program OptiPNG. Dzisiaj ze zdumieniem odkryłem, że jego początki sięgają grudnia 2001.

Program daje pozorny wybór stopnia kompresji. Nie działa to oczywiście tak jak w JPG. Jest to po prostu kompromis jaki sami ustalimy między dokładnością a czasem. Im dokładniej tym dłużej ale tym także mniejszy rozmiar pliku.

Dla programu istnieją różne dodatki/nakładki. Testowałem OptiPNG-UI. Program nie jest najładniejszy ale nie trzeba wszystkiego robić z linii poleceń co jest zbawienne przy większej ilości plików. Domyślnie wszystko jest po włosku. Aby to zmienić należy kliknąć na niebieską strzałkę w prawym górnym rogu i w nowo otwartym oknie wybrać jakąś flagę (dostępne języki: włoski, angielski, hiszpański, francuski).

Optymalizujcie swoje grafiki, stosujcie też technikę CSS Sprites (którą w pewnym stopniu opisałem tutaj). To wszystko daje wymierne efekty.


Połączenie AJAX z obcą domeną za pomocą jQuery

22 października 2011

AJAX to wspaniała technologia dzięki której mogło powstać wiele rewolucyjnych usług. Ma ona jednak pewne ograniczenia związane z polityką bezpieczeństwa przeglądarek. Jednym z największych ograniczeń jest możliwość łączenia się poprzez AJAX wyłącznie ze stronami w tej samej domenie. Krótko mówiąc, nie ma możliwości pobrać strony example2.com ze strony example1.com. Tak przynajmniej myślałem do tej pory :)

Nim jeszcze przejdę do meritum sprawy, dodam, że oczywiście istnieje obejście problemu. Można napisać swego rodzaju proxy w PHP lub w innym języku i za pomocą tego proxy pobierać docelową stronę. Trzeba jednak koniecznie pamiętać aby przy tego typu rozwiązaniach jakoś filtrować kto korzysta z naszego skryptu i co pobiera. Inaczej będą problemy bo skrypt musi być przecież publicznie dostępny.

Nam jednak zależy aby całą sprawę załatwić z poziomu JavaScript. Z pomocą przychodzi YQL od Yahoo!.

Czym jest YQL? W dużym uproszczeniu, jest to język składniowo podobny do SQL, który pozwala na odczyt/manipulację różnymi zorganizowanymi strukturami danych np. HTML. Jego możliwości możemy wykorzystać dla własnych celów o czym możemy się dowiedzieć z tego artykułu. Pozwolę sobie skopiować jeden przykład:

JavaScript:
  1. $(document).ready(function(){
  2. var container = $('#target');
  3. $('.ajaxtrigger').click(function(){
  4. doAjax($(this).attr('href'));
  5. return false;
  6. });
  7. function doAjax(url){
  8. // if it is an external URI
  9. if(url.match('^http')){
  10. // call YQL
  11. $.getJSON("http://query.yahooapis.com/v1/public/yql?"+
  12. "q=select%20*%20from%20html%20where%20url%3D%22"+
  13. encodeURIComponent(url)+
  14. "%22&format=xml'&callback=?",
  15. // this function gets the data from the successful
  16. // JSON-P call
  17. function(data){
  18. // if there is data, filter it and render it out
  19. if(data.results[0]){
  20. var data = filterData(data.results[0]);
  21. container.html(data);
  22. // otherwise tell the world that something went wrong
  23. } else {
  24. var errormsg = '<p>Error: could not load the page.</p>';
  25. container.html(errormsg);
  26. }
  27. }
  28. );
  29. // if it is not an external URI, use Ajax load()
  30. } else {
  31. $('#target').load(url);
  32. }
  33. }
  34. // filter out some nasties
  35. function filterData(data){
  36. data = data.replace(/<?/body[^>]*>/g,'');
  37. data = data.replace(/[r|n]+/g,'');
  38. data = data.replace(/<--[Ss]*?-->/g,'');
  39. data = data.replace(/<noscript[^>]*>[Ss]*?</noscript>/g,'');
  40. data = data.replace(/<script[^>]*>[Ss]*?</script>/g,'');
  41. data = data.replace(/<script.*/>/,'');
  42. return data;
  43. }
  44. });

To kompleksowy kod, który pozwala stworzyć proste odnośniki na stronie służące do pobierania zewnętrznych witryn, przy okazji filtrując wyniki z potencjalnie niebezpiecznego kodu. Dobrze wiedzieć, że YQL pobiera tylko zawartość tagu body docelowej strony, co ma oczywiście swoje konsekwencje np. dostaniemy dostęp tylko do tych styli CSS, które zostały bezpośrednio "wpisane" w tagi HTML, tzw. inline CSS.

Pod tym adresem znajduje się prezentacja działania tego kodu.

Na github.com znajduje się również prosty skrypt jQuery, który szalenie upraszcza korzystanie z dobrodziejstw YQL. Dzięki niemu możemy korzystać z dotychczasowych rozwiązań opartych o AJAX i podawać zewnętrzne adresy www a skrypt sam martwi się już o to aby cały proces przebiegł bez problemów. Przykład użycia (z tej strony):

JavaScript:
  1. $('#container').load('http://google.com'); // SERIOUSLY!
  2.  
  3. $.ajax({
  4.     url: 'http://news.bbc.co.uk',
  5.     type: 'GET',
  6.     success: function(res) {
  7.         var headline = $(res.responseText).find('a.tsh').text();
  8.         alert(headline);
  9.     }
  10. });

Warto wspomnieć o alternatywnej metodzie. Istnieją rozwiązania w których JS łączy się z odpowiednim plikiem Flash i to on wykonuje za nas robotę polegającą na pobraniu zawartości strony. Ograniczeniem tej metody jest fakt, że komunikacja nie może być zablokowana na domenie docelowej w pliku crossdomain.xml. Popularnym skryptem rozwiązującym problem właśnie za pomocą Flash'a jest flXHR.

Kłopot z tzw. cross-domain AJAX jest obszerny, mam za małą wiedzę aby móc go lepiej opisać. Żywię jednak nadzieję, że tekst będzie przydanty i pomoże komuś rozwiązać jego problemy. Zachęcam do samodzielnego zgłębiania problemu i dzielenia się wiedzą w komentarzach.

PS
Pytanie za 100 punktów. Skoro AJAX nie pozwala pobierać danych z zewnętrznych adresów www to jakim cudem pozwala łączyć się z domeną http://query.yahooapis.com/ ? Pytam szczerze bo ja tego nie wiem :) Firebug nie pokazuje ruchu generowanego za pomocą tego rozwiązania jako ruch AJAX tylko przypisuje go do zakładki JS.

EDIT
Czytaj komentarze, koledzy dali tam wiele interesujących, uzupełniających informacji!


Program do konwersji mediów między różnymi formatami

17 października 2011

Wpis spóźniony o dobry rok ale lepiej późno niż wcale ;)

Jeszcze dwa lata temu, gdy musiałem przekonwertować plik wideo z jednego formatu na drugi, nie miałem zbyt dużego wyboru. Programy były albo płatne albo z niewielką ilością funkcji i generowały słabej jakości materiał. Jakoś sobie jednak radziłem póki nie natrafiłem na Freemake Video Converter, około rok temu. Wtedy to były pierwsze dni i miesiące jego istnienia ale od razu wyróżniał się wyjątkową użytecznością.

Freemake ma mylącą nazwę bo obsługuje nie tylko pliki wideo ale również audio oraz ma wiele funkcji dodatkowych. Kilka jego cech:

  • obsługuje ponad 200 różnych formatów mediów
  • potrafi konwertować media bezpośrednio z takich stron jak youtube.com, vimeo.com itp.
  • potrafi tworzyć pokazy slajdów z plików graficznych
  • potrafi konwertować media do Flash'a (FLA i SWF)
  • obsługuje formaty obowiązujące na urządzeniach mobilnych typu iPod, iPad, urządzeniach z systemem Android itp.
  • potrafi nagrywać na DVD i Blue-ray
  • obsługuje napisy do filmów
  • zapewnia bezpośrednie wgrywanie filmów i dźwięku do youtube.com
  • pozwala wycinać, obracać i zmieniać format obrazu, łączyć kilka plików w jeden, nadawać różne efekty dodatkowe naszym multimediom
  • i wiele więcej :)

Powyższa lista jest mocno inspirowana tym co oni sami umieścili na swojej stronie ale potwierdzam, że nie ma w tym wszystkim ani trochę przesady. Ten program to zbawienie :) Jest darmowy, z bardzo dużą liczbą funkcjonalności i przy okazji jest banalny w użyciu. Polecam!

PS
Zauważyłem, że istnieje także Freemake Audio Converter. Nie testowałem go, chyba niektóre funkcjonalności dublują się w obu programach. Moim zdaniem lepiej byłoby to połączyć w coś w stylu Freemake Media Converter :)


Bootstrap od Twitter

13 października 2011

Twitter wypuścił jakiś czas temu w świat całkiem ciekawy twór, który zwie się Bootstrap. Można go chyba zaliczyć do frameworków CSS chociaż korzysta też z możliwości JavaScript.

Nie zdołałem się jeszcze przekonać do takich produktów jak Blueprint (3 i pół roku temu zamieściłem nawet krótki wpis informacyjny o tym frameworku, tutaj link) czy 960 Grid System. Niby znam ich zalety ale jakoś brakuje czasu i energii żeby wreszcie któryś poznać. Chyba nie leży mi przede wszystkim idea budowania CSS na bazie siatki. Może kiedyś będzie okazja się przemóc i spróbować któregoś rozwiązania.

Bootstrap wpadł mi jednak w oko. Może dlatego, że jego dokumentacja (tak, to ten sam link co wcześniej :) ) jest tak banalna, przejrzysta i przyjazna, że każdy złapie w lot jak go używać.

Bootstrap to zbiór bibliotek CSS wzbogacony o LESS (napiszę o tym więcej, obiecuję!) i pluginy JavaScript. Razem prezentuje się to naprawdę atrakcyjnie i prosto. Wystarczy spojrzeć na przykłady z dokumentacji. Typografia, przyciski, formularze, okienka. Wszystko to i wiele więcej, gotowe do użycia, często bez naszej ingerencji, czasami wymaga tylko dodania odpowiedniej klasy do elementu.

Raczej to nie jest jeszcze ten moment gdy zbuduję pierwszą stronę w całości opartą o framework CSS jednak Bootstrap idealnie pasuje mi do tworzenia różnego rodzaju paneli administracyjnych. Z wyglądem takich paneli zawsze jest problem a tutaj mamy wszystko gotowe.

Polecam Bootstrap, warto też bliżej przyjrzeć się dostępnym pluginom JavaScript (oparte o mój ulubiony famework JS czyli jQuery) i podejrzeć trzy przykładowe strony (pierwsza, druga, trzecia).

Źródła dostępne są do ściągnięcia na GitHub pod adresem https://github.com/twitter/bootstrap.


VPS od freecast.pl

04 października 2011

Trochę mi głupio, że to drugi wpis na blogu o firmie hostingowej i drugi z negatywną oceną. Ktoś w końcu dojdzie do wniosku, że potrafię tylko narzekać.

Z drugiej strony, gdy sam wybieram hosting, to szukam w Internecie rzetelnych recenzji. Szczególnie biorę pod uwagę opinie blogerów bo ktoś kto prowadzi swój blog od kilku lat, raczej nie będzie kłamał i koloryzował faktów. Nie jest już taki anonimowy i nie da się też ukryć, że jest się jakoś powiązanym z daną firmą.

Podsumowując: nie chcę narzekać ale trzeba ludzi informować jak wygląda sytuacja. Każdy sam wyciągnie wnioski.

Od kilku miesięcy, z przerwami, posiadam serwer VPS zarejestrowany na freecast.pl. Nigdy nie stało na nim nic poważnego, służy mi do rozrywki i nauki zarządzania LAMP. Nie jestem w stanie obiektywnie ocenić jego wydajności bo nigdy nie wygenerowałem na nim ruchu, który dostarczyłby mi jakichś miarodajnych danych. Zdążyłem sobie jednak już wyrobić opinię o tej firmie i jej usługach.

Spotkały mnie dwie nieprzyjemne sytuacje. Pierwsza, ewidentnie z mojej winy. Skasowałem sobie pliki. Żeby było śmieszniej, zrobiłem to podczas próby stworzenia backupu... :D Wszystko wydarzyło się w niedzielę około godziny 16 lub 17. Napisałem do BOK zapytanie czy mają backup mojego serwera ale nie liczyłem na pozytywną odpowiedź i zabrałem się od razu za odtwarzanie (czytaj: robienie od nowa..) straconych danych.

Odpowiedź od freecast.pl nadeszła w poniedziałek około południa. Oto ona:

Witam

kopie tworzone są o godzinie 22 każdego dnia

Kosztem niedzielnego wieczoru odzyskałem już wszystko co straciłem ale ta odpowiedź mnie zaintrygowała więc dopytałem czy to oznacza, że kopie są nadpisywane. Musiałem czekać aż do środy do godziny 11 aby dostać niezwykle rozbudowaną odpowiedź, która brzmiała: "Tak".

Wnioski? Backup na VPS'ach od freecast.pl niby jest ale trzeba mieć trochę szczęścia żeby z jego dobrodziejstw skorzystać. Jeżeli będziesz chciał coś z niego przywrócić to masz czas do godziny 22:00 tego samego dnia. W weekend się raczej nie doprosisz. W dni powszednie jest pewnie lepiej ale też trzeba się modlić aby usterka nie wystąpiła tuż przed godziną 22:00 i aby ktoś po drugiej stronie kabla przeczytał Twój e-mail na czas.

Oczywiście należy być obiektywnym. To ja sobie skasowałem pliki i to moja wina, że nie miałem ich kopii zapasowych. W ofercie VPS'ów na freecast.pl nie ma wzmianki o backupach więc nie mogę mieć do nich pretensji, że nie zabezpieczyli moich danych. Mimo to, skoro robią te backup'y to mogliby je już tak robić aby były użyteczne dla ich klientów. To by z pewnością poprawiło wizerunek firmy w moich oczach. Ta bezsilność jest okropna gdy podejrzewasz/wiesz, że Twoje dane jednak gdzieś się zachowały ale i tak wkrótce zostaną skasowane i nie masz na to żadnego wpływu.

To jednak nic w porównaniu z drugą sytuacją, która wydarzyła się kilka dni temu. Oto treść maila jaki otrzymałem 29 września o godzinę 18:15 (formatowanie oryginalne):

W dniu 28.09.2011 około godziny 19.40 doszło do ingerencji osób trzecich na główny serwer odpowiadający za usługi VPS . W wyniku tego doszło do wykasowania danych z dysku serwera , dane osobowe nie zostały naruszone .Cała sprawa jest w toku dochodzenia przez organy ścigania .

Za zaistniałą sytuacje firma Marcin Kostrzewa S.M.pl

Bardzo Przeprasza

P.S.

W ramach rekompensaty nasza firma zobowiązuje się dla osób poszkodowanych udzieleniem 30 dniowego korzystania z usług za darmo , tym samym informujemy że usługi VPS zostaną na nowo aktywowane .

Poczuwamy się do odpowiedzialności

Administracja

Domyślałem się odpowiedzi, dopytałem jednak jeszcze czy backup'y także zostały skasowane. Odpowiedź była twierdząca. Klientom po jakimś czasie przywrócono czyste instalacje ich serwerów VPS.

Padli ofiarą przestępstwa i z pewnością nie są zadowoleni z takiego obrotu spraw. Mimo to, trudno ocenić całą sytuację inaczej niż totalną katastrofę. Czy na pewno wszystko było należycie zabezpieczone? Czy backup'y były na tej samej maszynie czy na osobnej? Czy żaden pracownik nie popełnił błędów, które przyczyniły się/spowodowały ten armagedon? Nie mam pojęcia i pewnie nigdy się nie dowiem.

Sam nie ucierpiałem w tym jakoś strasznie. Serwer i usługi trzeba skonfigurować od nowa, przepadły też niektóre dane ale z rozmysłem ich nie kopiowałem, nie były mi już niezbędne. Natomiast wszystko to co ważne, mam skopiowane i trzymam w bezpiecznym miejscu. Obawiam się jednak, że inni klienci freecast.pl nie są w takiej dobrej sytuacji.

Próby (czasami udane) ataków/włamań na serwery to codzienność administratorów. Bez względu na przyczyny takich zdarzeń, klient ma prawo oczekiwać, że nawet w najczarniejszym scenariuszu jego dane przetrwają. Chociażby kopie sprzed kliku dni ale żeby coś zostało. Freecast.pl nie zdało egzaminu.

Życzę podniesienia się z tej klęski. Dostałem "gwarancje ze taka sytuacja się nie powtórzy". Mam nadzieję, że będą w stanie dotrzymać słowa i znajdą się jeszcze klienci, którzy im zaufają.

PS
Oby sprawcy zostali wykryci. Trzeba być naprawdę łajdakiem żeby robić takie rzeczy!

EDIT 2011-10-18
Byłem wyjątkowo wyrozumiały dla freecast.pl ale bałagan jaki tam mają skutecznie mnie do nich zniechęca. Mimo obiecanych 30 dni zadośćuczynienia za to, że przepadły moje dane, nadal automat kazał mi opłacić rachunek za następny miesiąc. Gdy nie opłaciłem, konto wygasło i przez weekend nie działało. Po mojej interwencji przywrócili je w poniedziałek. Na szczęście ze wszystkimi danymi.

EDIT 2011-10-25
Warto pisać o nieprawidłowościach! Ktoś z freecast.pl czytał mój wpis bo link podano w dyskusji o hostingu na webhostingtalk.pl i doczekaliśmy się nawet odpowiedzi na moje zarzuty. A przed chwilą w mojej skrzynce pojawił się taki oto e-mail:

Witamy

mamy dla Państwa miłą informacje z dniem dzisiejszym wszystkie serwery VPS naszych klientów będą posiadały kopie bezpieczeństwa , która będzie wykonywana codziennie o 5 rano na osobny serwer .Dziękujemy za uwagę.

Chyba można zaryzykować stwierdzenie, że miałem na to jakiś wpływ :) Cieszy mnie taki obrót spraw, nie wszystko jeszcze stracone! :)

EDIT 2011-11-02
Nie mogę sobie odmówić kolejnego dopisku :D Otóż dostałem dzisiaj rano informację od freecast.pl o konieczności opłacenia faktury bo za dwa tygodnie mój VPS wygasa. Taki zwykły komunikat, nic specjalnego. Problem w tym, że od godziny 5:00 do godziny 5:59 włącznie takich maili dostałem... 61! Oni to jednak mają talent :D


Szachy online z otwartym źródłem

26 września 2011

Przeglądając github.com w poszukiwaniu czegoś na czym mógłbym podszkolić się z Symfony 2 natknąłem się na ciekawy projekt. Ktoś stworzył aplikację (PHP5 + JS + HTML5) do gry w szachy i udostępnił całe źródło. Co prawda wygląda na to, że sam silnik odpowiedzialny za grę nie jest napisany w PHP "ale też jest zajebiście", cytując klasyka ;)

Projekt nazywa się lichess i jest naprawdę imponujący, zwłaszcza biorąc pod uwagę, że jest prowadzony przez jedną osobę. Szczegóły techniczne:

- PHP 5.3.2, użyto frameworka Symfony 2
- JavaScript (jQuery i jQuery UI)
- HTML5 i CSS
- "mózg" gry to Crafty Chess
- pgn4web służy do podglądu gier. Daje możliwość osadzania rozgrywek na stronie www, w prostej i miłej formie miniatury, bazuje na JavaScript.

Możliwości jakie aplikacja udostępnia graczowi są co najmniej wystarczające. Możemy grać z innymi ludźmi lub z komputerem (dla komputera wybieramy jeden z ośmiu poziomów trudności). Wybieramy między grą standardową a Chess960. Decydujemy także czy gramy z zegarem.

Każda gra ma swój unikalny adres. W ten sposób rozgrywkę może śledzić więcej osób a po rozegranej grze można prześledzić wszystkie ruchy i zobaczyć cały zapis rozgrywki. Dostępny jest katalog wszystkich rozgrywanych w tej chwili i wcześniej rozegranych gier.

Dzięki zastosowaniu JS i HTML5 gra się bardzo przyjemnie, przeglądarka w żaden sposób nas nie ogranicza. Funkcji jest wiele, nie będę ich wszystkich wymieniał. Jeszcze więcej jest planów, które autor przedstawia na liście TODO.

Twórca zapowiada, że cały projekt będzie zawsze darmowy, open source a strona gdzie można wszystko wypróbować (lichess.org) będzie zawsze wolna od reklam. Kimkolwiek jest, jestem pod wrażeniem jego pracy. Na pewno prześledzę kod PHP, to jest z pewnością nieocenione źródło wiedzy podczas nauki Symfony 2.


Parsowanie kodu CSS w PHP

23 września 2011

Zdarza się czasami, że musimy wykonać jakąś bardzo specyficzną pracę programistyczną. Mi to się niestety zdarza aż za często :) Tak było i tym razem. Musiałem zamienić pobrany kod CSS na coś bardziej strawnego, najlepiej na tablicę PHP. Przy tego typu zadaniach dobrze jest zacząć od Google, znaleźć rozwiązanie, użyć i zapomnieć. Niestety z tym znajdowaniem nie zawsze jest tak różowo...

Przeszukałem dość dokładnie Internet pod kątem parsowania kodu CSS w PHP. Znalazłem kilka, może kilkanaście rozwiązań ale z większością z nich były jakieś problemy. Skoro już przez to przeszedłem to chyba dobrze byłoby napisać o tym kilka słów i zaoszczędzić innym nieszczęśliwcom trochę pracy.

Zacznę od prostego, anonimowego kawałka kodu, który znalazłem gdzieś w sieci. Po lekkich poprawkach prezentuje się w taki sposób:

PHP:
  1. function parse_css($css) {
  2.  
  3.   preg_match_all('/(?ims)([a-z0-9\s\.\:#_\-@]+)\{([^\}]*)\}/si', $css, $parsed);
  4.  
  5.   $result = array();
  6.  
  7.   if(isset($parsed) AND !empty($parsed) AND isset($parsed[0]) AND !empty($parsed[0]) AND isset($parsed[1]) AND !empty($parsed[1]) AND isset($parsed[2]) AND !empty($parsed[2])) {
  8.  
  9.     foreach($parsed[0] AS $key => $value) {
  10.  
  11.     if(isset($parsed[1][$key]) AND isset($parsed[2][$key])) {
  12.  
  13.         $selector = trim($parsed[1][$key]);
  14.        
  15.         if($selector != '') {
  16.           $rules = explode(';', trim($parsed[2][$key]));
  17.  
  18.           if(!empty($rules)) {
  19.             if(!isset($result[$selector])) {
  20.               $result[$selector] = array();
  21.             }
  22.  
  23.             foreach($rules AS $rule) {
  24.  
  25.               if(!empty($rule)) {
  26.                 $rule = explode(':', $rule);
  27.  
  28.                 if(isset($rule[0]) AND $rule[0] != '' AND isset($rule[1]) AND $rule[1] != '') {
  29.                
  30.                   $rule[0] = trim($rule[0]);
  31.                   $rule[1] = trim($rule[1]);
  32.                  
  33.                   if($rule[0] != '' AND $rule[1] != '') {
  34.                     $result[$selector][trim($rule[0])] = trim($rule[1]);
  35.                   }
  36.                 }
  37.               }
  38.             }
  39.           }
  40.         }
  41.       }
  42.     }
  43.   }
  44.  
  45.   return $result;
  46. }

Kod jest naprawdę prosty a efektem jego działania jest ładna tablica wielowymiarowa PHP z kluczami głównymi jako selektory CSS do których są przypisane pary właściwość <-> wartość.

Na tym właściwie mógłbym zakończyć tego newsa ale zdaję sobie sprawę, że niektórzy mogą mieć inne/większe potrzeby dlatego teraz krótki przegląd rozwiązań:

  • CSSTidy - Rozbudowane narzędzie, dostępne w dwóch postaciach: plik wykonywalny EXE oraz aplikacja PHP. Głównym zadaniem CSSTidy jest tak przerobić dany kod CSS aby zmniejszyć jego objętość wywalając niepotrzebne fragmenty i poprawiając niektóre definicje. Dostępna jest również kompresja kodu. Oczywiście aby wykonywać takie czynności, potrzebny jest rozbudowany parser CSS :) Osobiście go nie testowałem dlatego chętnie przeczytam każdą opinię. PS: Autorzy na stronie chwalą się, że nie użyli żadnych wyrażeń regularnych.
  • PHP CSS Parser - Nie testowałem ale wygląda na całkiem rozbudowany parser CSS, w wygodnej, obiektowej formie. Przyda się szczególnie tym, którzy nie tylko chcą coś z kodu CSS odczytać ale również go zmodyfikować.
  • PEAR HTML_CSS - Z PEAR praktycznie nigdy nie korzystałem, jakoś nie było potrzeby, nie mogłem się do tego przekonać... Z opisu wygląda zachęcająco. Nic więcej o tym nie mogę napisać ale mimo to umieszczam na liście bo część z Was na pewno ma duże zaufanie do PEAR.
  • CSS parser - Prosta i przyjemna w użyciu klasa za pomocą której łatwo wyciągniemy informacje jaka wartość została przypisana do właściwości dla danego selektora. Martwi mnie jedynie wiek tego kodu (rok "produkcji": 2003) i lista tagów HTML w źródle, która jest niepełna i na nasz grzbiet spadnie obowiązek jej uzupełnienia i aktualizowania w przyszłości.
  • CssMin - Oprogramowanie nastawione przede wszystkim na "kompresję" styli CSS ale z krótkiej analizy kodu wnioskuję, że używa bardzo ładnego i rozbudowanego parsera CSS. Chętnie przeczytam opinię jak to działa jeżeli ktoś pokusi się o testy/użycie ;)

Oprócz tej krótkiej listy istnieją oczywiście inne rozwiązania. Szczególnie sporo jest malutkich parserów zrzucających CSS do tablicy PHP ale kod przedstawiony przeze mnie powyżej sprawdza się wyśmienicie dlatego chyba można sobie darować inne klony.

Na koniec dodam, że warto przed obróbką parserem usunąć z kodu CSS wszelkie komentarze. Pewnie te bardziej zaawansowane parsery same się tym martwią ale te mniej rozbudowane już niekoniecznie. Oto kod:

PHP:
  1. $css = preg_replace('!/\*.*?\*/!s', '', $css);
  2. $css = preg_replace('/\n\s*\n/', "\n", $css);


W Internecie nic nie ginie

31 sierpnia 2011

Ostatnio mało tu piszę i sam jestem z tego powodu zawiedziony... Niestety praca mi się nigdy nie kończy i bardzo ciężko znaleźć chwilę na przyjemne rozmyślanie i przelewanie tego na ekran.

Mimo tego trzymam się mojej żelaznej zasady przynajmniej jednego tekstu na miesiąc :) Dlatego dzisiaj dodaję ostatni artykuł jaki napisałem dla Przeglądu Lokalnego Famka. Nigdy nie został opublikowany. Teksty okazały się chyba za ambitne, tabloidyzowanie wszystkiego postępuje...

Z oczywistych powodów artykuł nie jest techniczny ale polecam jego lekturę aby zapisać sobie w pamięci, że jeżeli naprawdę mocno potrzebujemy jakichś informacji to warto sięgnąć po narzędzia o których na co dzień nie pamiętamy i z których nie korzystamy.


Internet to ogromna baza informacji, która cały czas ewoluuje, zmienia się. Zdarza się również, że jakieś dane z Internetu znikają, trwale (są usuwane przez autora) lub tymczasowo (np. awaria serwera). Czy jesteśmy zdani na łaskę i niełaskę ludzi i maszyn przy dostępie do wiadomości? Czy istnieją inne sposoby dotarcia do wiedzy, gdy wszystko wskazuje na to, że nie jest już ona dostępna z poziomu naszej przeglądarki internetowej?

Błąd 404 – nie odnaleziono strony sieci Web
Ileż to razy poszukiwaliśmy pilnie jakiejś informacji i znajdując potencjalnie interesujący nas link do jakiegoś artykułu, okazywało się, że serwer z daną stroną WWW akurat uległ awarii, wyczerpał się jego transfer na aktualny miesiąc lub nastąpiła inna z tysięcy plag, jakie nękają witryny internetowe. Wielu z nas odchodzi „z kwitkiem” i mozolnie przeszukuje kolejne, niezliczone ilości stron. Nie wolno się jednak tak łatwo poddawać.

Mamy swoje sposoby
Z pomocą przyjdą nam wyszukiwarki internetowe. Indeksując Internet nie zapisują jedynie wybranych informacji o stronach a często całe witryny. W łatwy sposób możemy je poprosić, aby wyświetliły nam swoje kopie.

W Google istnieje prosty operator specjalny, cache:. Znając adres poszukiwanej przez nas witryny wystarczy zadać zapytanie w takiej postaci cache:radiofama.com.pl. Jeżeli mamy trochę szczęścia to ujrzymy kopię strony radiofama.com.pl z czasu, gdy robot Google odwiedzał tą witrynę ostatnim razem. Można również zwyczajnie wpisać zapytanie o interesującą nas treść do wyszukiwarki i przy wynikach kliknąć link Kopia.

Oczywiście nie jest to metoda zapewniająca sukces. Po pierwsze, nie cały Internet jest w ten sposób zapisywany jako kopie i może się zdarzyć tak, że akurat interesujące nas treści nie zostały zapamiętane. Po drugie, taka kopia jest czasami sprzed godziny, czasami sprzed dwóch dni a czasami sprzed tygodnia. Wszystko zależy od tego, kiedy ostatnim razem robot wyszukiwarki zapisał kopię witryny. To powoduje, że wyszukiwarka nie zawsze zwróci nam to, czego byśmy oczekiwali.

Google to nie wszystko
W Polsce i na świecie istnieją inne wyszukiwarki, które tworzą kopie odwiedzanych stron. Należy tu przede wszystkim wymienić bing.com, search.yahoo.com, polskie netsprint.pl, gooru.pl i szukacz.pl (w dwóch ostatnich kopie potrafią być nawet sprzed kilku lat) czy chociażby tak mało u nas znanego chińskiego giganta wyszukiwarkowego, baidu.com. Możliwości jest więc wiele i tylko od naszego zawzięcia zależy czy dotrzemy do upragnionych informacji.

Archiwum Internetu
Istnieje w Internecie pewien osobliwy wehikuł czasu. Nie ma lepszej metody, aby zobaczyć jak wyglądała Twoja ulubiona strona np. 5 lat temu. Wgląd do przeszłości umożliwi Ci strona archive.org. Jest to ambitny projekt zachowania elektronicznych śladów dziedzictwa kulturowego. Interesujący nas element działalności ludzi z Internet Archive nazywa się Wayback Machine i w praktyce pozwala podglądać jak powstawały nowe i zmieniały się stare strony internetowe. Zawartość Internetu indeksowana jest od 1996 roku. Jeżeli chcesz wiedzieć jak wyglądała pierwsza wersja portalu Onet.pl to archive.org jest dla Ciebie.


Zachęcam do dodawania w komentarzach do artykułu własnych pomysłów w jaki sposób odnajdywać to co w Internecie jest już pozornie niedostępne.