Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: Śpiechu, dodany: 30.06.2010 19:46, tagi: php, zend_framework

W drugiej części napiszę co nieco na temat nazewnictwa klas i metod. Jak nazywać i czego unikać. Do tego na koniec dodam kilka zaleceń Roberta C. Martina z Czystego Kodu [Gliwice : Helion, 2010]. Klasy Składnikiem nazwy klasy nie powinien być żaden czasownik. Mało tego, nie powinien to być również fragment nazwy implementowanego interfejsu lub [...]

Autor wpisu: matipl, dodany: 30.06.2010 12:56, tagi: php

Xdebug - logoWczoraj Derick Rethans udostępnił w końcu Xdebug w wersji 2.1. W ciągu trzech lat (wersja 2.0 ukazała się w lipcu 2007) poprawione wszelkie błędy i skupiono się nad nowymi rozwiązaniami. Największą nowością jest pełna obsługa PHP 5.3 oraz  wsparcia wyłącznie dla PHP od wersji 5.1.

Xdebug w świecie PHP służy najczęściej do debugowania naszych aplikacji. Ale również posiada możliwość profilowania, jak i przeprowadzenia testu pokrycia kodu. D. Rethans dodał bardzo sporo nowości do Xdebuga, oto one:

  • kolekcja błędów Dodano funkcje xdebug_start_error_collection(), xdebug_stop_error_collection() i xdebug_get_collected_errors(). Zbierają one wszelkie powiadomienia, ostrzeżenia i błędy generowane z error_reporting.
  • gromadzenie nagłówków przez Xdebug Wszelkie funkcje ustawiające nagłówki HTTP (np. header(), setcookie()) są od teraz przechwytywane przez Xdebug. Dostęp mamy do nich poprzez xdebug_get_headers(), która zwraca tablicę.
  • śledzenie wszelkich przypisań do zmiennych Wprowadzono opcję xdebug.collect_assignments, która pozwala na rejestrowanie wszelkich zmian związanych ze zmiannymi w naszej aplikacji.
  • obsługa scream W PECL istnieje rozszerzenie scream wyłączające @ (wyciszanie). Od teraz Xdebug również posiada taką opcję, wystarczy ustawić w php.ini  xdebug.scream.
  • dodatki w stosie śledzenia Wszelki generowany kod HTML przez Xdebug posiada teraz klasy CSS, aby ułatwić łatwiejsze stylowanie.
  • przeciążanie var_dump Wprowadzono możliwość wyłączenia domyślnego przeciążania var_dump. Służy do tego parametr xdebug.overload_var_dump. W momencie gdy wyłączymy przeciążanie, mamy dostęp do Xdebugowej wersji poprzez xdebug_var_dump()

Jak widać przez te kilka lat zrobione kawał dobrej roboty przy projekcie Xdebug.

Download: Xdebug

Autor wpisu: sokzzuka, dodany: 29.06.2010 18:18, tagi: php

Dzisiaj Derick Rethans poinformował na swoim blogu o wydaniu finalnej wersji Xdebug-a 2.1. Ciekawe nowości:

  • funkcje do gromadzenia wszystkich errorów, które pojawiły się w czasie trwania skryptu
  • gromadzenie nagłówków
  • możliwość wyłączenia operatora uciszania „@”
  • output z var_dump teraz oparty jest na stylach dla łatwiejszego formatowania

Poza tym usunięto wsparcie dla starych protokołów debbugowania – gdb i php3 oraz poprawiono wiele drobnych błędów, w tym wywalanie się apache’a pod Vistą / Win7.

Autor wpisu: Vokiel, dodany: 27.06.2010 21:36, tagi: javascript, eclipse, php

Eclipse

23 czerwca 2010 r nastąpiło wydanie nowej wersji Eclipse 3.6 Helios . Owo wydanie jest największym z dotychczasowych wydań: 39 różnych zespołów projektowych, 33 miliony linii kodu, 490 commiterów. Eclipse udostępnia 12 różnych projektów, dla różnych typów programistów. W tym oczywiście dla programistów PHP – czyli Eclipse for PHP Developers . Czemu o tym piszę? Przede wszystkim dlatego, że Eclipse PDT jest moim ulubionym IDE, jest tym, na którym pracuję zawodowo, do którego jestem bardzo przyzwyczajony (dotychczas Eclipse Galileo).

