Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: sokzzuka, dodany: 18.01.2011 00:13, tagi: php, doctrine

Ostatnio wiele mówi się o bazach danych NoSQL (NotOnlySQL). Jako, że nie zauważyłem nic w polskim światku PHP na ten temat, stwierdziłem, że pora wypełnić tę lukę i zagłębić się w temat.

Czym są bazy NoSQL ?

Jak podpowiada nam ciotka wikipedia. Bazy NoSQL są to bazy danych, które nie są klasycznymi relacyjnymi bazami danych jakie znamy (MySQL,PostgreSQL etc). Termin NoSQL nie odpowiada żadnym wspólnym cechom tych baz, a raczej temu, że na pewno nie są one RDBMS-ami.

Popularne bazy NoSQL są magazynami danych. W przeciwieństwie do klasycznych odpowiedników nie posiadają stałego schematu, a dane przechowują jako pary klucz – wartość.

Jako przykład dla naszych rozważań wybrałem bazę MongoDB. Dlaczego akurat tą? Istnieją dwa główne powody. Pierwszym z nich jest to, że twórcy projektu Doctrine, stworzyli również ORM w wersji dla tej bazy. Drugim natomiast to, że baza jest szczególnie przyjazna dla webdeveloperów.

Jej przyjazność objawia się tym, że baza żyje i oddycha Javascriptem. Shell przyjmuje komendy tylko w tym języku. Natomiast odpowiedź na zapytania zwracana jest w formacie JSON. Ciekawą rzeczą, może mniej dla webdeveloperów a bardziej dla zwolenników funkcyjnego podejścia do programowania, jest to, że baza wspiera rozproszony model obliczeń oparty na paradygmacie map-reduce. Na roztrząsanie tego tematu czas przyjdzie później. Natomiast teraz przejdźmy do części praktycznej.

Instalacja

  1. Na stronie projektu, wyszukujemy odpowiednią dla nas paczkę i ściągamy
  2. Rozpakowujemy ją w dowolnym katalogu
  3. W głównym katalogu dysku tworzymy folder data/db
  4. W katalogu gdzie rozpakowaliśmy paczkę z bazą odpalamy plik bin/mongod.exe
  5. Z sourceforge ściągamy driver do php w postaci rozszerzenia (w archiwum są dll-e dla odpowiednich wersji php)

W tej chwili mamy już działającą bazę MongoDB. Kolejnym krokiem będzie zaprzęgnięcie Doctrine’a do pracy.

Struktura projektu:

|--application
|---model
|----MailBox
|------Message.php
|-----User.php
|--lib
|---vendor
|----Doctrine
|--proxies
|--index.php

Do katalogu Doctrine ściągamy ODM (Object Document Mapper).

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Śpiechu, dodany: 17.01.2011 22:43, tagi: php

Odrabiając zaległości na planecie PHP zainteresowałem się biblioteką filtrującą HTML Purifier zareklamowaną przez Kamila Brenka. Po wykonaniu kilku testów „popsucia kodu” i obserwacji jak biblioteka poradzi sobie z naprawieniem uznałem, że przydałoby się takie cudo w WordPressie. No i proszę: w oficjalnym repozytorium pluginów do WordPressa mamy wtyczkę filtrującą komentarze. Zwie się HTML Purified.

Co to w skrócie potrafi:

  • pozwala wybrać mechanizm filtrujący komentarze pomiędzy domyślnym wordpressowym KSES a zachwalanym wyżej HTML Purifier
  • możemy wybrać dozwolone tagi i atrybuty w komentarzach
  • możemy pozwolić wtyczce „naprawić” kod zawarty w komentarzu w 4 trybach:
    1. none — bez ingerencji w kod,
    2. lekki — poprawia wyłącznie elementy nieużywane w ustawionym DOCTYPE
    3. średni — wprowadza „najlepsze praktyki” (tak napisali w dokumentacji)
    4. ciężki — najbardziej zasobożerna transformacja tagów i atrybutów do spełniających standardy

Wtyczka na tyle mi się spodobała, że zrobiłem jej spolszczenie. Miałem nadzieję być w stanie umieścić je samodzielnie w repozytorium SVN wtyczki, ale wywala mi błąd 403. Próby kontaktu z autorem na razie bez odzewu. W razie dodania aktualizacji łaskawie o tym poinformuję.

Póki co ściągajcie ode mnie. (Najlepiej poprzez zapisz link jako…) pl_PL.mo pl_PL.po

Obydwa pliki należy umieścić w katalogu locale wtyczki.

Nie przyjmuję zażaleń apropos śmiesznego brzmienia słów escapowanie i back-ticki. Nie wiem jak to przetłumaczyć na w miarę krótką formę. Może jakieś propozycje?

