Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: Athlan, dodany: 17.07.2010 12:04, tagi: sql

Oblicza MySQL nie są do końca znane przy tworzeniu aplikacji, a problemy optymalizacyjne stają się nie lada problemem przy funkcjonowaniu wersji produkcyjnej projektu. Nie sposób przewidzieć wszystkich możliwości użycia pól, założenia zarówno wspólnych, jak i pojedynczych indeksów posiadających zakładaną przez nas moc i zajętą pamięć na dysku.

Ostatnimi czasy budowałem dość skomplikowany projekt, jeżeli chodzi o złożoność zapytań i wykonywanych przez nie operacje matematyczne. Pomimo tego, że aplikacja była doskonale przemyślana, a struktury bazy danych perfekcyjnie jej podporządkowane, gdzieś tkwił problem, bowiem jedno z zapytań generowało pozornie prosty (wizualnie) rezultat, baza reagowała na zapytanie dopiero po 2.5 sekundy dla 30k+ rekordów. Patrząc na strukturę kluczy i zapytania, zwłaszcza, że pola, na których operowałem były różnego rodzaju liczbami i datami zacząłem się poważnie martwić i rozkładać zapytanie na czynniki pierwsze, kończąc na warunkach. Wyobraźcie sobie moje zdziwienie, gdy doszedłem do tego, że całe obciążenie (ponad 2.3 sekundy) generował warunek:

WHERE DATE(ticket_date) >= " ... "

Gdzie ticket_date to pole typu DATETIME. Od razu doszedłem do wniosku, że w parze idzie złe przygotowanie danych przez PHP, a angażowana jest w to wszystko baza, na której forsuje się użycie funkcji DATE(). Przynajmniej dla 30k+ rekordów zindeksowanego pola. Prosty zabieg zamiany jednej linijki kodu na drugą przyniósł porządane efekty.

$aTerms[] = 'DATE(ticket_date) >= "' . $sDate . '"'
$aTerms[] = 'ticket_date >= "' . date('Y-m-d H:i:s', strtotime($sDate)) . '"'

Budując aplikację zwracam szczególną uwagę na strukturę bazy, indeksowanie pól, rysuję diagramy przewidujące wykorzystanie danych pod różne zapytania, ale… tak banalny błąd przy przeanalizowanej aplikacji rozłożył mnie na łopatki. Z drugiej strony, zapomniałem o jednej bardzo ważnej rzeczy: maksymalnym odciążeniu bazy danych przy preparowaniu argumentów warunków, skoro warunki te mogą być w odpowiedni i przede wszystkim szybki sposób spreparowane na poziomie modelu (abstrakcyjnie rzecz ujmując, pozbywam się pojęcia PHP), który przygotują zapytanie tylko do wykonania operacji na surowych danych, bez konieczności ich ewentualnego przeliczania. Oczywiście nie zawsze taki efekt da się uzyskać, ale należy to maksymalnie optymalizować.

Jedno jest wiadome: przeliczanie DATE() dla rekordów w warunku jest nieoptymalne dla pola DATETIME.

Autor wpisu: batman, dodany: 15.07.2010 20:16, tagi: php

Pisałem wczoraj o projekcie umożliwiającym tworzenie aplikacji PHP działających na Androidzie. Dzisiaj twórcy projektu zaprezentowali nowe logo oraz zaktualizowali roadmap.

Logo jest miksem pehapowego słonia oraz zielonego androida i nazywa się Pfaewok.

W kwestiach technicznych również zaszły pewne zmiany. Zaktualizowana została mapa projektu (roadmap) i obecnie wygląda następująco:

  • lipec – sierpień 2010
    • testy wersji 0.1 i wprowadzanie poprawek do znalezionych błędów
    • uzupełnienie manuala oraz dokumentacji, m. in. opisu dotyczącego instalacji i korzystania z emulatora
  • wrzesień – październik 2010
    • wypuszczenie wersji 0.2
    • udostępnienie repozytorium z kodem źródłowym
    • stworzenie issue trackera
    • kolejne modyfikacje manuala i dokumentacji
  • listopad – ? 2010
    • wydanie kolejnej wersji projektu
    • aktualizowanie projektu wraz z aktualizacjami SL4A
    • aktualizacja manuala i dokumentacji

Autor wpisu: sokzzuka, dodany: 15.07.2010 00:19, tagi: php

Pewnego dnia, jadąc w nocy na rowerze zamyśliłem się na temat klas, funkcji i obiektów. Przemyślenia te zawiodły mnie do pewnych ciekawych wniosków. Nie będę ich tutaj w tej chwili przytaczał, natomiast wpadł mi do głowy pewien ciekawy pomysł jak zrealizować wzorzec singleton w alternatywny sposób, opierając się na funkcjach anonimowych.