Nowości w Eclipse Helios

Helios wprowadza wiele nowości, część z nich, z punktu widzenia web developera nie ma większego znaczenia. Jednak warto mieć na uwadze zaangażowanie twórców, różnorodność tworzonych rozwiązań, ilość zaangażowanych developerów.

1. Lepsze wsparcie dla Linuxa

Ostatnie badania wskazały na rosnący udział systemu spod znaku pingwina w ogólnej liczbie developerów korzystających z tego IDE. Twórcy Eclipse wyszli im naprzeciw wprowadzając szereg usprawnień dedykowanych pod systemy z tej kategorii. Stworzony został Linux Tools Project , który ma na celu ułatwienie pracy przy programowaniu w C/C++. Zintegrowano m.in. GNU Autotools, Valgrind, OProfile, RPM, SystemTap, GCov, GProf, LTTng, etc.

2. Eclipse Marketplace Client

Eclipse Marketplace

Eclipse Marketplace

Jest to klient zapewniający developerom dostęp do czegoś w rodzaju “app-store” z tą różnicą, że dotyczy wtyczek. Daje możliwość łatwego przeglądania i instalowania nowych plug-in’ów. Będzie dostępnych ponad 100 wtyczek w jednym katalogu, co ma znacznie ułatwić i usprawnić ich wybieranie i dodawanie do programu.

3. Wsparcie dla Git’a

Pojawiło się długo oczekiwane wsparcie dla Git’a (popularnego rozproszonego systemu kontroli wersji). Wprowadzone zostało w projektach EGit oraz JGit. Nowe wydanie EGit 0.8 zawiera nowy widok repozytoriów Git’a, wsparcie dla “fast forward merging” oraz tagowania. JGit 0.8 – które jest wykorzystywane w EGicie dla połączeń z repozytoriami Git pokazało duży skok wydajności aż do 50% podczas pracy z dużymi repozytoriami.

4. Nowości w Web Tools Platform

WTP wprowadza wsparcie dla tworzenia, uruchamiania i debugowania aplikacji napisanych pod najnowsze specyfikacje Java EE (Java EE 6) włączając Servlet 3.0, JPA 2.0, JSF 2.0, and EJB 3.1.

5. Poprawione wsparcie dla JSDT

Framework w JSDT

Framework w JSDT

Ulepszone wsparcie dla JSDT dla programistów JavaScript. W tym framework debugera JavaScript, który umożliwia integrację debugerów JavaScript, takich jak Rhino i Firebug oraz korzystanie z nich bezpośrednio w IDE. Został utworzony nowy pakiet Eclipse IDE for JavaScript Web Developers , który ma na celu ułatwienie programistom JavaScript odszukania, zainstalowania i korzystania z IDE na bazie Eclipse.

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

Autor wpisu: cojack, dodany: 27.06.2010 11:37, tagi: sql

PostgreSQL Nadeszła w końcu ta chwila, w której miałem wolny czas by usiąść i dokończyć implementację ltree. Udało mi się, uzyskałem to co chciałem, i to na czym by każdemu programiście zależało. Działa tak jak ja chce, a nie tak jak baza chce. Do rzeczy, w ostatnim i zarazem pierwszym wpisie o ltree w postgresie nie mogłem sobie poradzić z sortowaniem, kombinowałem razem z depeszem jak by go tu posortować, w końcu jakieś rozwiązanie padło. Tylko te rozwiązanie depesz wziął z swojej struktury drzewiastej, otóż mówię temu stanowcze NIE! Dlaczego? Ltree zostało napisane po to by nie robić nic rekursywnie, to po prostu miażdży podejście do drzew w każdym calu, żadne nested sety i inne śmiecie z rightem i leftem. Tam to idzie zęby połamać a nie to ugryźć. Poza tym jest to mało optymalne, to już wolę id, parent_id (taki joke).

Sortowanie w ltree

