Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: sokzzuka, dodany: 25.08.2010 16:04, tagi: php

W niedawnym wpisie na liście php.internals, Pierrick Charron poinformował o stworzeniu patch’a dodającego obsługę adnotacji do php. Patch ten jest napisany zgodnie z odpowiednim RFC. Rozszerza on składnie języka, dodaje obsługę do refleksji i dwie nowe klasy ‘ReflectionAnnotation’ i ‘Inherited’ – pierwsza umożliwia tworzenie własnych adnotacji, natomiast druga umożliwia dziedziczenie adnotacji przez klasy dziedziczące z jakiejś klasy.

Jak dla mnie to ciekawy dodatek do języka, natomiast ja chętnie bym również widział jakąś implementacje Pythonowych dekoratorów o których już wcześniej wspominałem. A wy co o tym sądzicie ?

Autor wpisu: m1chu, dodany: 24.08.2010 22:38, tagi: css, javascript

Jak zmusić Internet Explorer 8 do obsługi HTML 5?

Sieć została ogarnięta szałem najnowszej, piątej wersji języka HTML. Jak to zazwyczaj bywa słabo z jej obsługą radzi sobie Internet Explorer. We wszystkich wydanych wersjach pojawia się problem z parsowaniem elementów języka HTML 5, a co za tym idzie nie ma domyślnie możliwości ich poprawnego ostylowania. Podobny problem w przeszłości występował w Firefoksie 2.

Zarys problemu

