Mar 11 2009

phpQuery - zdzieranie strony po selektorach CSS

Tag: PHP, Programowanieradmen @ 12:52

Jakiś czas temu odkryłem bardzo ciekawą bibliotekę -
phpQuery. Czym ona jest ? Przedewszystkim jest to biblioteka pozwalająca na wyciąganie elementów HTMLa (po stronie PHP), za pomocą selektorów CSS.

Czy to się przydaje? Owszem, nawet bardzo. Przykładowych zastosowań jest wiele. My to wykorzystaliśmy przykładowo do “poprawiania” podczas zapisu embedowanych filmów z YT.  Problem polegał na tym, że w dokumencie xHTML 1.1 Transitional nie można używać elementów <embed/>. Firefox i Opera sobie z tym radziły, IE natomiast sypał się i krzyczał, że nie może załadować strony.

Jak trzeba było to rozwiązać ? Musieliśmy pobrać z elementu <embed> atrybuty type i src, a później przepisać je do elementu <object> i <param name=”movie”>. Normalnie to byłoby pewnie masa roboty. Jakiś preg_match, preg_replace i inne cuda. Jak my to rozwiązaliśmy? Całkiem łatwo:

Wydaje się proste, prawda? Zalet jest wiele, wypunktuję najważniejsze:

  • pobieranie elementów strony za pomocą selektorów CSS
  • manipulowanie tymi elementami (dodawanie klas, stylow)
  • pobieranie atrybutów wybranych elementów.
  • iteracja na wielu elementach
  • możliwość tworzenia nowych elementów, zastępowania starych oraz wyplucie tego wszystkiego jako HTML
  • można nawet stworzyć za jego pomocą całego HTMLa (coś na zasadzie new Element(’div’))

Jakie dalsze plusy?

  • łatwa obsługa - naprawdę w bardzo łatwy sposób można pobrać dowolny element, oraz modyfikować je. Wystarczy odrobinkę znać składnię jQuery, ale jest to bardzo intuicyjne
  • w szybki sposób można “naprawiać” stronę (chociażby problemy z embedowanymi filmami YT)
  • szybko możemy modyfikować dane, bez używania skomplikowanych regexpów/etc
  • możemy parsować nie tylko HTMLa, praktycznie każdy XML przejdzie

Możliwości tej biblioteki są naprawdę spore. Pamiętajmy jednak, że nie zawsze dobrze jest wystawiać armatę przeciw komarowi. Ze względu na swój rozmiar może się okazać, że lepiej będzie użyć jakiś natywnych klas, które szybciej sobie poradzą z naszym problemem.


Jan 08 2009

Index na wielu polach, a kolejność tych pól

Tag: MySQLradmen @ 11:54

Dzisiaj walczyłem z dość prostym, aczkolwiek powolnym zapytaniem SQL. Problem pewnie polegał na tym, że dane były pobierane z tabeli o ~50k rekordach, sortowane, grupowane itd.

Owe zapytanie wyglądało mniej więcej tak:

Co ciekawe to zapytanie było strasznie powolne - czas wykonania 1,7s.  Dodatkowo zapytanie EXPLAIN dobiło faktem, że zapytanie typu SIMPLE musi wykorzystywać tabele tymczasową.

Aby całość przyspieszyć założono indeks na pola firstname i lastname

Oraz odpowiednio zmodyfikowaliśmy zapytanie:

Całość działała poprawnie i, co najważniejsze, szybko. Okazało się, że zapytanie ma jedną wadę. Sortowanie ma być najpierw po polu lastname, a potem po polu firstname. Okazuje się, że prosta zamiana kolejnością pól w wyrażeniu ORDER BY skutkuje spowolnieniem czasu wykonywania.

Fakt, czy będziemy grupować najpierw po polu firstname, a później po polu lastname nie miał znaczenia, dlatego postanowiono na zamianę kolejności tych pól, oraz poprawienie indeksu.

Dodatkowo drobna zmiana zapytania na:

I całość śmiga, aż miło :)

Okazuje się, że dla serwera MySQL kolejność pól w zakładanym indeksie ma wpływ na późniejszy czas wykonywania zapytań.


Nov 28 2008

Programmer blindness

Tag: Programowaniedooshek @ 12:08

Znacie na pewno termin “banner blindness” który określa rodzaj chwilowej ślepoty użytkownika na prezentowane mu bannery. Użytkownik podświadomie unika wzrokiem elementów mrugających lub też po prostu wyglądających jak bannery.

