Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: Tomasz Kowalczyk, dodany: 12.06.2011 22:20, tagi: doctrine, framework, php, symfony, symfony2

Nie ukrywam, że symfony jest moim ulubionym frameworkiem, jeśli mówimy o tych napisanych w języku PHP. Fabien Potencier stworzył naprawdę dobre narzędzie wspomagające tworzenie stron i aplikacji internetowych. Od pewnego czasu możemy usłyszeć o nowym przedsięwzięciu SensioLabs - frameworku Symfony2. Sf2 to zupełnie nowe podejście do tworzenia aplikacji internetowych, dlatego warto zapoznać się z możliwościami [...]

Autor wpisu: Zyx, dodany: 12.06.2011 13:06, tagi: php

Dzisiaj wydałem kolejną wersję mojej kolekcji automatycznych ładowarek klas Open Power Autoloader. Obok dodania wsparcia dla mechanizmu cech z nadchodzącego PHP 5.4, głównym powodem jej pojawienia się była chęć udostępnienia przydatnego narzędzia do optymalizacji i analizy procesu ładowania klas. Jednym z głównych powodów stosowania automatycznego ładowania jest chęć wczytania tylko tych plików, z których faktycznie korzystamy. Zauważmy jednak, że w każdej aplikacji mamy pewien zbiór klas ładowanych zawsze. Chciałem znaleźć ich listę i wygenerować zestaw komend require, które wczytają je "ręcznie". Tak powstał CoreTracker.

Autor wpisu: Athlan, dodany: 12.06.2011 00:11, tagi: php

Praktyka cache‘owania danych jest powszechna wśród programistów aplikacji webowych ze względu na optymalizację dostępu do danych bezpośrednio ze źródła ich pochodzenia, a w szczególności:

  • trudność dostępu (np. wykonanie skomplikowanych połączeń),
  • ograniczenia dostępu (np. limit odpytywania),
  • długi czas oczekiwania na dane; powodów jest wiele.

O ile tematyką stworzenia samego mechanizmu cache zajęli się m.in. Nospor, możecie podejrzeć jak to wygląda w Zend_Cache, Symfony, czy Kohana; tak ja chciałbym zwrócić uwagę na jeszcze jedną rzecz.

Zazwyczaj schemat kodu wygląda mniej więcej tak:

< ?php
$oCache = new Cache(); // tworzony jest jakis obiekt cache
 
if($oCache->expired(3600) || !is_array($aData = $oCache->load())) // sprawdzamy, czy jest cache i nie wygasł
{
  $aData = $oModel->GetSomething(); // zbieramy dane z bazy danych
  $oCache->save($aData);
}
 
// $aData przechowuje nasze dane do użytku
?>

Symulacja, parę linijek kodu, a ile nieszczęść.

Wszystko działa pięknie, dopóki nie spotkamy się z sytuacją, gdy setki osób (procesów) jednocześnie zechcą zbierać takie dane z bazy danych. Przeprowadźmy zatem krótką dywagację. Załóżmy, że użytkownik #1 wchodzi na stronę, stwierdza, że nie ma cache, lub jest nieświeży, wówczas przechodzi do połączenia się z bazą danych i zaczyna zbierać dane. W tym samym czasie, zanim użytkownikowi #1 zostaną zwrócone dane wchodzi użytkownik #2, który stwierdza, że nie ma cache, bo użytkownik #1 jeszcze nie zebrał danych, postanawia połączyć się z bazą i zrobić to samo, co użytkownik #1, powtarzając niepotrzebnie czynność i dodatkowo obciążając bazę. Można by iść dalej i wprowadzić n użytkowników, którzy powtarzają czynność, dopóki dane nie pojawią się w cache i kolejni użytkownicy będą z niego korzystać. Co się stanie natomiast, gdy kolejka tak narośnie, że użytkownikowi #1 zabraknie zasobów systemowych, aby ukończyć proces zbierania danych, co spowoduje, że pozostałym też? Kolejka będzie wydłużała się w nieskończoność, póki system operacyjny nie podejmie żadnych działań (np. odłączy bazę danych, lub po prostu wyłączy serwer, np. w IIS7 wyłączy cały application pool). Aby doszło do tej kolizji nie jest potrzebne wcale natężenie użytkowników, serwer może akurat np. zajmować się wysyłką maili lub nieoptymalnie zrobionym procesem, który zajmuje zasoby, a w tym czasie wejdzie tylko pięciu użytkowników.