Załóżmy więc, że tworzymy nowy projekt i jesteśmy na etapie dodawania nagłówka oraz stopki dokumentu.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Obsługa HTML 5 z CSS</title>
    <style>
    body { text-align: center; margin: 0; padding: 0; font-family: Tahoma, Verdana, Arial; font-size: 11px; }
    header { font-style: italic; width: 770px; height: 70px; padding: 15px; margin: 5px auto; background-color: #FC0; text-align: left; }
    footer { font-weight: bold; clear: both; width: 770px; height: 15px; padding: 15px; margin: 5px auto; background-color: #FC0; text-align: left; }
    </style>
</head>
<body>
    <header>Nagłówek</header>
    <footer>Stopka</footer>
</body>
</html>

Nadaliśmy powyżej kilka atrybutów stylów pozycjonujących elementy oraz nadających im odpowiedni wygląd. Po przetestowaniu w Internet Explorerze i alternatywnych przeglądarkach zobaczymy jednak różne wyniki.

Wynik w Firefoksie 4Wynik w Firefoksie 4.

Wynik w Internet Explorerze 8Wynik w Internet Explorerze 8.

Internet Explorer – rozwiązanie pierwsze

Aby pozbyć się tego problemu należy do sekcji head wstawić:

<script>
document.createElement('header');
document.createElement('footer');
</script>

Internet Explorer – rozwiązanie drugie

Dla każdej wersji Internet Explorera można także dodać do dokumentu HTML (w sekcję head) zewnętrzny kod JavaScript, dzięki któremu osiągniemy wyżej opisany skutek.

<!--[if IE lt 9]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

Firefox 2

Niespełna jeden procent internautów nadal używa drugiej odsłony popularnego lisa. Zarówno on, jak i wszystkie przeglądarki oparte na silniku Gecko pre 1.9b5 (np. Camino 1.x) posiadają błąd parsowania dzięki któremu w przypadku otwarcia nowego znacznika każdy nieznany, wcześniej otwarty zostanie automatycznie zamknięty.

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

Autor wpisu: batman, dodany: 24.08.2010 08:00, tagi: javascript

W poprzedniej części przewodnika opisałem najważniejsze zagadnienia związane z gadżetami pulpitu dostępnymi w systemach operacyjnych Windows Vista oraz Windows 7. W dzisiejszym oraz kilku następnych wpisach skupię się na poszczególnych elementach tej technologii. Zacznę od okien Settings oraz Flyouts. Struktura aplikacji Zanim przejdziemy dalej, należy wspomnieć nieco o strukturze aplikacji. Nie różni sie ona zbytno od struktury aplikacji internetowej. Mamy dokument główny, dokumenty dodatkowe oraz zasoby (CSS, Javascript oraz obrazki). Proponowany przeze mnie układ katalogów wygląda następująco. struktura-katalogow Katalogi raczej nie wymagają wyjaśnienia – są przeznaczone do przechowywania obrazków, skryptów Javascript oraz plików CSS. Z kolei pliki to manifest (gadget.xml), główny dokument gadżetu (Main.html – nazwa definiowana w manifeście) oraz pozostałe dokumenty .W tym przypadku jest to tylko Settings.html, ale nic nie stoi na przeszkodzie, aby tych dokumentów było więcej. W dalszej części dzisiejszego przewodnika dojdzie jeszcze jeden plik – Flyout.html W przykładach wykorzystałem bibliotekę jQuery, dzięki której wiele czynności zostało uproszczonych, przez co kod jest bardziej czytelny. Nie jest to wymóg. Jeśli nie znacie/nie lubicie jQuery możecie skorzystać z innej biblioteki lub nie korzystać wcale. Settings Settings to nic innego jak okno ustawień. Jest ono reprezentowane przez osobny dokukent HTML, w którym powinny znaleźć się elementy formularza (pola tekstowe, checkboxy, radiobuttony itp). Nie ma konieczności stosowania przycisków, ponieważ są one dodawane automatycznie. Jeśli chcemy wykorzystać okno ustawień wystarczy, że do właściwości settingsUI obiektu System.Gadget przypisana zostanie ścieska wskazująca na plik HTML. Ścieżka może być relatywna lub bezwzględna. Przypisanie powinno nastąpić w głównym dokumencie.
System.Gadget.settingsUI = "/Settings.html";
Dodanie powyższego kodu do gadżetu spowoduje pojawienie się ikonki klucza (wyróżniona na czerwono), settings-icon kliknięcie której spowoduje otwarcie dokumentu wskazanego we właściwości settingsUI. Dokument ten zostanie zamieszczony w specjalnym oknie, zawierającym nagłówek oraz niezbędne przyciski. settings-window W prawym górnym roku tego okna pojawi się podgląd gadżetu. Ponieważ dzisiejszy wpis poświęcony jest jedynie oknom Settings oraz Flyout, gadżet nie będzie zawierał żadnych elementów graficznych. Stąd ten biały pionowy pasek na powyższym screenie. Jak już wspomniałem, okno ustawień to nic innego jak najzwyklejszy formularz HTML. W naszym przykładzie formularz będzie zawierał jedynie jedno pole.
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <link type="text/css" rel="stylesheet" href="/styles/reset.css" />
  <link type="text/css" rel="stylesheet" href="/styles/global.css" />
  <script type="text/javascript" src="/scripts/jquery-1.4.2.min.js"></script>
 </head>
    <body class="settings">
  <label>Your name:</label>
  <input type="text" name="your-name" id="your-name" />
    </body>
</html>
Samo dodanie formularza oraz wskazanie go jako okno ustawień na nic się zda, jeśli chcemy przechowywać i odczytywać wprowadzone przez użytkownika dane. Na szzęście mamy do dyspozycji obiekt System.Gadget.Settings, który pozwala na zapisywanie i odczytywanie ustawień. Służą do tego cztery metody, przez ten obiekt udostępnione. Są to:
  • write
  • writeString
  • read
  • readString
Metody z przyrostkiem String służą odpowiednio do zapisania i odczytania danych tekstowych. Pozostałe typy danych powinny być zapisywane i odczytywane przez metody write oraz read. Jest to podyktowane względami wydajnościowymi. Warto mieć również na uwadze limity, które ograniczają ilość przechowywanych w ten sposób informacji. Klucze mogą mieć jedynie 1024 znaki, a przypisane im wartości 2048 znaki. W przypadku przekroczenia tych limitów, dane zostaną skrócone do maksymalnych wartości. Dane zapisywane w oknie ustawień można przechwycić w zdarzeniu onSettingsClosing obiektu System.Gadget. Przechwycenie tego zdarzenie musi nastąpić w pliku okna ustawień. W przeciwnym razie dane nie będą dostępne.
// przechwycenie zdarzenia zamykania okna ustawień
System.Gadget.onSettingsClosing = SettingsClosing;

// obsługa zdarzenia
function SettingsClosing(event)
{
 // czy zamknięcie nastąpiło na skutek kliknięcia w przycisk "OK"
 if(event.closeAction == event.Action.commit) {
  // zapisanie wprowadzonych danych
  System.Gadget.Settings.writeString("name", $("#your-name").val());
 }
}
Jeśli chcemy od razu po zamknięciu okna ustawień mieć dostęp do danych, musimy obsłużyć kolejne zdarzenie związane z ustawieniami – onSettingsClosed. Przy czym należy pamiętać, że obsługa tego zdarzenia musi – w przeciwieństwie do zdarzenia onSettingsClosing – odbyć się w głównym oknie gadżetu.
// przechwycenie zdarzenia zamknięcia okna ostawień
System.Gadget.onSettingsClosed = SettingsClosed;

// obsługa zdarzenia
function SettingsClosed(event)
{
 // odczytanie wprowadzonych danych
 var name = System.Gadget.Settings.readString("name");
 $("#entered-name").text(name);
}
Flyout Flyout jest specjalnym typem okna, które stosuje się do zaprezentowania dodatkowych informacji. Podobnie jak w przypadku okna ustawień, Flyout ma swój własny dokument HTML. Flyout jest wyświetlany w momencie ustawienia właściwości show obiektu System.Gadget.Flyout na true, a ukrywany po ustawieniu jej wartości na false.
// wskazanie pliku Flyout
System.Gadget.Flyout.file = "/Flyout.html";

$(document).ready(function() {
 $("#show-flyout a").click(function() {
  // wyświetlenie Flyout
  System.Gadget.Flyout.show = true;
  return false;
 });
});
Zamknięcie flyout odbywa się na tej samej zasadzie, przy czym kod odpowiedzialny za zamknięcie musi się znaleźć w pliku z flyout.

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

Autor wpisu: batman, dodany: 22.08.2010 17:35, tagi: javascript, jquery

Jakiś czas temu na blogu MIX Online pojawił się wpis na temat narzędzia pozwalającego tworzyć animacje jQuery. Podobnie jak wy teraz, podszedłem do tematu dosyć sceptycznie i odłożyłem jego zgłębianie na później. Dzisiaj zainstalowałem to narzędzie i przeprowadziłem kilka prostych testów. Ich wynik przeszedł moje najśmielsze oczekiwania. Okazuje się, że Glimmer został dokładnie przemyślany i oprócz przyjaznego interfejsu oferuje bardzo dobre narzędzia do tworzenia animacji. Wystarczy wspomnieć o wizadrach, dzięki którym w kilka chwil można stworzyć rozwijane menu lub tooltip. Oczywiście obok gotowych animacji mamy do dyspozycji edytor, który pozwoli zaprojektować animację od początku do końca. Po zainstalowaniu i uruchomieniu Glimmera, ujrzymy ekran powitalny, z poziomu którego można stworzyć własną animację, wybrać jedną z dostępnych lub przejść do strony projektu. glimmer Nie będę opisywał gotowych szablonów, ponieważ ich zastosowanie jest intuicyjne i sprowadza się do kilku prostych kroków. Poza tym wizardy zostały tak przygotowane, że nie wymagają dodatkowego opisu. O wiele bardziej interesujące są możliwości jakie daje edytor animacji. editor Wystarczy wczytać plik HTML, zawierający poprawnie sformatowany kod, a następnie wskazać źródło zdarzenia, typ zdarzenia oraz cel. Źródłem zdarzenia może być dowolny element znajdujący się we wczytanym dokumencie. Element można wskazać po tagu (np div), klasie (.jakas-klasa) lub identyfikatorze (#identyfikator). Typem zdarzenia są wszystkie przewidziane przez jQuery zdarzenia, np click, mouseover, blur, scroll, itp. new-action Cel wybiera się w taki sam sposób jak źródło. Po określeniu celu, należy wybrać rodzaj animacji oraz ustalić jej parametry. Np dla animacji przeźroczystości należy wybrać wartość początkową oraz końcową. Oprócz samej animacji mamy możliwość ustalenia dodatkowych parametrów, takich jak czas trwania oraz efekt przejścia. Co więcej, można wskazać animację jaka ma się wykonać po zakończeniu bieżącej. editor-expanded Edytor daje możliwość określenia więcej niż jednej animacji na cel oraz więcej niż jeden cel na zdarzenie. Przy odrobienie wysiłku można stworzyć skomplikowaną animację bez napisania ani jednego wiersza w Javascript. Jeśli martwicie się o jakość wygenerowanego kodu, spieszę wyjaśnić, że kod jest poprawnie wygenerowany i nie zawiera dziesiątek zbędnych zmiennych i dziwnych operacji. Jedyne co kiepsko wygląda w wygenerowanym kodzie, to komentarz zawierający informacje niezbędne dla Glimmera. Po zakończeniu pracy można ten komentarz śmiało usunąć. Oto przykładowy kod wygenerowany przez to narzędzie (nic w nim nie zmieniałem).
//Microsoft.Glimmer.OneWay
//<AnimationCollection FilePath="C:\test.html.glimmer.js" xmlns="clr-namespace:GlimmerLib;assembly=GlimmerLib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Animation Name="ActionName1" EventType="click" Trigger="#link"><Animation.Targets><Target Name="#div" Duration="1000" Easing="linear" Callback="ActionName2"><Target.Effects><ColorEffect CSSName="color" DisplayName="Color Animation" MaxValue="1" MinValue="0" From="0" To=""darkred"" IsStartValue="False" IsActive="True" IsAnimatable="True" IsExpression="False" FormatString="" RequiresJQueryPlugin="True" JQueryPluginURI="effects.core.js" /></Target.Effects></Target></Animation.Targets></Animation><Animation Name="ActionName2" EventType="[none]" Trigger="{x:Null}"><Animation.Targets><Target Name="#div" Duration="1000" Easing="linear" Callback="null"><Target.Effects><RemoveHTMLEffect CSSName="#link" DisplayName="Remove HTML Effect" MaxValue="0" MinValue="0" From="0" To="0" IsStartValue="False" IsActive="True" IsAnimatable="False" IsExpression="False" FormatString="$({1}).remove();
" RequiresJQueryPlugin="False" JQueryPluginURI="" /></Target.Effects></Target></Animation.Targets></Animation></AnimationCollection>
jQuery(function($) {
var timer;
function ActionName1(event)
{
    $("#div").animate({"color":"blue"},1000, "linear", ActionName2);
}

function ActionName2(event)
{
     $("#link").remove();
}

$('#link').bind('click', ActionName1);


});
Więcej informacji na temat Glimmera oraz przykładowe animacje znajdziecie na oficjalnej stronie projektu.

Autor wpisu: batman, dodany: 21.08.2010 08:00, tagi: php

Na pytanie jak wysłać POST’a bez submitowania formularza, padają dwie odpowiedzi – AJAX lub cURL. Okazuje się, że jest jeszcze trzecia odpowiedź. Można skorzystać z kontekstu oraz standardowej funkcji operującej na plikach, np file_get_contents.

Kontekst umożliwia zmianę… kontekstu requesta. Najprościej będzie to wyjaśnić na przykładzie:

// przygotowanie zmiennych do wysłania
$post = http_build_query(array(
	'zmienna1' => 'wartosc 1',
	'zmienna2' => 'wartosc2'
));

// wysyłane nagłówki
$headers = array(
	'Content-type: application/x-www-form-urlencoded'
);

// utworzenie kontekstu
$context  = stream_context_create(array(
	'http' => array(
		'method' => 'POST',
		'header' => implode("\r\n", $headers),
		'content' => $post
	)
));

// wysłanie POST-a i zapisanie odpowiedzi do zmiennej
$content = file_get_contents('http://example.com/file.php', false, $context);

Kluczowym elementem powyższego kodu jest funkcja stream_context_create. To ona odpowiada za modyfikację standardowego zachowania funkcji file_get_contents. Stream_context_create przyjmuje dwa parametry. Pierwszym jest tablica zawierająca konfigurację kontekstu, drugim tablica zawierająca dodatkowe parametry.

Dlaczego warto korzystać z kontekstów zamiast cURL-a? Przede wszystkim nie wymaga instalacji. Wiem, że cURL jest zazwyczaj dostęny, ale… Ponadto użycie kontekstu jest prostsze i wymaga mniej kodu oraz umożliwia skorzystanie z funkcji zwrotnej. Oto przykład takiej funkcji zaczerpnięty z maunala.

function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) {

    switch($notification_code) {
        case STREAM_NOTIFY_RESOLVE:
        case STREAM_NOTIFY_AUTH_REQUIRED:
        case STREAM_NOTIFY_COMPLETED:
        case STREAM_NOTIFY_FAILURE:
        case STREAM_NOTIFY_AUTH_RESULT:
            var_dump($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max);
            /* Ignore */
            break;

        case STREAM_NOTIFY_REDIRECTED:
            echo "Being redirected to: ", $message;
            break;

        case STREAM_NOTIFY_CONNECT:
            echo "Connected...";
            break;

        case STREAM_NOTIFY_FILE_SIZE_IS:
            echo "Got the filesize: ", $bytes_max;
            break;

        case STREAM_NOTIFY_MIME_TYPE_IS:
            echo "Found the mime-type: ", $message;
            break;

        case STREAM_NOTIFY_PROGRESS:
            echo "Made some progress, downloaded ", $bytes_transferred, " so far";
            break;
    }
    echo "\n";
}

Dodanie funkcji zwrotnej do kontekstu jest niezwykle proste i sprowadza się do wskazania jej nazwy w drugim parametrze funkcji stream_context_create.

$context  = stream_context_create(
	array(
		'http' => array(
			'method' => 'POST',
			'header' => implode("\r\n", $headers),
			'content' => $post
		)
	),
	array(
		'notification' => 'stream_notification_callback'
	)
);

Wywołaniu funkcji file_get_contenst z kontekstem zawierającym funkcję zwrotną spowoduje wyświetlenie:

Connected...
Found the mime-type: text/html
Made some progress, downloaded 0 so far
Made some progress, downloaded 8192 so far
Made some progress, downloaded 16384 so far
Made some progress, downloaded 24216 so far

Prawda, że proste?

Autor wpisu: batman, dodany: 20.08.2010 21:39, tagi: css

Rozpakowując ostatnie pudła, natrafiłem na trzy książki, które przez długi czas służyły mi pomocą. Aż się łezka w oku zakręciła, gdy je ponownie zobaczyłem. Z racji tematyki, były dosyć mocno eksploatowane, więc nie są pierwszej świeżości. Niemniej będą stanowić łakomy kąsek dla wszystkich zainteresowanych CSS. Książki, które dzisiaj mam zamiar wam oddać to:

CSS. Nieoficjalny podręcznik

HTML, XHTML i CSS. Biblia

CSS według Erica Meyera. Sztuka projektowania stron WWW

Jeśli chcecie otrzymać te książki, wystarczy, że napiszecie wiadomość korzystając z formularza, do którego link znajdziecie w prawej kolumnie, z odpowiedzią na pytanie ile MB zajmuje moja poczta na koncie Gmail. Utrudnieniem będzie tutaj fakt, iż ilość zajmowanego miejsca przez pocztę sprawdzę dopiero po zakończeniu konkursu. Na poprawne odpowiedzi czekam do końca poniedziałku (23.08.2010). Powodzenia.

Autor wpisu: cojack, dodany: 20.08.2010 20:10, tagi: php

PHP Dobra, trochę na speedzie jest pisany ten wpis, także może być w nim parę nieścisłości i niedociągnięć, ale mam nadzieje że poprawicie mnie w komentarzach. O co chodzi? Kod tutaj opisany poniżej nie jest mojego autorstwa, niektóre treści też zrzynam bezpośrednio z książki bo nie ma innych słów by to opisać. Jest prawie na żywca zdarty z książki „PHP 5 Zaawansowane Programowanie”, także odczepić się proszę, nie piszę że ja to napisałem, jak już ktoś coś wymyślił, to nie mam zamiaru wymyślać koła na nowo, tylko poskładać wszystko do kupy i połączyć by to działało. No dobra to jedziemy. Trochę nie po kolei, z tymi klasami, ale wybaczcie. Zaczynamy.

Słowem wstępu

Jest sobie taki interfejs w php, który się zwie Iterator, posiadający 5 metod, które informują foreach jak sobie ma radzić z argumentami niebędącymi tablicą. On zaś (co jeszcze dziwniejsze) dziedziczy po kolejnym interfejsie który się zwie Travesrable. To co poniżej zobaczycie w pełnej krasie, jest implementacją mapy. Ale do rzeczy, po cholerę nam takie pyszne rzeczy? Otóż jeżeli chcielibyśmy sobie obiektowo przechowywać elementy w zmiennej nie będącej tablicą i przeiterować jest foreachem, to jak to zrobicie? No to pokaże Wam jak to można było by zrobić:

 
/* odpowiedni foreach dla ($objIt as $key => $value ) */
$objIt = new MyIterator();
for( $objIt->rewind(); $obj->valid(); $objIt->next() ) {
  $key = $objIt->key();
  $member = $objIt->current();
}

Trochę mało to Wam mówi jeszcze, ale jak spojrzycie na dalszą część tekstu to się sami przekonacie.

Klasa Collection

Na omówieniu tej klasy, przysłużę się przykładem z książki.

Pisząc aplikację, często zachodzi potrzeba utworzeniu obiektów, które zawierają w sobie grupę innych obiektów. Na przykład w systemie obsługi dziekanatu potrzebna będzie klasa Student oraz Course. Obiekt Student zapewne będzie miał przypisany więcej niże jeden obiekt Course. Pierwsze nasuwające się rozwiążanie to dodanie tablicy obiektów Course jako zmiennej składowej obiektu Student.

Przykład z książki:

class Student {
  public $courses = array();
  //... itd
}
 
$objStudent = new Student( 124 );
foreach( $objStudent->courses as $objCourse ) {
  print $objCourse->name;
}

I wracamy do omówienia problemu:

Oczywiście gdyby taki sposób był najlepszy, to by nie było mowy o klasie Collection (trochę to przerobiłem :D )

Powyższe rozwiązanie sprawia kilka problemów. Po pierwsze, publiczny dostęp do tablicy obiektów Course nie jest zgodny z zasadą hermetyzacji. Nie ma możliwości weryfikacji zmian w tablicy czy modyfikacji stanu obiektu Student, gdyby zaszła taka potrzeba. Po drugie, taka implementacja nie określa porządku elementów w tablicy ani sposobu odnalezienia poszukiwanego obiektu. Po trzecie, i najważniejsze, aby zapewnić dostęp do informacji o kursach każdemu użytkownikowi klasy Student, informacje te muszą zostać pobrane z bazy danych za każdym razem, gdy pobierane są informacje o studencie. Oznacza to że nawet jeśli konieczne jest jedynie wyświetlenie imienia studenta, pobierane są wszystkie informacje o kursach. Niepotrzebnie zwiększa to obciążenie serwera baz danych i zmniejsza wydajność aplikacji. Klasa Collection została zaprojektowana tak, aby rozwiązać wszystkie te problemy. Zapewnia obiektową otoczkę dla tablicy i implementuje mechanizm leniwej konkretyzacji, czyli opóźnienia procesu tworzenia elementów kolekcji aż do czasu, gdy są one naprawdę potrzebne. Nazywa się ją „leniwą”, ponieważ decyzja o tym, kiedy tworzyć konkretne egzemplarze obiektów, jest podejmowana przez samą aplikację.

Dobra, o co ogólnie chodzi? Chodzi o to że nasza klasa Collection, jak sama nazwa wskazuje jest kolekcją obiektów, czyli dodajemy do niej obiekty, a ona zgrabnie je przechowuje w swoim ciele. I to by było na tyle z filozofią klasy Collection, żeby zbytnio nie przeciągać, to poniżej mamy już dwie gotowe klasy które razem z sobą współpracują, są na żywca wydarte z mojego FW, także BDT_Loader, jak po samej nazwie można się domyślić, wczytuje klasy, także nie mam tu nic więcej do dodania. Klasa BDT_Collection_Exception jest po prostu klasą wyjątków, i tu też nie mam nic więcej do dodania. W naszym przykładzie będziemy potrzebowali dwie klasy, Collection (BDT_Collection) oraz CollectionIterator (BDT_Collection_Iterator). Obiekt klasy CollectionIterator jest tworzony w metodzie getIterator. Pod ciałem klasy, krótki opis.

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.