Ostatnio rozmawiając z programistami na temat problemu testowania aplikacji pisanych przez nich wpadłem na pomysł stworzenia terminu programmer blindness.

Continue reading “Programmer blindness”


Nov 19 2008

Mapy odsyłaczy a mapy :)

Tag: CSS, HTML, JavaScriptskowron @ 09:05

Podgląd mapki

Ostatnimi czasy po raz kolejny, przy okazji tworzenia serwisu narciarskiego, musiałem stworzyć obsługę mapki z krajami. Same linki do poszczególnych krajów same w sobie nie stanowią żadnego problemu. Pojawia się on w momencie gdy dany kraj po najechaniu na jego terytorium, ma się podświetlić.

Przykład:
http://blog.desmart.com/wp-content/uploads/2008/mapa/

Rozwiązanie:

HTML:

JS (wymaga biblioteki
mootools):

Opis:

Obiekt JS dodaje do każdego z elementów <area> akcje mouseover i mouseout. Po najechaniu na kraj pobierany jest jego id które umożliwia ustawienie odpowiedniej classy elementowi #hover_el. W plikach css zdefiniowane są pozycje x i y, grafiki z podświetlonymi poszczególnymi krajami oraz ich rozmiary. Dzięki temu element #hover_el pojawia się w odpowiednim miejscu. Event mouseout służy tak naprawdę tylko do usuwania jakiegokolwiek zaznaczenia, gdy użytkownik wyjedzie poza mapkę.

Do rozwiązania pozostał jeszcze jeden problem. Element #hover_el jest divem więc nijak nie zmusimy go aby był poligonem (zawsze będzie prostokątem). Przesuwając więc kursor z jednego kraju o nieregularnym kształcie na inny nierzadko mogliśmy spotkać się z sytuacja gdy podświetlenie nie znikało z poprzedniego kraju, ponieważ kursor wciąż znajdował się na aktywowanym elemencie. Oto przykład:

map_problem.png

Przedstawiony powyżej kod posiada już obejście tego problemu. Nakłada on mapę odsyłaczy nie na sam plik z mapą ale na przeźroczystego gifa:

<img src=”/images/blank.gif” id=”big_map_europe_dot” usemap=”#map-europe” alt=”"/>

który znajduje się na samej górze, pod nim przemieszczany jest #hover_el a na samym dole wyświetlana jest mapa.

warstwy.png

Takim oto sposobem możemy cieszyć oko funkcjonalną mapą europy :)


Sep 23 2008

Sumowanie pól, które mogą mieć wartość NULL

Tag: MySQLradmen @ 11:20

Niedawno odkryłem dość irytujący problem w MySQL. Otóż okazuje się, że nie można sumować wartości NULL z dowolną cyfrą. Wynik takiego zapytania:

Zwróci nam wartość NULL. Jak na mój chłopski rozum to powinna być wartość 5. Ten mały problem, może czasami całkiem sprawnie pokrzyżować jakieś zliczania/etc przez co wyniki, które otrzymamy mogą mijać się z rzeczywistością.

Na szczęście udało mi się znaleźć całkiem zgrabne rozwiązanie. Jest nim funkcja COALESCE, która zwraca pierwszą nie-pustą wartość podaną podczas wywołania. Drobna modyfikacja zapytania i mamy poprawny wynik:


Sep 19 2008

Usuwanie wszystkiego przed hashem w URLu (JS)

Tag: HTML, JavaScript, Przeglądarkiradmen @ 04:09

