Autor wpisu: eRIZ, dodany: 03.06.2010 23:50, tagi: php
Jak pewnie niektórzy zdążyli się dowiedzieć, miałem okazję gościć na konferencji PHPCon 2010. Minął ponad tydzień od zakończenia, pora podzielić się subiektywnymi wrażeniami.
Oficjalną relację opublikuję na łamach Wortalu PHP.pl niebawem, tymczasem zapraszam do lektury notki.
Tekst będzie raczej należał do tych dłuższych, zostałeś ostrzeżony(a).
Autor wpisu: batman, dodany: 01.06.2010 20:40, tagi: php
Codeplex wzbogacił się o kolejną ciekawą bibliotekę – Bing Search Library dla języka PHP. Umożliwia ona korzystanie z API wyszukiwarki Bing z poziomu kodu PHP. Biblioteka została wydana na licencji BSD.
W najprostszej postaci kod PHP korzystający z Bing Search Library wygląda następująco:
$o = new MsftBingSearch($myBingAPPID); $o->setQuery('Microsoft') ->setWebCount(10) ->setSource('Web'); $raw = $o->search(); $result = json_decode($raw); foreach($result->SearchResponse->Web->Results as $value) { printf('%s', $value->Url, $value->Title); }
Więcej informacji można znaleźć na stronie projektu.
Autor wpisu: sokzzuka, dodany: 01.06.2010 00:15, tagi: php
Wielokrotnie czytając wpisy na rozmaitych blogach, zauważyłem w komentarzach niezrozumienie idei interfejsu. Jest to dość ważny koncept i poniekąd klucz do implementacji większości wzorców projektowych.
Czy to ptak ? Czy samolot ? Nie ! To interfejs !
Interfejs to przede wszystkim dokumentacja. Interfejs opisuje role jaką ma odegrać pewien twór.
Najprościej jest to sobie wyobrazić na prostym przykładzie gniazdka elektrycznego. Specyfikując problem transferu prądu pomiędzy dwoma elementami sieci elektrycznej definiujemy interfejs “podłączalny”. Zawiera on opis żeńskiego gniazdka elektrycznego w rodzaju: “Gniazdko składa się z dwóch otworów oddalonych od siebie o X centymetrów zakończonych metalowymi końcówkami, napięcie wynosi 230V a częstotliwość prądu 50 Hz”.
Dzięki temu, że zdefiniowaliśmy interfejs “podłączalny” i jest on powszechnym standardem w Europie to gdziekolwiek byśmy nie pojechali na wakacje w UE, będziemy mogli korzystać z naszych urządzeń elektrycznych. Co więcej, dzięki temu, że mamy jasno określony interfejs, to w przypadku, gdy np posiadamy urządzenie, które nie spełnia tego interfejsu, a chcemy je podpiąć do prądu, możemy zbudować adapter, który umożliwi dostosowanie się obu interfejsów ( urządzenia i gniazdka ) do siebie.
Wspomniałem wcześniej, że interfejs definiuje role obiektów, przyjrzyjmy się temu bliżej. Załóżmy, że konstruujemy telewizor. Jako producentowi telewizora, zależy nam na tym, żeby można było go podłączyć do prądu oraz obsługiwać z pilota.
Nasz telewizor będzie implementował więc dwa interfejsy “podłączalny” i “pilotowalny”, dzięki którym będzie spełniał oczekiwania nasze i klientów .
Z powyższego opisu widać, że generalnie interfejs określa protokół komunikacyjny między dwoma obiektami. Tak też należy go stosować. Dzięki interfejsom, nie musimy martwić się o implementacje. W końcu co to byłby za świat, gdyby tylko jedna firma produkowała gniazdka elektryczne.
Mam nadzieje, że powyższy artykuł w sposób przystępny przybliżył zagadnienie interfejsów. Jeżeli mielibyście jakieś pytania zapraszam do wpisywania ich w komentarzach
Autor wpisu: batman, dodany: 30.05.2010 17:00, tagi: php
Najpopularniejszym pakietem biurowym na świecie jest Microsoft Office. Od dobrych kilku lat, programy takie jak Word, Excel, czy PowerPoint, zapisują dokumenty w formacie Office Open XML. Jak sama nazwa wskazuje, jest to format bazujący na XML, a co za tym idzie, możliwy do odczytania w PHP.
Struktura dokumentu
Dokument Office Open XML jest niczym innym jak archiwum zip, które zawiera określoną strukturę katalogów i plików. Pliki zapisane są w formacie XML. Tak wygląda zawartość archiwum dla pliku docx.
Jak widać, struktura katalogów jest bardzo prosta. Przeznaczeniem tych katalogów jest:
- docProps – znajdują się w nim dwa dokumenty core.xml oraz app.xml, które opisują podstawowe właściwości dokumentu
- word – katalog znajdujący się tylko w plikach docx. Inne dokumenty Office będą zawierały katalog xl w przypadku plików Excel lub ppt w przypadku plików PowerPoint. Katalog ten zawiera kilka plików XML oraz dodatkowe podfoldery, jednak jedynym interesującym nas elementem jest plik document.xml. Jeśli w dokumencie będą osadzone jakieś obrazki, to warto zainteresować się katalogiem media, w którym są one umiejscowione.
- _rels – zawiera plik opisujący relację między plikami w archiwum a ich przeznaczeniem
- [Content_Types].xml – jak sama nazwa wskazuje jest to plik określający typy plików znajdujących się w archiwum
PHP i archiwa ZIP
Od wersji 5.2 PHP zawiera klasę ZipArchive, która oferuje szereg możliwości, między innymi przeglądanie zawartości archiwum. Klasa ta idealnie nadaje się do rozpoczęcia pracy z dokumentami Open XML.
$zip = new ZipArchive(); $res = $zip->open('./Dokument testowy.docx'); if($res === true) { // operacje na pliku } else { // obsługa błedu echo 'Error: ' . $res; }
Jedyne co pozostało to przeparsować dokument XML w celu pobrania treści. Do dyspozycji mamy kilka sposobów. Jeśli plik docx zawiera jedynie niesformatowany tekst, bez żadnych obrazków, tabel i innych elementów, wystarczy że pobierzemy treść pliku document.xml, znajdującego się w katalogu word i potraktujemy go funkcją strip_tags.
$document = $zip->getFromName('word/document.xml'); echo strip_tags($document);
Jeśli jednak potrzebujemy zachować formatowanie dokumentu, trzeba nieco się wysilić. W przypadku niewielkich dokumentów warto skorzystać z SimpleXML, które idealnie się nada. Duże dokumenty będą wymagały zaprzęgnięcia klasy XMLReader.
Parsowanie dokumentu
Autor wpisu: sokzzuka, dodany: 29.05.2010 00:12, tagi: php
Pewnie wielu z was zastanawia się, jaka będzie przyszłość języka PHP. Co będzie w nowych wersjach, a czego nie będzie i dlaczego. Dlatego powiem kilka słów o tym jak wygląda ewolucja języka.
Proces decyzyjny.
Typowo proces decyzyjny wygląda tak: ktoś wymyśla feature, tworzy nową propozycję rfc. Następnie zapisuje się na listę mailingową internals tam obwieszcza, że stworzył propozycje i zaprasza do dyskusji.
Następnie osoby zapisane do listy, które to są core developerami PHP dyskutują na temat propozycji. Zwykle pojawia się wiele opinii za i przeciw oraz prośby na uściślenie propozycji. Losy propozycji zależą od tego czy po pierwsze ma sens, jeżeli nie ma, to już na początku osoba proponująca jest pozbawiana złudzeń, że to nie przejdzie.
Jeżeli propozycja ma sens i jest czymś co większość może zaakceptować, to osoba proponująca proszona jest o napisanie prototypowej implementacji i udostępnienie jej jako svn-patch do trunka, do testów. Ostateczną decyzje czy uwzględnić nowy feature podejmuje release manager wydania.
Generalnie proces wprowadzenia nowych funkcjonalności do języka jest procesem demokratycznym, jednak trzeba być dobrym “mówcą” i mieć naprawdę mocne argumenty, żeby wprowadzić coś nowego. Z tego co zauważyłem czytając listę internals, prawie nigdy nie przechodzą featury, które zrywają wsteczną kompatybilność.
Interesujące propozycje.
Z kilkunastu propozycji rfc wybrałem do opisu kilka, które wg. mnie zasługują na szczególną uwagę i zmieniają jakość obcowania z językiem.
Proponuje zamianę prawie wszystkich błędów ( oprócz parse i compile errors ) na wyjątki. Czyli defakto ukonstytuowuje to co wiele osób robi ustawiając swój error handler, który wyrzuca exception.
Autor wpisu: sokzzuka, dodany: 24.05.2010 23:51, tagi: php
Dzisiejszy post będzie o moim własnonożnie zrobionym kontenerze IOC (inversion of control). Najpierw kilka słów, czym jest wzorzec IOC.
W wielkim uproszczeniu wzorzec IOC polega na przeniesieniu poza obiekt wszelkich funkcjonalności nie związanych bezpośrednio z jego przeznaczeniem. Celem jest:
- zdefiniowanie jasnych odpowiedzialności poszczególnych klas
- stworzeniem abstrakcji dzięki której zmiana jednego elementu systemu nie będzie wpływała na inne
- uniezależnienie się od implementacji poszczególnych części systemu
Tyle do IOC, natomiast kontener IOC jest specjalną klasą, która na nasz zlecenie konstruuje za nas obiekty, których potrzebujemy dbając o wszelkie zależności między nimi.
Realizacja wygląda w ten sposób, że deklaratywnie określamy jakie są zależności między obiektami i na podstawie naszego opisu całą techniczną stroną tworzenia obiektów zajmuje się kontener IOC.
Kontener wraz z przykładem użycia można ściągnąć z tąd (licencja BSD).
Mój kontener IOC składa się z dwóch podstawowych częsci:
- fabryka obiektów
- adaptery dla różnych formatów określania zależności między obiektami
Fabryka obiektów tworzy i zarządza obiektami biorąc pod uwagę czas ich istnienia. Zarządza obiektami, których stan trzymany jest przez całą sesję użytkownika jak i może ich stan być trzymany nieskończenie długo i dostępny między sesjami użytkowników ( do tego potrzebny jest mechanizm cache typu APC lub XCache z odpowiednim adapterem).
Co do adapterów to na dziś dzień stworzony jest jeden adapter, który czyta XML-e. Pokrótce o tym jak opisywać obiekty w tymże XML-u.
<object-config> <application> <!-- For now empty, objects declared here will be cached by APC or something similiar --> </application> <session> <object class="FooFoo"> <property name="someParameter">baz_foo</property> </object> </session> <request> <object class="Foo1"> <property name="param2">other_baz</property> <property name="param1">baz</property> </object> <object class="Foo2"> <property name="param2">baz_faz</property> <property name="param1">baz_baz</property> </object> <object class-match="/Foo[0-9]+/"> <property name="param3" type="class">@self</property> </object> <object class="Bar" id="FooBar"> <property type="class" name="param1">Foo1</property> <property type="const" name="param2">FooConst</property> <property type="id" name="param3">Foo2</property> <proxy class="FooProxy"/> </object> </request> </object-config>
Jak widać albo i nie . Stopień niżej od roota są trzy tagi – “application”, “session”, “request”, które grupują w sobie tagi object. Te trzy tagi określają czy stan obiektu będzie trwał dla sesji czy dla pojedynczego requestu czy wiecznie dla całej aplikacji.
Tagi object określają konfigurację poszczególnych obiektów. Kolejne właściwości obiektu ustawiamy za pomocą tagów “property”. Obowiązkowym atrybutem tagu “property” jest “name”, mówi on o nazwie parametru w konstruktorze lub nazwie settera przez który ma być wstrzyknięta właściwość obiektu. Dzięki temu rozwiązaniu, nie ma znaczenia w jakiej kolejności podamy właściwości, zawsze zostaną one właściwie wstrzyknięte.