Autor wpisu: Athlan, dodany: 15.01.2011 16:54, tagi: php.pl, mysql, sql

Nie raz, nie dwa mieliśmy sytuację, która wymagała od nas koniunkcji warunków większej ilości danych lub dane te były tekstowe, ale niedługie. Niby nic, klucze załatwiają sprawę, ale sięgając do kodu gry bukmacherskiej, musiałem ją nieco zoptymalizować pod względem częstego wyciągania danych. Baza rozrosła się dość szybko, dlatego niezbędna była lekka modyfikacja jej struktury.

Moim zadaniem było bardzo częste wyciągnięcie ID meczu, który musiał na raz (AND) być zgodny z żądaną datą, nazwą drużyny pierwszej oraz drugiej. Informacji do warunków dostarczał system. Oprócz daty, są to dane tekstowe, więc połączyłem je ze sobą CONCAT i stworzyłem z nich sumę md5. Indeks, po którym baza szukała, był już krótszy od warunków, bo zawierał zawsze 32 znaki. Pierwszym warunkiem koniunkcji zawsze była suma md5 wymienionych wcześniej pól rekordu, nazwałem to suma kontrolna rekordu, potem faktyczna wartość pól, aby w razie zdublowania sumy kontrolnej (czego się nie spodziewamy, bo zakres wariacji jest ogromny, ale dla idei) wybrać prawidłowy rekord. Do tej pory wystarczało…

Gdy baza rozrasta się, problemem staje się wyszukiwanie. O ile suma kontrolna to już krok w stronę optymalizacji, dla >100k rekordów, baza danych potrzebowała co najmniej 0.05 sekundy na zwrócenie wyniku. Postanowiłem dodać odcisk palca sumy kontrolnej. Najlepszym rozwiązaniem okazało się dodanie jednego bajtu, który zrobił magię w bazie danych. Jedno pole TINYINT – 8 bitów, zakres 0-255 bez znaku. Założenia odcisku palca:

  • jest wartością liczbową oraz zajmuje tylko jeden bajt, aby oszczędzić miejsca w rekordach oraz indeksach bazy danych,
  • nie musi być uniwersalny (unikalny), a jedynie grupować odciski palców w mniejsze, a liczniejsze zbiory.

Rozwiązanie, które zastosowałem przy generowanu odcisku palca sumy kontrolnej, również nie jest skomplikowane:

  1. Odcisk palca to suma kolejnych znaków sumy kontrolnej rekordu, gdzie 0 – 9 zachowują swoje wartości, a litery [a-f] przyjmują kolejno [10-15], dokładnie jak w przeliczaniu pojedynczych wyrazów systemu liczbowego o podstawie 16 (HEX) na dziesiętny.
  2. Skoro jest to suma, to wartość minimalna jest dla samych zer, zatem MIN = 0.
  3. Wartość maksymalną można stworzyć podając same maksymalne wartości F, zatem MAX = 480.
  4. 480 mieści się na 9 bitach (min. 2 bajty, zakres 0-65535 bez znaku, tracimy 65055 wartości), dzieląc liczbę przez 2 tracimy unikalność odcisku dwukrotnie, ale zmieścimy się na ośmiu bitach, czyli jednym bajcie – możemy użyć typu TINYINT (zakres 0-255 bez znaku, nasza to 0-240), zatem tracimy tylko 15 niewykorzystanych wartości.

Przeprowadzamy testy naszego rozwiązania.

Stwórzmy przykładową tabelę danych test_md5_index, która będzie przechowywała wartości tekstowe w polach data_content, data_content2, data_content3. Tabela może zawierać pole dodatkowe, ale te trzy będziemy wykorzystywać w naszym wyszukiwaniu. Ważnym jest to, że warunkiem jest koniunkcja (AND), dlatego możemy stworzyć sumę (analogicznie do sumy logicznej) md5 jako odcisk palca tych pól, który zapiszemy w data_sum varchar(32). Dodatkowo stworzymy odcisk palca odcisku palca – jednobajtowe pole data_sum_index TINYINT.

Od razu zakładamy klucz podstawowy na data_id oraz klucz dla zapytania, który będzie go wykorzystywał, czyli szukanie wspólnie po data_sum_index oraz data_sum.