Czym jest wzorzec Singleton ? Pokrótce mówiąc, stosujemy go jeżeli a) chcemy mieć tylko jedną instancję obiektu, b) jeżeli chcemy aby nasz obiekt był globalnie dostępny.

Jednym z wzorców, który korzysta z singletona jest rejestr, większość z Was pewnie używała go w Zendzie gdzie jest nagminnie wykorzystywany. Dla przypomnienia:

//inicjalizacja singletona
$oReg = Zend_Registry::getInstance();
//ustawienie zmiennej w rejestrze
$oReg->jakis_klucz = 'jakas wartosc';
//pobranie
echo $oReg->jakis_klucz;

Jedną z rzeczy, którą uważam za złą w tej implementacji od strony filozoficznej jest to, że klasy generalnie definiujemy po to by tworzyć wiele instancji danego obiektu. W tym przypadku potrzebujemy tylko jeden egzemplarz, stosując klasy trzeba używać więc dodatkowych sztuczek. Natomiast zamiast tworzyć klasę i bawić się w Singletona z klasą rejestru stworzyć taką oto zgrabną funkcję:

function Registry($key, $value = null){
    static $reg;
    if($value === null){
        return $reg[$key];
    } else {
        $reg[$key] = $value;
    }
}
//ustawianie
Registry('a','b');
Registry('d','e');
//pobieranie
echo Registry('a');
echo Registry('d');

Jak widać implementacja jest prosta jak budowa czołgu t-52 i realizuje wszystkie założenia rejestru – jedna instancja i globalna dostępność elementów które przechowuje.

Przejdźmy dalej i spróbujmy zaimplementować Singletona w podobny sposób, ale już jako konkretny obiekt z metodami. Klasyczne podejście wygląda mniej więcej tak:

class My_Singleton {
    protected static $_instance = null;
    private $_prywatna1 = 'aaa';
    private $_prywatna2 = 'bbb';
 
    protected __construct(){
 
    }
    public getInstance(){
        if(self::$_instance === null){
            self::$_instance = new self;
       }
       return self::$_instance;
    }
    public function method1(){
        echo $this->_prywatna1.' <br/>';
        $this->_prywatna2 = 'ccc';
    }
    public function method2(){
        echo $this->_prywatna2.' <br/>';
    }
}
 
My_Singleton::getInstance()->method1();
My_Singleton::getInstance()->method2();

Alternatywne podejście:

class Proxy {
    function  __call($name,  $arguments) {
        if(is_callable($this->$name)){
            return call_user_func_array($this->$name, $arguments);
        }
    }
}
 
function Singleton() {
    static $self;
    //konstruktor pol
    if($self == null) {
        $self = new stdClass();
        $self->_prywatna1 = 'aaa';
        $self->_prywatna2 = 'bbb';
    }
    //konstruktor metod
    static $oObj;
    if($oObj == null) {
        $oObj = new Proxy();
        $oObj->method1 = function() use ($self) {
                    echo $self->_prywatna1.' <br/>';
                    $self->_prywatna2 = 'ccc';
                };
        $oObj->method2 = function() use ($self) {
                    echo $self->_prywatna2.' <br/>';
                };
    }
 
    return $oObj;
}
 
Singleton()->method1();
Singleton()->method2();

Technika przedstawiona powyżej jest bardzo podobna do programowania opartego na prototypach, z jakim mamy np do czynienia w JavaScript’cie. Jedyną różnicą w ciele metod „metoda1″ i „metoda2″ jest zastąpienie zmiennej $this, zmienną $self, spowodowane tym, że $this jest zastrzeżoną nazwą zmiennej. Przykład spełnia założenia Singletona – jedna instancja i dostępność w kontekście globalnym. Jedyną wadą tego rozwiązania jest to, że nie da się dziedziczyć po takim obiekcie, mam wrażenie jednak, że nie jest to koniecznie potrzebne.

Ciekawy jestem Waszego zdania o tej technice, zapraszam do komentowania ;)

P.S przykłady działają tylko w PHP 5.3.x

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

Autor wpisu: batman, dodany: 14.07.2010 18:00, tagi: php

Na blogu PHP Classes pojawił się dziś ciekawy wywiad z Iván Mosquera Paulo, głównym deweloperem PHP for Android. Opowiada on o nowym projekcie, którego celem jest umożliwienie tworzenia aplikacji na telefony wyposażone w system operacyjny Android w języku PHP. Zasada działania jest prosta. Najpierw należy zainstalować ASE (Android Scripting Environment), czyli środowisko, które pozwala na tworzenie i wykonywanie skryptów mających dostęp do API systemu operacyjnego. Następnie należy zainstalować PhpForAndroid.apk, który tak na prawdę nie jest aplikacją, tylko zbiorem niezbędnych komponentów, bez których aplikacje PHP nie będą działać. W skład pakietu wchodzi PHP CLI z zainstalowanymi dwoma modułami – socket oraz JSON. Jak widać nie ma tutaj żadnego serwera, na którym wykonują się skrypty PHP.

