<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-7207760637314065424</atom:id><lastBuildDate>Wed, 14 Oct 2009 07:54:57 +0000</lastBuildDate><title>simons devBlog</title><description></description><link>http://simons-ifdesign.blogspot.com/</link><managingEditor>noreply@blogger.com (simons)</managingEditor><generator>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-7207760637314065424.post-4184606063792346550</guid><pubDate>Fri, 12 Sep 2008 14:58:00 +0000</pubDate><atom:updated>2008-09-12T13:13:05.851-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>php</category><category domain='http://www.blogger.com/atom/ns#'>wzorce projektowe</category><title>O Singletonie raz jeszcze</title><description>O Singletonie napisano już chyba wszystko. Ten, jakby nie patrzeć, wzorzec projektowy wzbudza bardzo wiele kontrowersji - ma tylu samo przeciwników co i zwolenników. Osobiście zaliczam się do tej drugiej grupy, choć niektóre argumenty jego przeciwników uważam za całkiem słuszne. No ale do rzeczy.&lt;br /&gt;&lt;h2&gt;Singleton - filozofia&lt;/h2&gt;Wyobraźmy sobie sytuację, w której piszemy klasę obsługi bazy danych. W jej konstruktorze wywoływana jest metoda odczytująca z pliku konfiguracyjnego dane, potrzebne do nawiązania połączenia z bazą. Dla lepszego zobrazowania problemu, załóżmy że plik konfiguracyjny ma strukturę dokumentu XML, którego odczytanie wymaga odwołania się do odpowiednich klas (np. DOMDocument). Dodatkowo niech nasz konstruktor nawiązuje połączenie z bazą, od razu po odczytaniu potrzebnych danych. Jak widzimy, operacji do wykonania jest całkiem sporo.&lt;br /&gt;W sytuacji, gdy będziemy musieli odwoływać się do obiektu tej klasy w wielu miejscach, dodatkowo w różnych od siebie plikach naszej aplikacji, każdorazowe tworzenie tego obiektu będzie bardzo nieefektywne. Z logicznego punktu widzenia, najlepszym rozwiązaniem byłoby utworzyć raz instancję tej klasy i używać jej później w miarę potrzeb. Takie rozwiązanie umożliwia właśnie Singleton.&lt;br /&gt;&lt;h2&gt;Singleton - implementacja&lt;/h2&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;class Singleton&lt;br /&gt;{&lt;br /&gt;    private static $_oInstance = NULL;&lt;br /&gt;&lt;br /&gt;    private function __construct() { }&lt;br /&gt;&lt;br /&gt;    private function __clone() { }&lt;br /&gt;&lt;br /&gt;    public static function getInstance()&lt;br /&gt;    {&lt;br /&gt;        $className = get_class();&lt;br /&gt;&lt;br /&gt;        if (is_null(self::$_oInstance)) return self::$_oInstance = new $className;&lt;br /&gt;&lt;br /&gt;        return self::$_oInstance;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Implementację Singletonu można opisać w kilku punktach:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;zablokowanie modyfikatorem private konstruktora i metody kopiującej obiekt,&lt;/li&gt;&lt;li&gt;przygotowanie prywatnego statycznego pola, które będzie przechowywać instancję klasy,&lt;/li&gt;&lt;li&gt;przygotowanie publicznej statycznej metody getInstance(), która zwracać będzie obiekt - jeżeli jest to pierwsze wywołanie, tworzy obiekt i zwraca go, zapisując do pola statycznego; jeżeli pole statyczne przechowuje już obiekt, metoda zwraca ten właśnie obiekt,&lt;/li&gt;&lt;/ul&gt;Jak widać, zamiast tworzyć w tradycyjny sposób obiekty (przy pomocy operatora &lt;span style="font-weight: bold;"&gt;new&lt;/span&gt;), instancje klas pobieramy przy pomocy naszej publicznej metody getInstance(). W przypadku powyższej klasy, byłoby to tak:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;$singleton = Singleton::getInstance();&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Dzięki temu mamy zagwarantowane, że zawsze będziemy mieć jedną jedyną instancję określonej klasy (poprzez modyfikator private przy konstruktorze, niemożliwe będzie utworzenie obiektu przy pomocy operatora &lt;span style="font-weight: bold;"&gt;new&lt;/span&gt;).&lt;br /&gt;&lt;h2&gt;Plusy i minusy&lt;/h2&gt;Główną zaletę Singletonu opisałem w powyższym przykładzie - nasz kod zyskuje na wydajności, dzięki ograniczonej liczbie wywołań konstruktora klasy. Przeciwnicy tego rozwiązania, przedstawiają zawsze jeden główny kontrargument - Singleton ukrywa pod obiektową otoczką zmienną globalną (a jak wiadomo, stosowanie zmiennych globalnych w programowaniu obiektowym jest bardzo nieeleganckie). Dobrze, załóżmy że zgodzimy się z tym argumentem. W tym miejscu zawsze na myśl przychodzi mi bardzo prosta riposta - Ci sami przeciwnicy Singletonu, używają w swoim kodzie zmiennych sesyjnych, które z logicznego punktu widzenia są zmiennymi super globalnymi (!). Nie mam nic przeciwko zmiennym sesyjny (gwoli wyjaśnienia), ich stosowanie jest bardzo powszechne (m.in. w mechanizmach uwierzytelniania). Z tego właśnie punktu widzenia, argumenty przeciwników Singletonu moim zdaniem tracą na znaczeniu.&lt;br /&gt;&lt;br /&gt;Wzorcem zbliżonym swoją filozofią do Singletonu, jest wzorzec &lt;b&gt;Fabryka&lt;/b&gt;, o którym tutaj jeszcze napiszę.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7207760637314065424-4184606063792346550?l=simons-ifdesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://simons-ifdesign.blogspot.com/2008/09/o-singletonie-raz-jeszcze.html</link><author>noreply@blogger.com (simons)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-7207760637314065424.post-1790747867715207788</guid><pubDate>Wed, 10 Sep 2008 14:50:00 +0000</pubDate><atom:updated>2008-09-10T09:45:39.620-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>framework</category><category domain='http://www.blogger.com/atom/ns#'>php</category><title>Zróbmy sobie framework - kurs PHP 5 - prolog</title><description>Witam wszystkich w prologu kursu. Czym będziemy się tutaj zajmować? Postaram się przekazać w przyjazny oraz co najważniejsze - w praktyczny sposób wiedzę na temat programowania w PHP 5. Kurs ten skierowany jest raczej do średnio-zaawansowanych programistów, nie będziemy tutaj omawiać podstawowej składni języka, operatorów etc. Zakładam, że osoby zainteresowane tym kursem posiadają podstawową wiedzę na ten temat. Zatem - zaczynajmy!&lt;br /&gt;&lt;br /&gt;Na wstępie postaram się wyjaśnić, dlaczego obiektem naszego zainteresowania będzie napisanie własnego frameworka. Pisząc różnorodne aplikacje, wyrabiamy sobie pewne nawyki programistyczne - dotyczy to zarówno nazewnictwa plików, budowania struktury katalogów czy sposobu przechowywania danych konfiguracyjnych. Przystępując do pracy nad każdym nowym projektem, niejako automatycznie sięgamy do tych samych rozwiązań, przez co możemy wyodrębnić je i stworzyć na ich podstawie tzw. szkielet aplikacji. Dopełnienie go odpowiednim dla danego projektu kodem, pozwoli na stworzenie pełnej aplikacji. Tak oto w kilku słowach można najprościej zdefiniować pojęcie frameworku.&lt;br /&gt;&lt;br /&gt;Wielu w tym miejscu mogłoby zadać pytanie - po co pisać własny framework, jeżeli dostępnych mamy wiele darmowych frameworków, napisanych przez zespoły programistów i przetestowanych przez społeczności ich używających? Odpowiedź na to pytanie jest prosta - nie będziemy tutaj wyważać otwartych drzwi. Celem tego kursu jest przedstawienie pewnej koncepcji programowania obiektowego w języku PHP 5, jak i również m.in. zapoznanie czytelnika z wzorcami projektowymi. Kurs ten należy traktować wyłącznie jako praktyczny trening. Po tym dość długim wstępie, czas najwyższy przejść do konkretów.&lt;br /&gt;&lt;h2&gt;Przygotowujemy warsztat pracy&lt;/h2&gt;Zanim przejdziemy do implementacji, zajmiemy się kilkoma, czysto technicznymi sprawami:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;strukturą katalogów i nazewnictwem plików,&lt;/li&gt;&lt;li&gt;przygotowaniem wirtualnego hosta do testowania kodu,&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Struktura katalogów&lt;/span&gt; została zaprezentowana na poniższym obrazku:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_oIJYRGuRxkc/SMfri4-n4PI/AAAAAAAAABQ/pYL0MmcEfv8/s1600-h/struktura_katalogow.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_oIJYRGuRxkc/SMfri4-n4PI/AAAAAAAAABQ/pYL0MmcEfv8/s320/struktura_katalogow.png" alt="" id="BLOGGER_PHOTO_ID_5244419275739357426" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Katalog &lt;span style="font-style: italic;"&gt;/framework&lt;/span&gt; jest naszym katalogiem nadrzędnym, zawiera dwa podkatalogi - &lt;i&gt;apps&lt;/i&gt; oraz &lt;i&gt;core&lt;/i&gt;. W pierwszym z nich będą przechowywane katalogi aplikacji, tworzonych na bazie frameworka (na powyższym obrazku mamy przedstawioną strukturę katalogów przykładowego projektu - first_app). Każda aplikacja zawierać będzie katalogi:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;cache&lt;/span&gt; (tutaj będą przechowywane pliki cache),&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;config&lt;/span&gt; (pliki konfiguracyjne),&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;controllers&lt;/span&gt; (kontrolery aplikacji),&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;models&lt;/span&gt; (modele aplikacji),&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;views&lt;/span&gt; (widoki aplikacji),&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;web&lt;/span&gt; (pliki dostępne z poziomu przeglądarki),&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;templates&lt;/span&gt; (pliki szablonów)&lt;/li&gt;&lt;/ul&gt;Dodatkowo katalog &lt;span style="font-style: italic;"&gt;web&lt;/span&gt; zawierać będzie dwa podkatalogi - &lt;span style="font-style: italic;"&gt;frontend&lt;/span&gt; i &lt;span style="font-style: italic;"&gt;backend&lt;/span&gt;, dzielące aplikację na część użytkową oraz administracyjną, odpowiednio. Ponadto znaczenie każdego z tych katalogów zostanie dokładnie wyjaśnione w dalszej części, gdy będziemy zajmować się implementacją odpowiednich elementów.&lt;br /&gt;&lt;br /&gt;Mając przygotowaną strukturę katalogów, zajmiemy się stworzeniem wirtualnego hosta. Zakładam, że serwer Apache jest już zainstalowany na komputerze czytelnika, przejdziemy zatem do opisania procedury tworzenia wirtualnego hosta (jeżeli serwer Apache nie jest jeszcze zainstalowany, odsyłam do &lt;a href="http://httpd.apache.org/docs/1.3/install.html"&gt;źródeł&lt;/a&gt; lub skorzystania z ulubionej wyszukiwarki). Jako użytkownik linuxa, opiszę metodę dla tego systemu, a dokładniej - dystrybucji &lt;a href="http://ubuntu.com/"&gt;Ubuntu&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Krok 1:&lt;/u&gt; tworzymy plik [nazwa_wirtualnego_hosta].conf w lokalizacji /etc/apache2/sites-available (w naszym przykładzie utworzymy host o nazwie front-framework):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# sudo vim /etc/apache2/sites-available/front-framework.conf&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Krok 2:&lt;/u&gt; uzupełniamy utworzony plik konfiguracyjny:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;VirtualHost *&amp;gt;&lt;br /&gt;ServerName front-framework&lt;br /&gt;DocumentRoot /home/simons/framework/apps/firs_app/web/frontend&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;b&gt;Uwaga&lt;/b&gt;: w sekcji DocumentRoot podajemy poprawną, lokalną ścieżkę!&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Krok 3:&lt;/u&gt; ładujemy plik konfiguracyjny:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# sudo a2ensite front-framework.conf&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Krok 4:&lt;/u&gt; dodajemy wirtualnego hosta do pliku /etc/hosts&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# sudo vim /etc/hosts&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Do pliku dodajemy na końcu:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;127.0.0.1 front-framework&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Zapisujemy i zamykamy plik.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Krok 5:&lt;/u&gt; przeładowujemy Apache:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# sudo /etc/init.d/apache2 reload&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Po przejściu przez te 5 kroków możemy cieszyć się nowo utworzonym hostem - wpisujemy w przeglądarce adres &lt;code&gt;http://front-framework&lt;/code&gt;, aby sprawdzić poprawność konfiguracji. Jeżeli wszystko poszło dobrze, w oknie przeglądarki powinniśmy zobaczyć pusty listing plików katalogu &lt;i&gt;frontend&lt;/i&gt;.&lt;br /&gt;&lt;h3&gt;Podsumowanie&lt;/h3&gt;We wstępie do kursu udało nam się przygotować dwie, bardzo istotne rzeczy - strukturę katalogów oraz wirtualnego hosta, na którym będziemy testować kod.&lt;br /&gt;Na koniec jeszcze kilka słów wyjaśniających naszą strukturę katalogów. Jednym z głównych czynników, jakie kierowały mną przy jej ustalaniu było bezpieczeństwo. Zwróćmy uwagę, że z poziomu przeglądarki użytkownicy nie będą mieć możliwości odczytania zawartości katalogów innych niż ten, na który wskazuje domena - w naszym przykładzie jest katalog &lt;span style="font-style: italic;"&gt;frontend&lt;/span&gt;. Dzięki temu pliki konfiguracyjne i źródłowe pozostają bezpieczne.&lt;br /&gt;Drugą rzeczą, na którą chciałbym zwrócić uwagę, to struktura katalogu &lt;span style="font-style: italic;"&gt;apps&lt;/span&gt;. Znajdować się w nim będą katalogi aplikacji, ułożone w odpowiednich katalogach. Dzięki temu rozwiązaniu, wiele aplikacji będzie mogło współdzielić pliki źródłowe naszego frameworka w ramach jednego serwera. Dla przykładu wyobraźmy sobie, że napisaliśmy 10 aplikacji na bazie frameworka. Wszystkie aplikacje przechowywane będą na jednym serwerze, zatem struktura katalogu apps będzie prezentować się następująco:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;apps/&lt;br /&gt;&amp;nbsp; &amp;nbsp;app_1/&lt;br /&gt;&amp;nbsp; &amp;nbsp;app_2/&lt;br /&gt;&amp;nbsp; &amp;nbsp;app_3/&lt;br /&gt;&amp;nbsp; &amp;nbsp;...&lt;br /&gt;&amp;nbsp; &amp;nbsp;app10/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Jak łatwo zauważyć, nie trzeba będzie dziesięciokrotnie kopiować katalogu &lt;i&gt;core/&lt;/i&gt; z plikami źródłowymi frameworka. Zyskujemy dzięki temu jeszcze jedną ważną rzecz - w przypadku wprowadzenia istotnych zmian w kodzie źródłowym, zmiany będą widoczne od razu we wszystkich aplikacjach współdzielących kod.&lt;br /&gt;&lt;br /&gt;W następnym odcinku zajmiemy się już implementacją podstawowych elementów frameworka. Skupimy naszą uwagę na programowaniu obiektowym, wykorzystamy możliwości jakie daje nam PHP w wersji piątej. Do zobaczenia wkrótce!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7207760637314065424-1790747867715207788?l=simons-ifdesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://simons-ifdesign.blogspot.com/2008/09/zrbmy-sobie-framework-kurs-php-5-prolog.html</link><author>noreply@blogger.com (simons)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oIJYRGuRxkc/SMfri4-n4PI/AAAAAAAAABQ/pYL0MmcEfv8/s72-c/struktura_katalogow.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-7207760637314065424.post-1888782000032322339</guid><pubDate>Wed, 10 Sep 2008 00:24:00 +0000</pubDate><atom:updated>2008-09-10T05:12:16.081-07:00</atom:updated><title>Pierwszy wpis...</title><description>Od dłuższego już czasu nosiłem się z zamiarem rozpoczęcia redagowania własnego bloga - do tej pory brakowało niestety odpowiedniej ilości czasu, aby słowa wprowadzić w czyn. Jednak z tą oto chwilą, a właściwie tym pierwszym wpisem, rozpoczynam swoją przygodę z blogowaniem.&lt;br /&gt;&lt;h2&gt;O czym będę pisać?&lt;/h2&gt;Przede wszystkim chciałbym podzielić się swoją wiedzą z zakresu programowania aplikacji webowych (głównie w języku PHP 5), jednak postaram się na tym nie kończyć i poruszyć kilka około-programistycznych tematów.&lt;br /&gt;&lt;br /&gt;Kończąc ten krótki, kilku zdaniowy wstęp, chciałbym zaprosić wszystkich do czytania i komentowania treści, jakie będą się tutaj pojawiać. Mam nadzieję, że znajdzie się choć jedna osoba, która znajdzie tutaj coś ciekawego dla siebie.&lt;br /&gt;Pozdrawiam!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7207760637314065424-1888782000032322339?l=simons-ifdesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://simons-ifdesign.blogspot.com/2008/09/pierwszy-wpis.html</link><author>noreply@blogger.com (simons)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item></channel></rss>