Parę linijek kodu, a ile nieszczęść.

Pojęcie semafora.

Semafor w informatyce – jest chronioną zmienną lub abstrakcyjnym typem danych, który stanowi klasyczną metodę kontroli dostępu przez wiele procesów do wspólnego zasobu w środowisku programowania równoległego.

Więcej na temat semaforów na Wikipedii, bądź w Podstawy informatyki / Stefan Węgrzyn. – Warszawa : Państwowe Wydawnictwo Naukowe, 1982.

Podejście do problemu.

< ?php
$oCache = new Cache();
 
if($oCache->expired(3600) || !is_array($aData = $oCache->load()))
{
  $oCache->savePrepare(); // stawiamy semafor
 
  $aData = $oModel->GetSomething();
  $oCache->save($aData); // metoda save() może (nie musi) od razu zwolnić semafor, gdy próba zapisu się zakończy
  // jeżeli metoda save() nie zwalnia zasobu, możemy np. użyć:
  // $oCache->saveFinalize();
}
 
// $aData przechowuje nasze dane do użytku
?>

Rozwiązaniem jest zastosowanie semafora blokującego dostęp do zasobu (w tym przypadku abstrakcyjnie “cache”, mniej abstrakcyjnie może być to plik na dysku, przestrzeń w pamięci operacyjnej, rekord w bazie danych, cokolwiek, co cache przerzymuje). Dla wartości semafora = 1 zasób jest wolny (nieużywany, jest 1 cache), gdy jest mniejszy/równy 0 zasób jest zajęty, ktoś z niego “korzysta”. Zajętość zasobu powinna być sprawdzana przy próbie odczytu. Dopóki zasób nie zostanie zwolniony, nie będzie można określić, czy są dane w cache. Jeżeli nie można określić, czy dane są w cache, należy zaczekać na zwolnienie zasobu.

Teraz nasze rozwiązanie nie dopuści do przytoczonej w powyższym przykładzie sytuacji. Zanim cache nie zostanie odblokowany po próbie zapisu, nie uzyskamy odczytu, czekając na niego i nie przechodząc w skrypcie nigdzie dalej.

Gdy save() się nie powiedzie? Można zastosować timeouty odczytu na load(). Wówczas złapalibyśmy wyjątek i przeszli dalej do realizacji zapisu, tak, jakby semafora nie było.

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

Autor wpisu: singles, dodany: 11.06.2011 12:43, tagi: zend_framework

Kolejny krótki wpis, także w ramach autolansu ;)

Dla tych co nie mają, bądź nie śledzą Twittera, to informuję, że od kilku miesięcy Getting Started With Zend Framework 1.11 autorstwa Rob Allena dostępny jest po polsku (w tłumaczeniu mojej skromnej osoby;). Znajdziecie go tutaj.

Wiem, że podstawowym językiem developera jest albo powinien być angielski, ale może wersja w ojczystym języku pomoże niektórym w zrozumieniu działania ZF.

Autor wpisu: singles, dodany: 11.06.2011 12:33, tagi: php, zend_framework

Kolejny wpis z serii Zend Framework Quick Tip

Podstawowym elementem sporej liczby aplikacji internetowych jest datagrid – tabela, której zawartość można filtrować, sortować, z pagerem. W ostatnio wykonywanej aplikacji natrafiliśmy na potrzebę wykorzystania tych samych datagridów w kilku miejsach.