Dzisiaj miałem dość ciekawą sytuację, której rozwiązanie zajęło mi dobre 20 minut. Otóż na linki nałożyłem event onClick. Po kliknięciu na nie odczytywałem z atrybutu ‘href’ co tam w nich jest (dodam, że każdy url miał href’a - “#cos”), usuwałem hash’a i wykonywałem jakąś czynność w zależności od tego co zawierał.

Usuwanie hasha wykonywałem całkiem banalnie. Najpierw za pomocą metody Mootoolsowej pobierałem atrybut ‘href’ (metodą getAttribute) i później już tylko zamieniałem:
href.replace(/#/, '');

Oczywiście Firefox łykał to wszystko bardzo ładnie. Niestety IE7 już nie. Co się okazało ? IE wstawiało do atrybutu href pełen adres przez co zamiast mieć tam “#foo” miałem “http://serwer.com/#foo”. Jak łatwo można się domyślić nie byłem w stanie wyłapać tylko tego co jest za hashem, dlatego trzeba było nieco zmodyfikować pattern na coś takiego:
href.replace(/.*#/, '');

Teraz wszystko gra i efekt jest dokładnie taki jaki miał być :) Dziwne są cuda IE :P

PS. sprawdziłem sobie na innej stronce podobny mechanizm, ale w surowym JSie. Wszystko wskazuje na to, że to JSowe frameworki same wycinają pełną nazwę hosta. Na stronie
jogger.pl odpaliłem z konsoli JS Firebuga taki kod:
document.getElementsByClassName('next')[0].href

Wynikiem był pełen URL, wraz z nazwą hosta. Natomiast wykorzystany na tamtej stronie
jQuery zwracał jedynie wartości od hash’a do końca linii.


Sep 01 2008

IE 8 Beta2 na VirtualPC

Tag: Programy, Przeglądarkidooshek @ 01:40

Właśnie znalazłem info, że wyszła druga wersja beta IE8. Problemem jest to, że po instalacji może nie dać się już go odinstalować (znamy Microsoft prawda? :)

Jest jednak rozwiązanie! Microsoft wspaniałomyślnie
udostępnia obrazy dysku do ich
VirtualPC na których można potestować sobie nie tylko IE8 Beta2 ale też np. IE6!

Nie testowałem jeszcze ale już zaciągam (dla zainteresowanych obrazy będą dostępne na faramirze).


Aug 27 2008

VirtualBox - wirtualny komputer

Tag: Programydooshek @ 11:40

Zapewne większość zna
Vmware. Znalazłem ostatnio odpowiednik darmowy
VirtualBox wspierany bodajże przez Sun’a. Nie sprawdzałem w działaniu ale warto chyba go obadać.


Aug 20 2008

Małe a cieszy - czyli do czego może się przydać COUNT(DISTINCT …)

Tag: MySQLbirkin @ 01:14

O rety.. Przeszedłem długą drogę, JOIN.. GROUP BY.. FROM (SELECT …) i oczywiście i tak nie chciało działać.. A potrzebowałem pewnej prostej rzeczy, którą opiszę na prostym przykładzie: w bazie trzymam n-zamówień, zaś każde zamówienie może być podzielone na x-części, przy czym każda ta część ma swój status (np.: zgłoszone, zapłacone, wysłane…). Problem: w jaki sposób wyciągnąć jednym zapytaniem wszystkie zamówienia, przy czym chce również wiedzieć czy poszczególne zamówienia posiadają części o różnych statusach. Nic nie działało i tak o to trafiłem w tajemnicze COUNT(DISTINCT), i okazało się, że właśnie ta funkcja robi wszystkie skomplikowane rzeczy, które ja próbowałem tworzyć w ciągu pół godziny :)

Przykład zastosowania:


Aug 07 2008

Alternatywa dla sIFRa?

Tag: JavaScriptdooshek @ 10:46

Znamy już w miarę dobrze
sIFRa używaliśmy go przy okazji np. strony
GetZZZ. Dzisiaj znalazłem podobne
rozwiązanie które nazywa się FaceLift.

Generuje on obrazki z różnymi czcionkami w locie po stronie serwera czyli PHP + GD a nie jak sIFR po stronie przeglądarki (Flash). Na pewno jest łatwiejszy w implementacji jednak nigdzie nie doczytałem informacji o obsłudze UTFa. Jakiś czas temu próbowałem za pomocą GD zrobić parę polskich “krzaków” ale niestety nie wyszło mi to :(

Być może było to winą niepoprawnej czcionki (która nie miała w sobie znaków z puli UTF8) -  nie badałem tego tak dokładnie. Innym problemem z generowaniem obrazków po stronie serwera jest jego obciążenie. Oczywiście wygenerowany obrazek jest cachowany po stronie serwera (a więc napis jest generowany tylko raz) pozostaje jednak problem, że nadal wszystkie takie obrazki są przetwarzane przez PHP.

W przypadku “zwykłego” pobierania obrazków jest on serwowany bezpośrednio przez Apache’a, w przypadku generowanego niestety zawsze uruchamiany jest PHP co dodatkowo obciąża serwer (niewiele ale jednak). Rozwiązaniem jest nasz pomysł z wcześniejszym sprawdzaniem (przed wygenerowaniem strony) czy dany obrazek znajduje sie w cache’u i wygenerowanie URLa bezpośrednio do obrazka zanjdującego sie w cacheu.


« Previous PageNext Page »