Projekt ma dopiero jeden dzień (wystartował 13.07.2010) i jeszcze długa droga przed nim, jednak można już zobaczyć jak wygląda przykładowy kod:

require_once("Android.php");
$droid = new Android();
$droid->vibrate();

Jak widać kod jest banalny i raczej nie wymaga wyjaśnienia. Oczywiście “prawdziwe” aplikacje będą dalece bardziej złożone, jednak już teraz widać jak będą one tworzone. Więcej przykładów można znaleźć w manualu.

Projekt jest zbyt świeży, by można w jakikolwiek sposób ocenić czy ma szansę powodzenia. W znacznej mierze sukces tej technologii będzie zależał od społeczności, która powstanie wokół tego projektu oraz od aplikacji jakie będą powstawać.

źródło: www.phpclasses.org/blog

Autor wpisu: sokzzuka, dodany: 14.07.2010 08:39, tagi: php

W najnowszym wpisie na internalsach, Johannes Schlüter ogłosił, że wersje RC3 php 5.2.14 i 5.3.3 powinny trafić do obiegu najdalej w piątek. Natomiast wypuszczenie finalnych wersji planowane jest na 22-iego lipca.

Autor wpisu: sokzzuka, dodany: 13.07.2010 00:10, tagi: php

Po przeczytaniu wpisu na blogu Cyśka stwierdziłem, że jednak świadomość rozumienia istoty modelu w świecie PHP wymaga poprawy i stąd ten artykuł. Opiszę w nim jeden ze sposobów tworzenia warstwy modelu, a dokładnie metodologię DDD. Dla pobieżnego zapoznania się z tematem polecam Wikipedię, natomiast ja będę starał się rozwinąć ten temat tutaj i pokazać go na przykładach, czego większości opisów brakuje. Jeszcze słowem wstępu powiem, że metodologia DDD nie tylko mówi jak zaprojektować warstwę modelu, oprócz tego odnosi się również do prowadzenia samego projektu informatycznego ukierunkowanego na stworzenie gotowego produktu. Metodologia DDD w kwestii prowadzenia projektu mówi, że model domeny nigdy nie jest ukończony, jego powstawanie wiążę się ze stałym kontaktem z klientem. Rozmawiając z klientem porozumiewamy się z nim w języku domeny czyli w terminologii danego zagadnienia. Wielu z Was pewnie łapię się za głowę i pyta – po co to wszystko ? Przecież żeby postawić stronę wizytówkę nie potrzeba żadnej magicznej terminologii i kontaktów z klientem… I macie racje, generalnie metodologie DDD stosuje się do projektów o skomplikowanej logice, czyli generalnie do aplikacji dedykowanych. Nikomu raczej bym jej nie polecał stricte do budowania CMS-a, chociaż można wykorzystać pewne jej elementy.

Wracając do języka domeny. Zdefiniujmy sobie przykładowy problem, załóżmy, że mamy do wykonania dedykowana aplikację hurtowni internetowej w której będziemy obsługiwać klientów korporacyjnych. Rozmawiając z klientem będziemy używali takich terminów z języka domeny jak: kontrahent, faktura, księgowanie, przedstawiciel handlowy, towar, oferta handlowa, zamówienie. W tradycyjnym podejściu z pewnością kontrahenta i przedstawiciela handlowego nazwalibyśmy Userem, towar produktem, zamówienie koszykiem a oferta handlowa była by jakimś tam rabatem. Rozmawiając z klientem w sposób tradycyjny w przypadku jakichkolwiek błędów w naszej aplikacji spotykamy się z sytuacją gdy obie strony mówią niby o tym samym ale zupełnie co innego mają na myśli co generuje dodatkowe błędy. Miałem (nie) przyjemność pracować przy projekcie, w którym właśnie nastąpiło rozminięcie się terminologii pomiędzy klientem a wykonawcą aplikacji i powiem Wam, że nie życzę nikomu tego doświadczenia.

Pewnie u części z Was w tym momencie zaświeciła się nad głową żarówka i wpadliście na z pozoru świetny pomysł „ale co nas obchodzi język domeny, rolą projekt managera jest to, żeby nam przełożył język domeny na coś zrozumiałe dla nas programistów”. W metodologii DDD, kładzie się nacisk na to, by używać języka domeny również w kodzie (nazwy metod, klas, pól, zmiennych), dzięki temu gdy następują jakieś zmiany w modelowanym przez nas zagadnieniu (a jest to proces ciągły i nieskończony) możemy odnaleźć w naszych klasach metody, które dokładnie odpowiadają zachowaniu się modelowanej domeny. Efektem ubocznym takiego podejścia jest to, że programista uczestniczący w projekcie prowadzonym w terminologii DDD staje się stopniowo specjalistą w danej dziedzinie, a przynajmniej zaczyna się w niej orientować.