Potrzeba

Do stworzenia gridów wykorzystaliśmy do tego celu bibliotekę ZFDataGrid (która wymagała kilkunastu poprawek, ale i tak nie znaleźliśmy niczego lepszego). Utworzyliśmy jedną bazową klasę Grid i po niej dziedziczyły wszystkie gridy zawarte w aplikacji, definiując własne źródła danych, filtry czy też akcje. Do pełni szczęścia brakowało, aby ładowane były na żądanie, wykorzystując domyślny Zendowy autoloader. Okazało się, że jest bardzo prosty sposób na osiągnięcie takiej funkcjonalności.

Implementacja

ZF domyślnie mapuje kilka rodzajów zasobów (resources) na ścieżkę w strukurze plików. Należą do nich:

Zend Framework Base Resources

Lista domyślnie zdefiniowanych ścieżek w ZF - na bazie " Getting Started with Zend Framework 1.11" Roba Allen'a

Nam brakowało jeszcze prefixu Grid, który mapowałby na ścieżkę grids. Szybkie spojrzenie do manuala i mamy rozwiązanie. Wszystko ogranicziło się do dodania następującego kodu do Bootstrap.php:

/**
 * Register 'Grid', so they could be created the same way like forms, models, etc.
 */
protected function _initGridsAutoload()
{
    $this->getResourceLoader()
         ->addResourceType('grid', 'grids', 'Grid');
 
    //or for many custom resources
    /*
    $this->getResourceLoader()->addResourceTypes(array(
        'item' => array(
            'path'      => 'items/',
            'namespace' => 'Item',
        ),
        'task' => array(
            'path'      => 'some/deep/folder/tasks',
            'namespace' => 'Task'
        )
    ));
    */
}

Pierwszy parametr to wewnętrzny klucz dla loadera, drugi to ścieżka, pod jaką mają być szukane pliki – zaczynając od `application/’, a trzeci to prefix jakiego będziemy używać w aplikacji. I tyle :) Od tego momenu w można wykorzystywać konstrukcję:

$grid = new Grid_Users(); // autoload files application/grids/User.php

Podany przykład dla applicationNamespace = ” – w przypadku kiedy wykorzystujecie namespace powiedzmy My, albo App, będzie to oczywście `App_Grid_Users_.

Autor wpisu: batman, dodany: 11.06.2011 08:00, tagi: internet

Tytuł może być nieco mylący, ponieważ krótkie opisanie Bouce, wbrew pozorom nie jest łatwe. Czym jest Bounce? Jest to aplikacja online, która pozwala nanosić na wskazaną stronę internetową uwagi w postaci kolorowej ramki wraz z opisem w chmurce. Dzięki temu narzędziu w kilka chwil jesteśmy w stanie przesłać dowolne uwagi do dowolnej strony.

Jak to działa? Najpierw podajemy adres strony, którą chcemy opisać, następnie przy pomocy myszki zaznaczamy obszar, który chcemy opisać i na koniec wpisujemy nasz komentarz do chmurki. Chwilę później mamy gotowy link, który możemy wysłać autorowi strony. Jeśli z jakiegoś powodu nie możemy podać adresu strony, istnieje możliwość uploadowania obrazka, który chcemy w jakiś sposób opisać.

Aplikację znajdziecie pod adresem www.bounceapp.com.

Autor wpisu: Tomasz Kowalczyk, dodany: 10.06.2011 22:38, tagi: symfony, framework, php

Prowadzenie blogu ma, a przynajmniej powinno mieć na celu niesienie pomocy Czytelnikom. Czasem jednak trzeba też pomóc sobie - autorowi. Najlepiej jest wtedy, kiedy przy okazji spełniania tego pierwszego wymagania, spełnia się przy okazji to drugie. Ze względu na to, że tworzenie wpisów pomaga mi w uporządkowaniu wielu informacji kołaczących się nieskładnie w głowie, czasem [...]
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.