CREATE TABLE test_md5_index (
  data_id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  data_sum_index tinyint(1) UNSIGNED NOT NULL,
  data_sum varchar(32) NOT NULL,
  data_contents text NOT NULL,
  data_contents2 text NOT NULL,
  data_contents3 text NOT NULL,
  PRIMARY KEY (data_id),
  KEY data_index (data_sum_index, data_sum)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

Pora stworzyć funkcję, która przeliczy nam nowy, krótszy odcisk palca na podstawie poprzedniego:

CREATE FUNCTION TestIndexChecksum(sSum VARCHAR(32)) RETURNS TINYINT
BEGIN
 
  DECLARE sSumPart VARCHAR(1);
  DECLARE iSumPart TINYINT;
  DECLARE iSum SMALLINT DEFAULT 0;
  DECLARE i INT;
 
  IF (SELECT sSum NOT REGEXP '^([a-z0-9]){32}$') THEN RETURN 0; END IF;
 
  SET i = 1;
 
  WHILE i <= LENGTH(sSum) DO
    SET sSumPart = SUBSTR(sSum, i, 1);
    SET iSumPart = (SELECT (CASE WHEN sSumPart = 'a' THEN 10 WHEN sSumPart = 'b' THEN 11 WHEN sSumPart = 'c' THEN 12 WHEN sSumPart = 'd' THEN 13 WHEN sSumPart = 'e' THEN 14 WHEN sSumPart = 'f' THEN 15 ELSE 0 END));
 
    IF iSumPart = 0 THEN
      SET iSumPart = sSumPart;
    END IF;
 
    SET iSum = iSum + iSumPart;
    SET i = i + 1;
  END WHILE;
 
  RETURN iSum / 2;
END;

Aby przeprowadzać testy, stwórzmy sobie procedurę, która wstawi nam N losowo, jakkolwiek wypełnionych rekordów do bazy danych:

CREATE PROCEDURE TestIndexesPrepareTest(IN i INT)
BEGIN
  TRUNCATE TABLE test_md5_index;
 
  WHILE i > 0 DO
 
    INSERT INTO test_md5_index SET
      data_contents  = (SELECT REPLACE(CONCAT(RAND() * 32), ".", "")),
      data_contents2 = (SELECT REPLACE(CONCAT(RAND() * 32), ".", "")),
      data_contents3 = (SELECT REPLACE(CONCAT(RAND() * 32), ".", "")),
      data_sum = CONCAT(data_contents, data_contents2, data_contents3),
      data_sum_index = TestIndexChecksum(data_sum);
 
    SET i = i - 1;
  END WHILE;
END;

Po wykonaniu CALL TestIndexesPrepareTest(100000) mamy przygotowane małe środowisko testowe.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Zyx, dodany: 15.01.2011 15:10, tagi: php

Na planecie PHP niedawno pojawił się wpis batmana poświęcony magicznym elementom języka PHP. Jako sam opis sprawdzał się całkiem fajnie, ale jak to już przy tego typu materiałach bywa - zabrakło porządnego rozwinięcia, kiedy i czy w ogóle magię powinno się stosować w swoich aplikacjach WWW. Ten wpis ma za zadanie wypełnić przynajmniej częściowo tę lukę, tym bardziej że obecnie największe projekty PHP zaczęły się od magii odwracać.

Autor wpisu: batman, dodany: 14.01.2011 22:43, tagi: javascript, jquery

14 stycznia 2006 roku światło dzienne ujrzała pierwsza wersja najpopularniejszej biblioteki JavaScript. Dzisiaj, w piąte urodziny, wydana została pierwsza beta jQuery 1.5. Według roadmap stabilna wersja ma się pojawić ostatniego dnia stycznia. Co nowego pojawi się w najnowszym wydaniu jQuery? Przede wszystkim przebudowany zostanie moduł $.ajax. Do tego dochodzi szereg usprawnień poprawiających i wydajność biblioteki oraz poprawiających błędy. Pełną listę zmian można znaleźć na blogu jQuery.

Autor wpisu: batman, dodany: 13.01.2011 08:00, tagi: php

Każdy język programowania ma swoje smaczki. W przypadku PHP smaczkiem tym są magiczne metody – znienawidzone przez jednych, nadużywane przez innych. Zastosowane z rozwagą i dobrze użyte mogą znacząco wpłynąć na rozwój kodu. Każda magiczna metoda rozpoczyna się dwoma znakami podkreślenia ( __ ). Twórcy języka wyraźnie zaznaczyli, że konwencja ta jest zarezerwowana wyłącznie dla magicznych metod i nie powinna być stosowana w innych przypadkach.

Konstruktor

Najczęściej używaną przez programistów PHP magią jest konstruktor. Oznaczony jako __construct odpowiada za inicjalizację obiektu. Konstruktor może przyjąć dowolną liczbę argumentów i wbrew pozorom nic nie zwraca.

class Foo
{
    protected $_zmienna;

    public function __construct($arg1 = null)
    {
        $this->_zmienna = $arg1;
    }
}

Jeśli zwrócimy coś w konstruktorze, dopiero jego jawne wywołanie spowoduje, że wartość ta będzie dostęna.

class Foo
{
    public function __construct()
    {
        return null;
    }
}

$foo = new Foo();
var_dump($foo->__construct()); // wyswieli NULL

Konstruktory mogą być podstępne, zwłaszcza jeśli korzystamy z dziedziczenia. Należy pamiętać, iż nadpisanie konstruktora spowoduje, że wykona się konstruktor zadeklarowany najniżej w hierarchii. Pozostałe musimy sami wywołać.

class Foo
{
    public function __construct()
    {
        echo 'Konstruktor Foo';
    }
}

class Bar extends Foo
{
    public function __construct()
    {
        echo 'Konstruktor Bar';
    }
}

class Baz extends Bar
{
    public function __construct()
    {
        echo 'Konstruktor Baz';
    }
}

$baz = new Baz();

Powyższy kod wyświetli tylko jeden tekst – Konstruktor Baz. Dopiero jawne wskazanie, że konstruktor rodzica też ma się wykonać, spowoduje wyświetlenie pozostałych tekstów.

class Foo
{
    public function __construct()
    {
        echo 'Konstruktor Foo';
    }
}

class Bar extends Foo
{
    public function __construct()
    {
        parent::__construct();
        echo 'Konstruktor Bar';
    }
}

class Baz extends Bar
{
    public function __construct()
    {
        parent::__construct();
        echo 'Konstruktor Baz';
    }
}

$baz = new Baz();

Powyższy kod wyświetli

Konstruktor Foo
Konstruktor Bar
Konstruktor Baz

Jak widać konstruktory wykonują się po kolei. Dzieje się tak dlatego, że wywołanie konstruktora rodzica jest pierwszą instrukcją. Dzięki możliwości sterowania momentem wywołania konstruktora rodzica mamy wpływ na proces inicjalizacji obiektów.

Destruktor

Przeciwieństwem konstruktora jest destruktor, który służy do sprzątania bałaganu po obiekcie. Metoda ta zostanie wywołana w momencie, gdy na dany obiekt nie wskazuje żadna referencja. Podobnie jak w przypadku konstruktorów, destruktory klas nadrzędnych należy wywołać samemu.

class Foo
{
    public function __destruct()
    {
        echo 'Destruktor Foo';
    }
}

class Bar extends Foo
{
    public function __destruct()
    {
        parent::__destruct();
        echo 'Destruktor Bar';
    }
}

class Baz extends Bar
{
    public function __destruct()
    {
        parent::__destruct();
        echo 'Destruktor Baz';
    }
}

$baz = new Baz();

Przeciążanie metod

W PHP nie ma możliwości zdefiniowania dowolnej ilości takich samych metod z różnymi parametrami. Jeśli ktoś spróbuje takie coś zrobić, niemiło się rozczaruje. Z pomocą przychodzi kolejna magia w postaci dwóch metod: __call oraz __callStatic. Obie metody działają w taki sam sposób, przy czym __call działa z poziomu obiektu, a __callStatic z poziomu klasy. Obie metody zostaną wywołane w przypadku gdy na obiekcie (__call) lub klasie (__callStatic) wywołana zostanie niezdefiniowana metoda.

Zarówno metoda __call jak i __callStatic przyjmują dwa argumenty. Pierwszym z nich jest nazwa wywołanej (nieistniejącej) metody, drugim tablica przekazanych do niej argumentów.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Daniel Burchardtt, dodany: 12.01.2011 23:05, tagi: php

Rosyjska firma ONsec opublikowała ciekawy raport dotyczący tego, jak PHP na Windowsie traktuje nazwy plików. Badanie pokazuje, że wszyscy którzy hostują swoje webaplikacje napisane w PHP na Windows, powinni jeszcze raz przyjrzeć się wszelkim regexpom i regułkom na IDS-ach…

Nazwy plików a PHP na Windows

Do stworzenia raportu badaczy zainspirował fakt, że w Windows interpreter PHP może z sukcesem odwołać się do pliku na 4 poniższe sposoby:

  • example.phP
  • example.php
  • example.ph>
  • example.ph<

Z przeprowadzonych przez ONsec testów wynika, że za błąd odpowiedzialna jest funkcja WinAPI FindFirstFile(). Badacze zauważyli, że znak > zastępowany jest tak naprawdę przez ? a < przez * i dodatkowo “ zastępowany jest przez .. Co ciekawe, ten bug jest znany Microsoftowi od roku 2007.

Po całość wpisu zapraszam na niebezpiecznik lub pouczyć się historii.

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.