Podsumowując, w tym wpisie dowiedzieliśmy się czym jest Domain Specific Language i jaką rolę odgrywa w budowaniu modelu oraz jakie konsekwencje niesie ze sobą jego używanie bądź nie używanie. W drugiej części serii postaram się zaprezentować jak przełożyć DSL na konkretny kod.

Mam nadzieje, że zainteresowała Was ta tematyka i liczę na Wasze pytania i komentarze ;)

Autor wpisu: widmogrod, dodany: 11.07.2010 20:29, tagi: php, zend_framework

Niezależnie od rodzaju, wielkości i skomplikowania aplikacji internetowej można wyróżnić w niej kilka podstawowych (prawie zawsze występujących) elementów; autoryzacja, model, prezentacja danych, itp.

Przykład wyglądu i zastosowania KontorX_DataGrid

KontorX_DataGrid

Ten wpis chciałbym poświęcić bardzo powszechnemu elementowi – prezentacji, a dokładniej prezentacji danych tabelarycznych z j.ang. „data grid”. Notorycznie napotykamy ten element w prawie każdym panelu administracyjnym. Przybiera on różne formy w zależności od postawionych wymagań. Można wyróżnić:

Formy prezentacji danych tabelarycznych

  • Podstawową – dane są prezentowane w tabeli HTML bez możliwości sortowania, filtrowania i stronicowania
  • Rozszerzoną - tabela z możliwościami stronicowania i filtrowania kolumn danych
  • Dedykowaną- rozwiązanie jest połączeniem w/w typów z elementami rozszeżającymi, np.:
    • tabelę z możliwościami eksportowania danych tabelarycznych do różnych formatów (csv, pdf, itp…)
    • spersonalizowany wygląd komórek danych w zależności od typu: data, godzina, waluta, url, grafika, ….
    • możliwość edycji danych w bezpośrednio w wierszu tabeli (inline editing)
    • prezentacja danych za pomocą biblioteki JavaScript (np. Ext.DataGrid i inne,… )

Rodzaje istniejących bibliotek poruszających ten problem

Natywne PHP:

JavaScript + PHP:

Powyższe biblioteki implementują mniej lub więcej form prezentacji danych. Każda z nich wymaga wykonania kilku „ruchów” by je skonfigurować ale czy można prościej?… Tak. Dlatego chciałbym w tym wpisie omówić bibliotekę – KontorX – jest to biblioteka, którą nieprzerwanie rozwijam od  prawie 3 lat. Bibliotekę KontorX zawiera w sobie wiele elementów a jednym z nich jest KontorX_DataGrid.

Czym jest biblioteka KontorX_DataGrid

Biblioteka umożliwia elastyczne prezentowanie danych tabelarycznych w dowolny sposób i prawie w dowolnej formie. Poniżej przedstawiam główne cechy biblioteki:

  • Adaptowanie danych różnych typów np. Doctrine, Zend_Db_Table, Zend_Db_Select, natywna tablica – array, …. (więcej w budowie :) )
  • Różnorodna forma prezentacji danych. Data_Grid prezentuje dane jako czysty HTML oraz dynamiczny widok ExtJS Grid. Biblioteka pozwala również na implementacje nowych sposobów prezentacji danych np. jako plików .csv, .xls, .pdf.
  • Integracja z Zend_Form.
  • Zbiór gotowych rozwiązań. Biblioteka posiada już zaimplementowane elementy odpowiedzialne za filtrowanie, grupowanie i stronicowanie danych.
  • Elastyczność i rozszerzalność poprzez dopisywanie plugin’ów.

Powyższy opis może nie wiele mówić dlatego zapraszam do przykładów demonstrujących, niektóre możliwości komponentu: http://kontorx.widmogrod.info/#http://kontorx.widmogrod.info//KontorX/DataGrid/example1.php

DataGrid – „Out of the box”

Jeżeli korzystasz z ZF wystarczy że pobierzesz bibliotekę z Google Code umieścisz ją w include_path aplikacji i zaimplementujesz powyższy kod w kontrolerze wybranej akcji przekazując model danych (na chwilę obecną zaimplementowałem obsługę Zend_Db_Table, Zend_Db_Select, array).

Biblioteka posiada już zaimplementowany domyślny sposób prezentacji danych więc niczym nie musisz się martwić  (jedynie tabelę możesz ostylować w/g własnych upodobań :) )

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

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