Rozwiązanie było bliżej niż można było się tego spodziewać. Miałem z trylion pomysłów jak to rozkminić. Pomyślałem o liczbie rzeczywistej której każda kolejna część po przecinku będzie przedstawiała nr zagłębienia, tylko to nie jest tak łatwo oprogramować i mogłyby wyjść niezłe kaszany, także odpuściłem sobie to. I olśniło mnie ARRAY! No jacha! To przecież jest tak proste i oczywiste że nie wiem o czym my rozmawiamy. Sam sobie ten problem urodziłem, a powodem tego było iż nikt wcześniej nie pisał o tym, w necie to nawet nie ma słowa o tym module, parę rzeczy znajdziemy w manualu i stronie twórców. Ale nikt nie pokwapił się z implementacją tego z sortowaniem i się nie podzielił.

Implementacja ltree z sortowaniem

Otóż sprawa jest banalnie prosta (teraz już jest):

CREATE TABLE "category" (
   "idCategory"  SERIAL PRIMARY KEY NOT NULL,
   "categoryPath"   LTREE,
   "ordering" INT[]
);

I mógłbym powiedzieć amen. Alę dodam jeszcze:

INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top', '{1}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Science', '{1,1}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Science.Astronomy', '{1,1,1}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Science.Astronomy.Astrophysics', '{1,1,1,1}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Science.Astronomy.Cosmology'. '{1,1,1,2}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Science.Astronomy.Planets'. '{1,1,1,3}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies', '{1,2}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies.Amateurs_Astronomy', '{1,2,1}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies.Swiming', '{1,2,2}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies.Football', '{1,2,3}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies.Chess', '{1,2,4}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies.Basketball', '{1,2,5}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies.Voleyball', '{1,2,6}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies.Checkers', '{1,2,7}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies.Cards', '{1,2,8}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies.Skis', '{1,2,9}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies.Post_Cards', '{1,2,10}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Hobbies.Book', '{1,2,11}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections', '{1,3}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures', '{1,3,1}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures.Astronomy', '{1,3,1,1}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures.Astronomy.Stars', '{1,3,1,1,1}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures.Astronomy.Galaxies', '{1,3,1,1,2}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures.Astronomy.Astronauts', '{1,3,1,1,3}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures.Astronomy.Planets', '{1,3,1,1,4}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures.Astronomy.Sun', '{1,3,1,1,5}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures.Astronomy.Earth', '{1,3,1,1,6}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures.Astronomy.Asteroids', '{1,3,1,1,7}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures.Astronomy.UFO', '{1,3,1,1,8}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures.Astronomy.Milk_Way', '{1,3,1,1,9}');
INSERT INTO category ( "categoryPath", ordering ) VALUES ('Top.Collections.Pictures.Astronomy.Space_Ships', '{1,3,1,1,10}');

To powyżej to demo do tabeli, o zapomniałbym o indeksach:

CREATE INDEX "categoryPath_gist_idx" ON "category" USING gist( "categoryPath" );
CREATE INDEX "categoryPath_idx" ON "category" USING btree( "categoryPath" );
CREATE INDEX "ordering_gist_idx" ON "category" USING gist( "categoryPath" );
CREATE INDEX "ordering_idx" ON "category" USING btree( "categoryPath" );

I sobie protestujcie sami jak to świetnie działa. W następnym i przy okazji ostatnim wpisie o ltree, przedstawię wszystkie metody do zarządzania drzewem, oraz widoki.

Autor wpisu: sokzzuka, dodany: 24.06.2010 20:07, tagi: php

Do napisania tego wpisu zainspirował mnie post u Zyx-a pod tym samym tytułem. Zyx przedstawił w nim świeżą koncepcję php-owego frameworka opartego o paradygmat MVC wraz z przykładami kodu. Uzasadnieniem dlaczego „wynajdywał koło na nowo” było to, że uważał, że istniejące frameworki tak na prawdę nie realizują paradygmatu MVC a tylko jego mutację zwaną też MVP. Ten artykuł nie jest bezpośrednio polemiką z Zyx-em a raczej bardziej próbą zademonstrowania podejścia alternatywnego zarówno do tego jakie prezentuj on jak i popularne frameworki.

Chciałbym więc przedstawić pewien zarys frameworka opartego o wzorzec MVP (a raczej MTV ;>) i zasady programowania funk(cyjnego/funkcjonalnego). Napisałem już jeden podobny framework do opisywanego na którym postawiona jest jedna z stron w moim portfolio i dobrze się sprawuje. Natomiast to co opisuje nie posiada jeszcze implementacji i jest w zasadzie kolejną iteracją mojej poprzedniej próby.

Dla jasności przypomnę jeszcze jakie są różnice między MVC i MVP. Oba wzorce służą do separacji warstwy prezentacji aplikacji (View) od warstwy logiki biznesowej (Model).

W MVC kontroler na podstawie requestu łączy odpowiednie modele z odpowiednimi widokami. Widok pobiera odpowiednie dane z modelu wg swojego uznania i tworzy odpowiedź.

W MVP kontroler wyciąga dane potrzebne do renderowania strony z modeli i przekazuje je do widoku. Jak widać w MVP widok nie jest zależny od modelu, po prostu renderuje dane, natomiast w MVC ma świadomość czym jest model (jaką klasą) i potrzebuje konkretnego interfejsu aby móc z nim się porozumiewać.

Wzorzec MVP powstał w celu zapewnienia lepszej testowalności i większej niezależności widoku od modelu.

Sposób działania mojego frameworka.Plik index:

$oContainerConfig = new CContainerConfigXml('config/object-config.xml');
$oFactory = new CContainerManager($oContainerConfig);
 
$oFlowConfig = new CFlowConfigXml('config/flow-config.xml');
$oExecutor = new CExecutor();
$oPageResolver = new CPageResolver($oFlowConfig);
 
$oFrontController = new CFrontController($oPageResolver, $oExecutor, $oFactory, $oFlowConfig);
 
echo $oFrontController->execute($_REQUEST, $_ENV, $_SERVER);

W pliku index widzimy kilka obiektów:

  • $oFactory jest kontenerem IoC, który konfiguruje wszystkie obiekty jakie istnieją w aplikacji.
  • $oFlowConfig jest obiektem który zwraca nam flow całej aplikacji.
  • $oExecutor jest obiektem wykonującym flow
  • $oPageResolver jest obiektem który na podstawie adresu zwraca informację jaka strona jest żądana oraz parsuje parametry

Przepływ sterowania wygląda tak:

  • PageResolver na podstawie $_SERVER i danych z FlowConfig wybiera stronę do pokazania
  • FrontController wyciąga z $oFlowConfig informacje o czynnościach, które należy wykonać dla danej strony oraz przekazuje je do $oExecutor aby je zrealizował
  • $oExecutor wykonuję odpowiednie Command-y i zbiera dane do widoku oraz zwraca je do FrontControllera
  • FrontController wyciąga z $oFlowConfig informacje o rodzaju widoku który wyrenderuje odpowiedź i przekazuje mu zmienne, zajmuje się również wszelkimi redirectami, które miałby wcześniej miejsce.
  • FrontController dostaje od widoku wyrenderowaną stronę i zwraca do index.php gdzie jest echowana
  • FrontController łapie również wszystkie wyjątki które mogą wystąpić i przeprowadza cały proces renderowania strony z błędem zgodnie z ww. flow

Teraz pewnie zastanawiacie się czym są wymienione między wierszami Command-y? Są to jakby pojedyncze akcje kontrolera, ale silnie wyabstrachowane. Zwracają array() z zmiennymi do widoku albo informacji o redyrekcji na inny adres. Reagują na konkretne eventy takie jak pojawienie się jakiejś zmiennej z get-a lub posta.

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

Autor wpisu: batman, dodany: 24.06.2010 17:30, tagi: jquery, javascript

Programiści pracujący nad jQuery UI wypuszczają co pewien czas kolejne milestone’y tej biblioteki. Dzisiaj światło dzienne ujrzał milestone 2, zawierający długo wyczekiwaną funkcjonalność – menu. Widżet ten zamienia standardową listę kotwic (znaczników a) w menu, obsługiwane zarówno myszką, jak i klawiaturą.

Równie ciekawym widżetem jest zaprezentowany w pierwszym milestone tooltip, którego zadaniem jest zastąpienie domyślnego, nieatrakcyjnego wizualnie tooltipa. Widżet ten jest w pełni konfigurowalny i dzięki czemu można dowolnie określić położenie tooltipa jak również jego wygląd.

Opis menu oraz tooltipa znaleźć można w dokumentacji jQuery UI pod adresami http://docs.jquery.com/UI/Menu oraz http://docs.jquery.com/UI/Tooltip.

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