<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Blog o PHP</title>
	<atom:link href="http://blogophp.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogophp.com</link>
	<description>i tematyce pokrewnej</description>
	<pubDate>Sun, 14 Feb 2010 19:50:50 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
	<language>en</language>
			<item>
		<title>intercepting filter</title>
		<link>http://blogophp.com/2010/02/14/intercepting-filter/</link>
		<comments>http://blogophp.com/2010/02/14/intercepting-filter/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 19:46:58 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
		
		<category><![CDATA[php]]></category>

		<category><![CDATA[wzorce projektowe]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=46</guid>
		<description><![CDATA[Intercepting filter to wzorzec projektowy, który znajduje zastosowanie w aplikacjach wymagających wielokrotnego wykonywania tych samych czynności. Za przykład może posłużyć sytuacja, w której skrypt na samym początku musi uzyskać połączenie z bazą danych, a na końcu je zamknąć. Innymi często powtarzającymi się działaniami są operacje związane z autoryzacją, transakcjami, logowaniem zdarzeń, itd. Sposób implementacji intercepting [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Intercepting filter</strong> to wzorzec projektowy, który znajduje zastosowanie w aplikacjach wymagających wielokrotnego wykonywania tych samych czynności. Za przykład może posłużyć sytuacja, w której skrypt na samym początku musi uzyskać połączenie z bazą danych, a na końcu je zamknąć. Innymi często powtarzającymi się działaniami są operacje związane z autoryzacją, transakcjami, logowaniem zdarzeń, itd.<span id="more-46"></span> Sposób implementacji <em>intercepting filter</em> zależy w dużej mierze od naszych indywidualnych wymagań. Nie pozostaje nam więc nic innego, jak przejść do praktyki.</p>
<h3>przykład pierwszy</h3>
<p>Poniżej prezentuję prostą klasę <em>ImplementAction</em>, która korzysta z omawianego przeze mnie wzorca (klasa abstrakcyjna <em>Action</em>). Popatrzmy na jej kod:</p>
<pre class="brush: php;">
abstract class Action {

	abstract public function BeforeAction();

	abstract public function AfterAction();

	public function __construct () {
		$this->BeforeAction ();
	}

	public function __destruct() {
		$this->AfterAction ();
	}

}

class ImplementAction extends Action {

	public function BeforeAction() {
		echo __METHOD__;
	}

	public function AfterAction() {
		echo __METHOD__;
	}

	public function A () {
		echo __METHOD__;
	}

	public function B () {
		echo __METHOD__;
	}

}

$obj = new ImplementAction();
$obj->A();
$obj->b();
</pre>
<p>Na wyjściu otrzymamy:</p>
<div class="codesnip-container" >
ImplementAction::BeforeAction<br />
ImplementAction::A<br />
ImplementAction::B<br />
ImplementAction::AfterAction</div>
</p>
<p>Jak widać przy tworzeniu obiektu wywoływana jest metoda <em>BeforeAction()</em>, a w destruktorze <em>AfterAction()</em>. Oczywiście powyższy kod ma swoje wady i zalety. Zależą one jednak od wymogów tworzonego oprogramowania, zatem coś co dla jednych może być dużym plusem, dla innych staje się rozwiązaniem nie do przyjęcia. Najwyższy czas na przyjrzenie się bardziej zaawansowanemu modelowi użycia <em>Intercepting Filter</em>, dzięki któremu zwiększymy jego elastyczność i możliwości.</p>
<h3>przykład drugi</h3>
<pre  class="brush: php;">
// iterfejs dla filtrow
interface InterceptingFilter {

	public function doBefore();
	public function doAfter();

}

// klasa filtra
class FirstFilter implements InterceptingFilter {

	public function doBefore() {

		echo __METHOD__;

	}

	public function doAfter() {

		echo __METHOD__;

	}

}
// klasa filtra
class SecondFilter implements InterceptingFilter {

	public function doBefore() {

		echo __METHOD__;

	}

	public function doAfter() {

		echo __METHOD__;

	}

}
// klasa filtra
class AnotherFilter implements InterceptingFilter {

	public function doBefore() {

		echo __METHOD__;

	}

	public function doAfter() {

		echo __METHOD__;

	}

}
// abstrakcyjna klasa zajmujaca sie odpowiednim wywolywaniem
// filtrow
abstract class UseInterceptingFilter {

	private $filters = array();

	private function doBeforeActions() {

		foreach ($this->filters as $do)
			$do->doBefore();

	}

	private function doAfterActions() {

		foreach ($this->filters as $do)
			$do->doAfter();

	}

	public function __construct (array $filters = array()) {

		$this->filters = $filters;

		$this->doBeforeActions();

	}

	public function __destruct () {
		$this->doAfterActions();
	}

}

// klasa korzystajaca z filtrow
class Example extends UseInterceptingFilter {

	public function A() {

		echo __METHOD__;

	}

	public function B() {

		echo __METHOD__;

	}

}

// tworzymy przykladowe filtry
$filter1 = new FirstFilter();
$filter2 = new SecondFilter();
$filter3 = new AnotherFilter();

// filtry przekazywane w konstruktorze
$obj = new Example(array($filter1,$filter2,$filter3));
$obj->A();
$obj->B();
</pre>
<p>Na wyjściu dostajemy:</p>
<div class="codesnip-container" >
FirstFilter::doBefore<br />
SecondFilter::doBefore<br />
AnotherFilter::doBefore<br />
Example::A<br />
Example::B<br />
FirstFilter::doAfter<br />
SecondFilter::doAfter<br />
AnotherFilter::doAfter</div>
</p>
<p>Aby dodać nowy filtr wystarczy napisać klasę implementującą interfejs <em>InterceptingFilter</em>. Natomiast klasy z nich korzystające dziedziczą po <em>UseInterceptingFilter</em> , a ów filtry są przekazywane jako tablica w konstruktorze.</p>
<p>Zachęcam więc do własnych eksperymentów, które doprowadzą do rozwiązań w pełni dostosowanych do stawianych przez Was wymagań.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2010/02/14/intercepting-filter/feed/</wfw:commentRss>
		</item>
		<item>
		<title>namespaces</title>
		<link>http://blogophp.com/2010/01/17/namespaces/</link>
		<comments>http://blogophp.com/2010/01/17/namespaces/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 10:53:59 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
		
		<category><![CDATA[php]]></category>

		<category><![CDATA[namespaces]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=45</guid>
		<description><![CDATA[Przestrzenie nazw, czyli jedna z najbardziej oczekiwanych funkcjonalności, została udostępniona dla programistów wraz z wydaniem PHP 5.3. Namespaces pozwalają na grupowanie klas, funkcji i stałych poprzez nadawanie im unikalnych nazw, które są następnie wykorzystywane w procesie odwoływania się do tak uporządkowanych struktur kodu. Nabiera to ogromnego znaczenia na przykład w pracy grupowej. Może się bowiem [...]]]></description>
			<content:encoded><![CDATA[<p>Przestrzenie nazw, czyli jedna z najbardziej oczekiwanych funkcjonalności, została udostępniona dla programistów wraz z wydaniem <strong>PHP 5.3</strong>. Namespaces pozwalają na grupowanie klas, funkcji i stałych poprzez nadawanie im unikalnych nazw, które są następnie wykorzystywane w procesie odwoływania się do tak uporządkowanych struktur kodu.<span id="more-45"></span> Nabiera to ogromnego znaczenia na przykład w pracy grupowej. Może się bowiem zdarzyć sytuacja, w której dwóch niezależnie pracujących informatyków, napisze klasy które będą miały tę samą nazwę. Idealnym rozwiązaniem okazują się przestrzenie nazw właśnie.</p>
<h3>praktyka</h3>
<p>W PHP namespaces można tworzyć na dwa sposoby i oba zostały zaprezentowane poniżej:</p>
<pre class="brush: php;">
namespace A;

function ShowMsg() {

	echo __FUNCTION__;

}
</pre>
<p>Albo tak:</p>
<pre class="brush: php;">
namespace A {

function ShowMsg() {

	echo __FUNCTION__;

}

}
</pre>
<p>Jak widać na powyższych przykładach, przestrzeń konstruuje się z użyciem słowa kluczowego <em>namespace</em>, po czym określana jest jej nazwę (w tym wypadku <em>A</em>). Należy pamiętać, aby<strong> deklaracja ta znajdowała się na początku skryptu</strong> (przed nią może wystąpić tylko  <em>declare</em>). Dozwolone jest też tworzenie kilku przestrzeni w jednym pliku, aczkolwiek rozwiązanie to nie jest zalecane:</p>
<pre class="brush: php;">
namespace A ;

function ShowMsg() {

	echo __FUNCTION__;

}

namespace B ;

function ShowMsg() {

	echo __FUNCTION__;

}
</pre>
<p>Można również organizować pewnego rodzaju hierarchię, formując poziomy (sub-namespaces):</p>
<pre class="brush: php;">
namespace Main\First ;

function ShowMsg() {

	echo __FUNCTION__;

}

namespace Main\First\One ;

function ShowMsg() {

	echo __FUNCTION__;

}

namespace Main\First\Two ;

function ShowMsg() {

	echo __FUNCTION__;

}
</pre>
<p>Zapewne zastanawiacie się jak wywoływać klasy, funkcje i stałe z różnych przestrzeni. Przełączanie się między nimi przypomina proces poruszania się po strukturze katalogów. Występuje tutaj pojęcie ścieżek względnych i bezwzględnych. Najprościej będzie to zrozumieć analizując prosty kod, zamieszczony poniżej: </p>
<pre class="brush: php;">
// przestrzen A\First
namespace A\First {

	function ShowMsg () {
		// specjalna stala predefiniowana zawiera
		// przestrzen w ktorym sie znajduje struktura
		echo __NAMESPACE__;

	}
}

// przestrzen A\Second
namespace A\Second {

	function ShowMsg () {

		echo __NAMESPACE__;

	}
}

// przestrzen A
namespace A {

	// sciezki bezwzgledne
	\A\First\ShowMsg();
	\A\Second\ShowMsg();

	// sciezki wzgledne (wzgledem obecnej przestrzeni)
	First\ShowMSg();
	Second\ShowMSg();

	// jeszcze jeden sposob namespace to odwolanie
	// do aktualnej przestrzeni
	namespace\First\ShowMsg();
	namespace\Second\ShowMsg();

	// wywolywanie globalnych funkcji, klas i stalych
	echo \count(array(1,2,3));

}

// przestrzen "globalna"
namespace {

}
</pre>
<p>Oczywiście nie opisałem wszystkich możliwości namespaces w PHP. Zainteresowanych odsyłam <a href="http://www.php.net/manual/en/language.namespaces.php" title="tutaj">TUTAJ</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2010/01/17/namespaces/feed/</wfw:commentRss>
		</item>
		<item>
		<title>introspekcja</title>
		<link>http://blogophp.com/2010/01/03/introspekcja/</link>
		<comments>http://blogophp.com/2010/01/03/introspekcja/#comments</comments>
		<pubDate>Sun, 03 Jan 2010 13:30:44 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
		
		<category><![CDATA[php]]></category>

		<category><![CDATA[introspekcja]]></category>

		<category><![CDATA[reflection]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=44</guid>
		<description><![CDATA[Introspekcja to pojęcie oznaczające zdolność aplikacji do zarządzania własnym kodem. Pozwala zatem pobierać informacje na temat klas,interfejsów i funkcji w trakcie działania programu. Termin ten jest utożsamiany z mechanizmem refleksji. W zależności od języka programowania, oba pojęcia mogą się subtelnie różnić. Z reguły mechanizm odbić (reflection) rozszerza introspekcję, oferując znacznie większe spektrum możliwości (dostarczając bardziej [...]]]></description>
			<content:encoded><![CDATA[<p>Introspekcja to pojęcie oznaczające zdolność aplikacji do zarządzania własnym kodem. Pozwala zatem pobierać informacje na temat klas,interfejsów i funkcji w trakcie działania programu. Termin ten jest utożsamiany z mechanizmem refleksji.<span id="more-44"></span> W zależności od języka programowania, oba pojęcia mogą się subtelnie różnić. Z reguły mechanizm odbić (reflection) rozszerza introspekcję, oferując znacznie większe spektrum możliwości (dostarczając bardziej szczegółowych informacji, czasami dając szansę na zmianę semantyki, czy też zachowania metod, funkcji itp.). Refleksja stanowi doskonałe narzędzie inżynierii odwrotnej i jest jedną z technik programowania generycznego.</p>
<h3>Introspekcja w PHP</h3>
<p>Po krótkim wstępie teoretycznym przechodzimy do praktycznego przykładu, wykorzystującego introspekcję. Na początku przykładowa klasa pełniąca rolę królika doświadczalnego.</p>
<pre class="brush: php;">
class Rabbit {

	public $name;

	public function PrintClassName () {

		echo __CLASS__;

	}

	public function PrintRabbitName () {

		echo $this->name;

	}

}
</pre>
<p> Pobierzmy podstawowe informacje o tej klasie. Sposób pierwszy - na podstawie nazwy klasy:</p>
<pre class="brush: php;">
var_dump (class_exists('Rabbit'));
var_dump (get_class_methods('Rabbit'));
var_dump (method_exists('Rabbit','PrintRabbitName'));
var_dump (property_exists('Rabbit','name'));
</pre>
<p>Sposób drugi - korzystając z instancji klasy:</p>
<pre class="brush: php;">
$obj = new Rabbit();
var_dump (get_class_methods($obj));
var_dump (method_exists($obj,'PrintRabbitName'));
var_dump (property_exists($obj,'name'));
</pre>
<p>Omówmy użyte powyżej funkcje:</p>
<ul>
<li><strong>class_exists(</strong><em>string</em><strong> $name)</strong> - zwraca <em>bool</em> informując czy klasa została zdefiniowana czy też nie. <strong>UWAGA!</strong> Funkcja posiada opcjonalny parametr, o którym można przeczytać w dokumentacji.</li>
<li><strong>get_class_methods(</strong><em>mixed</em><strong> $class)</strong> - zwraca <em>array</em> zawierającą wszystkie metody klasy przekazanej w parametrze (instancja lub jej nazwa). Jeśli wystąpił błąd funkcja zwróci <em>NULL</em>.</li>
<li><strong>method_exists(</strong><em>mixed</em><strong> $class, </strong><em>string</em><strong> $method)</strong> - zwraca <em>bool</em> informując czy istnieje metoda <em>$method</em> dla klasy przekazanej w parametrze <em>$class</em> (instancja lub jej nazwa).</li>
<li><strong>property_exists(</strong><em>mixed</em><strong> $class, </strong><em>string</em><strong> $property)</strong> - zwraca <em>bool</em> informując czy istnieje właściwość <em>$property</em> dla klasy przekazanej w parametrze <em>$class</em> (instancja lub jej nazwa).</li>
</ul>
<p>Oczywiście to tylko wybrane funkcje. Zainteresowanych zapraszam <a href="http://www.php.net/manual/en/ref.classobj.php" title="tutaj">TUTAJ</a>. Źródło przykładu zamieszczonego w tym poście znajdziecie <a href="http://blogophp.com/download/introspection.rar" title="przykład">TUTAJ</a>. O refleksji pisałem już trochę <a href="http://blogophp.com/2009/02/22/wstep-do-mechanizmu-refleksji-w-php/" title="tutaj">TUTAJ</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2010/01/03/introspekcja/feed/</wfw:commentRss>
		</item>
		<item>
		<title>stan</title>
		<link>http://blogophp.com/2009/11/22/stan/</link>
		<comments>http://blogophp.com/2009/11/22/stan/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 19:00:24 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
		
		<category><![CDATA[php]]></category>

		<category><![CDATA[wzorce projektowe]]></category>

		<category><![CDATA[wzorzec]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=42</guid>
		<description><![CDATA[Stan to kolejny wzorzec projektowy, z którym chciałbym Was zapoznać. W dużym stopniu wykazuje on podobieństwo do innego wzorca, którego miałem już okazję opisywać - strategii. Stan posługuje się kompozycją obiektów, implementujących ten sam interfejs, przez co pozwala na swobodne zmiany sposobu wykonania tych samych czynności w zależności od potrzeb (a konkretniej stanu obiektu). Cały [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Stan</strong> to kolejny wzorzec projektowy, z którym chciałbym Was zapoznać. W dużym stopniu wykazuje on podobieństwo do innego wzorca, którego miałem już okazję opisywać - strategii. Stan posługuje się kompozycją obiektów, implementujących ten sam interfejs, przez co pozwala na swobodne zmiany sposobu wykonania tych samych czynności w zależności od potrzeb (a konkretniej stanu obiektu).<span id="more-42"></span> Cały proces jest poddany hermetyzacji, zatem używając klasy wykorzystującej ów wzorzec zmiany delegacji są przed nami ukrywane. Choć może się to wydawać troszkę niezrozumiałe, zapraszam do zapoznania się z poniższym przykładem.</p>
<h3>stan w praktyce</h3>
<p>Przyjmijmy następujące założenie. Chcemy uzależnić wywoływanie kolejnych metod na obiekcie, na podstawie typu zmiennej (integer,boolean,itp.) wcześniej do niego przekazanej. Zatem chciałbym, aby do &#8220;obsługi&#8221; integer&#8217;a,boolean&#8217;a został delegowany odpowiedni, dedykowany obiekt. Spójrzmy na poniższy przykład:</p>
<pre class="brush: php;">
interface Stan {

	public function CheckIt ($value);
	public function WriteMessage ();

}
</pre>
<p>Powyżej znajduje się interfejs dla klas (ich implementacja znajduje się poniżej), które będą obsługiwać poszczególne typy zmiennych. Metoda <em>CheckIt($value)</em> sprawdza typ przekazanego parametru a metoda <em>WriteMessage()</em> wypisze go na wyjściu.</p>
<pre class="brush: php;">
class NoStan implements Stan {

	private $stan;

	public function __construct (UseStan $usestan) { 

		$this->stan = $usestan;

	}

	public function CheckIt ($value) {

		if (is_int($value))
			$this->stan->ChangeStan($this->stan->GetIntegerStan());
		elseif (is_bool($value))
			$this->stan->ChangeStan($this->stan->GetBooleanStan());
		elseif (is_string($value))
			$this->stan->ChangeStan($this->stan->GetStringStan());
	}

	public function WriteMessage () {

		echo 'Nie wywolano metody CheckIt()!';

	}

}

class IntegerStan implements Stan {

	private $stan;

	public function __construct (UseStan $usestan) { 

		$this->stan = $usestan;

	}

	public function CheckIt ($value) {

		echo 'Metoda CheckIt() byla juz wolana!';
	}

	public function WriteMessage () {

		$this->stan->ChangeStan($this->stan->GetNoStan());
		echo 'INTEGER';

	}

}

class StringStan implements Stan {

	private $stan;

	public function __construct (UseStan $usestan) { 

		$this->stan = $usestan;

	}

	public function CheckIt ($value) {

		echo 'Metoda CheckIt() byla juz wolana!';
	}

	public function WriteMessage () {

		$this->stan->ChangeStan($this->stan->GetNoStan());
		echo 'STRING';

	}

}

class BooleanStan implements Stan {

	private $stan;

	public function __construct (UseStan $usestan) { 

		$this->stan = $usestan;

	}

	public function CheckIt ($value) {

		echo 'Metoda CheckIt() byla juz wolana!';
	}

	public function WriteMessage () {

		$this->stan->ChangeStan($this->stan->GetNoStan());
		echo 'BOOLEAN';

	}

}
</pre>
<p>Jak widać każdy typ danych ma swoją klasę (string - <em>StringStan</em>, itd.). Wyjątek stanowi <em>NoStan</em>, której zadaniem jest określenie typu zmiennej <em>$value</em> przekazanej w metodzie <em>CheckIt($value)</em>,a następnie wydelegowanie do dalszej obsługi metod interfejsu <em>Stan</em> instancji odpowiedniej klasy(<em>StringStan</em>,<em>BooleanStan</em>,itd.). Może zastanawiać do czego służy i czym jest prywatna właściwość <em>$stan</em> klasy <em>UseStan</em>. Zatem spójrzmy na jej implementację: </p>
<pre class="brush: php;">
class UseStan {

	private $nostan;
	private $integerstan;
	private $stringstan;
	private $booleanstan;

	private $stan;

	public function __construct () {
                // przekazywanie w parametrze obiektu klasy UseStan ($this)
                // pozwoli na swobodna zmiane delegacji przez klasy stanow
                // z uzyciem setter'a stanu i getterow wszystkich stanow
		$this->nostan = new Nostan($this);
		$this->integerstan = new IntegerStan($this);
		$this->stringstan = new StringStan($this);
		$this->booleanstan = new BooleanStan($this);
                // na poczatku nie wiemy jaki typ zmiennej bedzie przekazany, zatem
                // inicjujemy wlasciwosc obiektem klasy NoStan
		$this->stan = $this->nostan;

	}

	//implementacja interfejsu obiektow - stanow

	public function CheckIt ($value) {

		$this->stan->CheckIt($value);

	}

	public function WriteMessage () {

		$this->stan->WriteMessage();

	}

	// metoda delegujaca nowy obiekt stanu do pracy

	public function ChangeStan (Stan $newstan) {

		$this->stan = $newstan;

	}

	// gettery stanów

	public function GetNoStan () {

		return $this->nostan;

	}

	public function GetIntegerStan () {

		return $this->integerstan;

	}

	public function GetStringStan () {

		return $this->stringstan;

	}

	public function GetBooleanStan () {

		return $this->booleanstan;

	}
}
</pre>
<p>Obiekty stanów używają instancji klasy <em>UseStan</em> która je posiada, do zmiany delegacji (stąd gettery wszystkich stanów i setter <em>ChangeStan($nowystan)</em>). Na koniec użycie:</p>
<pre class="brush: php;">
$obj = new UseStan();
// W zaleznosci od typu parametru, zostanie wydelegowana instancja
// odpowiednej klasy do dalszej obslugi metod interfejsu Stan.
$obj->CheckIt(true); 

// Stad tez metoda WriteMessage wywolana zostanie na obiekcie klasy
// BooleanStan a nie zadnym innym.
$obj->WriteMessage();
</pre>
<p>Powyższy przykład jest prosty i ma na celu zrozumienie wzorca <strong>Stan</strong>. Mam nadzieje, iż w jakimś stopniu Wam w tym pomogłem. Kod przykładu znajduje się <a href="http://blogophp.com/download/stan.rar" title="tutaj">TUTAJ</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2009/11/22/stan/feed/</wfw:commentRss>
		</item>
		<item>
		<title>funkcje anonimowe</title>
		<link>http://blogophp.com/2009/10/31/funkcje-anonimowe/</link>
		<comments>http://blogophp.com/2009/10/31/funkcje-anonimowe/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 19:04:33 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
		
		<category><![CDATA[php]]></category>

		<category><![CDATA[anonimowe]]></category>

		<category><![CDATA[funkcje]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=41</guid>
		<description><![CDATA[Dla osób, które miały okazję programować w języku JavaScript zapewne nie będzie to żadna nowość. Niemniej jednak od wersji PHP 5.3, otrzymaliśmy możliwość korzystania z funkcji anonimowych. W tym krótkim wpisie chciałbym wytłumaczyć zasadę ich działania w oparciu o kilka przykładów.
Co to jest?
Funkcja anonimowa, to funkcja jak każda inna z tym wyjątkiem, iż nie wymaga [...]]]></description>
			<content:encoded><![CDATA[<p>Dla osób, które miały okazję programować w języku JavaScript zapewne nie będzie to żadna nowość. Niemniej jednak od wersji <strong>PHP 5.3</strong>, otrzymaliśmy możliwość korzystania z funkcji anonimowych. W tym krótkim wpisie chciałbym wytłumaczyć zasadę ich działania w oparciu o kilka przykładów.<span id="more-41"></span></p>
<h3>Co to jest?</h3>
<p>Funkcja anonimowa, to funkcja jak każda inna z tym wyjątkiem, iż nie wymaga określania jej nazwy i  może zostać przypisana do zmiennej, a następnie wywołana z jej poziomu. Najlepiej będzie to zobrazować na prostym przykładzie:</p>
<pre class="brush: php;">
$zmienna = function () {
	echo 'a';
};

$zmienna();
</pre>
<p>Po wywołaniu powyższego skryptu, na wyjściu otrzymamy:</p>
<div class="codesnip-container" >a</div>
<p>
Prawda, że proste? W ten sposób możemy bezpośrednio definiować funkcje zwrotne w wywołaniach funkcji, które tego wymagają:</p>
<h4>Dla PHP < 5.3</h4>
<pre class="brush: php;">
function echosomething () {

	echo 'callback';

}
// wolanie funkcji zdefiniowanej przez programiste
call_user_func('echosomething');
</pre>
<h4> Dla PHP >= 5.3</h4>
<pre class="brush: php;">
call_user_func(function () { echo 'callback';});
</pre>
<p>Dodatkowo funkcja anonimowa może korzystać ze zmiennych &#8220;dziedziczonych&#8221; z przestrzeni, w której została zdefiniowana. Aby użyć tej opcji, w deklaracji funkcji stosuje się słowo kluczowe <em>use</em>. Spójrzmy na poniższy przykład:</p>
<pre class="brush: php;">
class Przyklad {

	public static function Wypisz () {

		$a = 'in';

		// przestrzenia ponizszej funkcji jest metoda Wypisz()
		$zmienna = function () use ($a) {

			echo $a;

		};

		$zmienna();

	} 

}
$a = 'out';
Przyklad::Wypisz();
</pre>
<p>Na wyjściu ujrzymy napis:</p>
<div class="codesnip-container" >in</div>
<p>
Osoby zainteresowane odsyłam <a href="http://php.net/manual/en/functions.anonymous.php" title="info">TUTAJ</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2009/10/31/funkcje-anonimowe/feed/</wfw:commentRss>
		</item>
		<item>
		<title>dekorator</title>
		<link>http://blogophp.com/2009/08/16/dekorator/</link>
		<comments>http://blogophp.com/2009/08/16/dekorator/#comments</comments>
		<pubDate>Sun, 16 Aug 2009 16:51:14 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
		
		<category><![CDATA[php]]></category>

		<category><![CDATA[wzorce projektowe]]></category>

		<category><![CDATA[dekorator]]></category>

		<category><![CDATA[wzorce]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=40</guid>
		<description><![CDATA[Dekorator to wzorzec projektowy, który z wykorzystaniem kompozycji obiektów, pozwala na dynamiczne dołączanie do klas nowych funkcjonalności. Składa się z obiektu dekorowanego i dekoratorów. Obiekt dekorowany to instancja klasy, którą zamierzamy wzbogacić o dodatkowe zadania. Dekoratory implementują nowe zachowania, aby na końcu delegować wykonanie konkretnych operacji do obiektu dekorowanego. Choć po takim wprowadzeniu ów wzorzec [...]]]></description>
			<content:encoded><![CDATA[<p>Dekorator to wzorzec projektowy, który z wykorzystaniem kompozycji obiektów, pozwala na dynamiczne dołączanie do klas nowych funkcjonalności. Składa się z obiektu dekorowanego i dekoratorów. Obiekt dekorowany to instancja klasy, którą zamierzamy wzbogacić o dodatkowe zadania. Dekoratory implementują nowe zachowania, aby na końcu delegować wykonanie konkretnych operacji do obiektu dekorowanego. <span id="more-40"></span>Choć po takim wprowadzeniu ów wzorzec może się wydawać skomplikowany, to w rzeczywistości jest prosty i niezwykle przydatny. Aby zrozumieć sposób jego działania proponuje zapoznać się z poniższym przykładem.</p>
<h3>Prosty przykład</h3>
<p>Wyobraźmy sobie abstrakcyjną klasę <em>Information</em>, której jedynym zadaniem jest wypisywanie na wyjście wiadomości przekazanej w parametrze metody <em>Write($message)</em>. Spójrzmy na poniższy listing.</p>
<pre class="brush: php;">
abstract class Information {

	abstract public function Write($message);

}
</pre>
<p>Zatem najprostsza implementacja powyższej klasy może wyglądać następująco:</p>
<pre class="brush: php;">
// obiekty tej klasy beda dekorowane

class SimpleText extends Information {

	public function Write ($message) {

		echo $message;

	}

}
</pre>
<p>Nie chcemy jednak, by każdy łańcuch znaków mógł zostać wyświetlony. W związku z tym stworzymy teraz klasy, które zapewnią walidację parametru <em>$message</em>.</p>
<pre class="brush: php;">
// klasa sprawdza dlugosc string'a.

class TextLength extends Information {

	// obiekt dekorowany
	private $decorate;

	public function __construct (Information $dec) {
                // korzystamy z kompozycji obiektow

		$this->decorate = $dec;

	}

	public function Write ($message) {
                // warunek wyswietlenia string'a
		if (isset($message{5}))
			$this->decorate->Write($message);

	}

}

// klasa sprawdza czy pierwsza litera wiadomosci jest A

class FirstLetter extends Information {

	// obiekt dekorowany
	private $decorate;

	public function __construct (Information $dec) {
                //korzystamy z kompozycji obiektow

		$this->decorate = $dec;

	}

	public function Write ($message) {
                //warunek walidacji
		if ($message{0}=='A')
			$this->decorate->Write($message);

	}

}
</pre>
<p>Jeśli chcemy zezwolić na wyświetlanie na wyjściu wiadomości, których długość przekracza pięć znaków wystarczy zapis:</p>
<pre class="brush: php;">
$obj = new TextLength(new SimpleText());
$obj->Write('Napis');
</pre>
<p>Warunki mogą być łatwo dołączane jak zaprezentowano poniżej:</p>
<pre class="brush: php;">
// wyswietli napis gdy bedzie on mial wiecej niz
// 5 znakow a pierwszym bedzie litera A.
$obj = new FirstLetter(new TextLength(new SimpleText()));
$obj->Write('Napis');
</pre>
<p>W ten prosty sposób możemy dowolnie nakładać ograniczenia na parametr <em>$message</em>. Proszę zwrócić uwagę na fakt, iż gdy obiekt dekorowany jest tego samego typu co dekoratory jesteśmy w stanie &#8220;dekorować&#8221; również dekoratory - tak właśnie dzieje się w powyższym przykładzie. Zachęcam do korzystania z tego wzorca. </p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2009/08/16/dekorator/feed/</wfw:commentRss>
		</item>
		<item>
		<title>asercja</title>
		<link>http://blogophp.com/2009/07/27/asercja/</link>
		<comments>http://blogophp.com/2009/07/27/asercja/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 13:00:50 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
		
		<category><![CDATA[apache]]></category>

		<category><![CDATA[php]]></category>

		<category><![CDATA[asercja]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=39</guid>
		<description><![CDATA[Pojęcie asercji wiąże się ściśle z etapem testowania napisanego kodu. Zazwyczaj przyjmuje formę wyrażenia logicznego, które zwraca albo prawdę albo fałsz. Stanowi więc doskonałe narzędzie, dzięki któremu możemy w prosty sposób, wychwycić błędy w pisanych aplikacjach. W PHP dostęp do asercji umożliwiają dwie funkcje assert() i assert_options(). Aby dobrze zrozumieć omawiane zagadnienie, spójrzmy na poniższy [...]]]></description>
			<content:encoded><![CDATA[<p>Pojęcie asercji wiąże się ściśle z etapem testowania napisanego kodu. Zazwyczaj przyjmuje formę wyrażenia logicznego, które zwraca albo prawdę albo fałsz. Stanowi więc doskonałe narzędzie, dzięki któremu możemy w prosty sposób, wychwycić błędy w pisanych aplikacjach. W PHP dostęp do asercji umożliwiają dwie funkcje <em>assert()</em> i <em>assert_options()</em><span id="more-39"></span>. Aby dobrze zrozumieć omawiane zagadnienie, spójrzmy na poniższy przykład.</p>
<h3>Asercja w praktyce</h3>
<p>Na początek zasada działania funkcji <em>assert()</em>.</p>
<pre class="brush: php;">
// asercja z wyrażeniem logicznym które jest zawsze prawdziwe
assert ('12>1');
</pre>
<p>Wykonanie powyższego kodu zakończy się sukcesem, gdyż wyrażenie podane jako parametr funkcji będzie zawsze prawdziwe. Wprowadźmy więc małą zmianę:</p>
<pre class="brush: php;">
// asercja z wyrażeniem logicznym które jest zawsze fałszywe
assert ('12<1');
</pre>
<p>Tym razem zostanie zgłoszony błąd, zgodnie z ustawieniami zdefiniowanymi przy użyciu <em>assert_options()</em>. U mnie na wyjściu otrzymałem następujący komunikat:</p>
<div class="codesnip-container" >Warning: assert() [function.assert]: Assertion &#8220;12<1" failed in assert.php on line 5</div>
</p>
<p>Nasuwa się więc prosty wniosek. Gdy warunek podany w asercji nie jest spełniony jesteśmy w stanie dostrzec i wyeliminować potencjalne błędy w kodzie. Popatrzmy na bardziej skomplikowany przykład:</p>
<pre class="brush: php;">
function getnews ($id) {

	//sprawdzamy czy przekazano integer
	assert ('is_int($id)');
	echo $id;

}

getnews('3');
</pre>
<p>Powyższy skrypt zgłosi błąd, gdyż do funkcji przekazano <em>string</em> a nie <em>integer</em>. Asercja nie została spełniona.</p>
<p>Na koniec pozostało omówienie opcji, które pozwalają skonfigurować asercje w PHP. Do tego celu używa się funkcji <em>assert_options($option,$value)</em>, gdzie pierwszym parametrem jest konkretna opcja, a drugim jej nowa wartość. Jeśli <em>$value</em> nie zostanie przekazana, to zwrócona zostanie bieżąca wartość opcji <em>$option</em>. Opcje konfiguracyjne przedstawiają się następująco:</p>
<ul>
<li><strong>ASSERT_ACTIVE</strong> - asercja włączona lub nie. (<em>true</em> lub <em>false</em>)</li>
<li><strong>ASSERT_WARNING</strong> - asercja generuje ostrzeżenie PHP. (<em>true</em> lub <em>false</em>)</li>
<li><strong>ASSERT_QUIET_EVAL</strong> - generowanie komunikatu w przypadku, gdy w trakcie obliczania wyrażenia logicznego przekazanego w asercji wystąpi błąd. (<em>true</em> lub <em>false</em>)</li>
<li><strong>ASSERT_BAILE</strong> - niespełniona asercja zatrzymuje wykonywanie skryptu. (<em>true</em> lub <em>false</em>)</li>
<li><strong>ASSERT_CALLBACK</strong> - nazwa funkcji, która jest wywoływana w przypadku niespełnienia asercji.</li>
</ul>
<p>To tylko zalążek możliwości jakie oferuje asercja, a zarazem wstęp do pisania testów jednostkowych. Zainteresowanych odsyłam <a href="http://www.phpunit.de/" title="testy">TUTAJ</a>. W przyszłości postaram się do tego tematu powrócić.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2009/07/27/asercja/feed/</wfw:commentRss>
		</item>
		<item>
		<title>directoryiterator</title>
		<link>http://blogophp.com/2009/03/30/directoryiterator/</link>
		<comments>http://blogophp.com/2009/03/30/directoryiterator/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 19:38:32 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
		
		<category><![CDATA[ciekawostki]]></category>

		<category><![CDATA[php]]></category>

		<category><![CDATA[directoryiterator]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=36</guid>
		<description><![CDATA[Być może nie wiecie, ale w PHP 5 istnieje świetna alternatywa dla funkcji opendir(),readdir() czy też scandir().Przedstawiam zatem obiektowy sposób poruszania się po katalogach systemu plików. Spójrzmy na przykład użycia:

try {
	$dir = new DirectoryIterator ('./przykladowy_katalog');

	// $file jest rowniez obiektem klasy DirectoryIterator
	foreach ($dir as $file)
		echo $file->GetFilename();
}
catch (RuntimeException $e) {
	echo $e->getMessage();
}

Pragnę zwrócić uwagę, iż w powyższym skrypcie [...]]]></description>
			<content:encoded><![CDATA[<p>Być może nie wiecie, ale w PHP 5 istnieje świetna alternatywa dla funkcji <em>opendir()</em>,<em>readdir()</em> czy też <em>scandir()</em>.Przedstawiam zatem obiektowy sposób poruszania się po katalogach systemu plików.<span id="more-36"></span> Spójrzmy na przykład użycia:</p>
<pre class="brush: php;">
try {
	$dir = new DirectoryIterator ('./przykladowy_katalog');

	// $file jest rowniez obiektem klasy DirectoryIterator
	foreach ($dir as $file)
		echo $file->GetFilename();
}
catch (RuntimeException $e) {
	echo $e->getMessage();
}
</pre>
<p>Pragnę zwrócić uwagę, iż w powyższym skrypcie przechwytujemy wyjątek <em>RuntimeException</em>, który zostanie zgłoszony np. jeśli katalog przekazany w konstruktorze klasy nie istnieje. </p>
<p>Pozostaje mi omówić kilka podstawowych metod, które dostarcza <em>DirectoryIterator</em>. Zatem:</p>
<ul>
<li><em>bool</em> <strong><em>isDir()</em></strong> - sprawdza czy bieżący element to katalog</li>
<li><em>bool</em> <strong><em>isFile()</em></strong> - sprawdza czy bieżący element to plik</li>
<li><em>bool</em> <strong><em>isDot()</em></strong> - sprawdza czy bieżący element to &#8216;.&#8217; lub &#8216;..&#8217;</li>
<li><em>string</em> <strong><em>getFilename()</em></strong> - zwraca nazwę bieżącego elementu (pliku lub katalogu)</li>
<li><em>int</em> <strong><em>getSize()</em></strong> - zwraca rozmiar pliku</li>
<li><em>bool</em> <strong><em>isReadable()</em></strong> - sprawdza czy plik można odczytać</li>
<li><em>bool</em> <strong><em>isWritable()</em></strong> - sprawdza czy w pliku można zapisywać zmiany</li>
<li><em>bool</em> <strong><em>isExecutable()</em></strong> - sprawdza czy plik można wykonać</li>
<li><em>string</em> <strong><em>getType()</em></strong> - zwraca typ bieżącego elementu (dir,file) a nie MIME!</li>
</ul>
<p>Prawda, że proste i przyjemne? Zainteresowanych odsyłam do oficjalnej dokumentacji, którą można znaleźć <a href="http://pl.php.net/manual/pl/class.directoryiterator.php" title="dokumentacja">TUTAJ</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2009/03/30/directoryiterator/feed/</wfw:commentRss>
		</item>
		<item>
		<title>fasada</title>
		<link>http://blogophp.com/2009/03/08/fasada/</link>
		<comments>http://blogophp.com/2009/03/08/fasada/#comments</comments>
		<pubDate>Sun, 08 Mar 2009 16:50:28 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
		
		<category><![CDATA[php]]></category>

		<category><![CDATA[wzorce projektowe]]></category>

		<category><![CDATA[fasada]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=35</guid>
		<description><![CDATA[Przyszedł czas na zapoznanie się z kolejnym design pattern&#8217;em. Dlaczego właściwie fasada? Jednym z powodów może być fakt, iż często mylony jest lub utożsamiany ze wzorcem adapter, o którym już wcześniej pisałem parę słów. A trzeba to jasno powiedzieć - występują między nimi spore różnice!
fasada
Z założenia tworzy zunifikowany i uproszczony interfejs wysokiego poziomu dla podsystemu, [...]]]></description>
			<content:encoded><![CDATA[<p>Przyszedł czas na zapoznanie się z kolejnym design pattern&#8217;em. Dlaczego właściwie fasada? Jednym z powodów może być fakt, iż często mylony jest lub utożsamiany ze wzorcem adapter, o którym już wcześniej pisałem parę słów.<span id="more-35"></span> A trzeba to jasno powiedzieć - występują między nimi spore różnice!</p>
<h3>fasada</h3>
<p>Z założenia tworzy zunifikowany i uproszczony interfejs wysokiego poziomu dla podsystemu, który korzysta z własnych interfejsów. Wyobraźmy sobie taką sytuację. Wracamy zmęczeni do domu i chcemy się odprężyć. W tym celu włączamy telewizor, potem odtwarzacz dvd, nastawiamy odpowiednią temperaturę w mieszkaniu i przygaszamy światło. Dużo pracy? Nie prościej byłoby posiadać pilot, gdzie za sprawą naciśnięcia jednego przycisku wszystkie te czynności zostałyby wykonane? Rozwiązanie wydaje się być idealne! W programowaniu możemy stosować takie uproszczenie do obsługi zazwyczaj wielu obiektów różnych klas. Na początek prezentuje bardzo abstrakcyjne klasy odzwierciedlające opisaną przeze mnie sytuację.</p>
<pre class="brush: php;">
class Telewizor {

	public function WlaczTV () {

		echo 'Wlaczony TV';

	}

	public function WylaczTV () {

		echo 'Wylaczony TV';

	}

}

class OdtwarzaczDVD {

	public function WlaczDVD () {

		echo 'Wlaczone DVD';

	}

	public function PuscFilm () {

		echo 'Film puszczony';

	}

	public function WylaczDVD () {

		echo 'Wylaczone DVD';

	}

}

class Oswietlenie {

	public function Rozjasnij () {

		echo 'Rozjasnij oswietlenie';

	}

	public function Przygas () {

		echo 'Przygas oswietlenie';

	}

}

class Klimatyzacja {

	private $temp = 20;

	public function UstawTemp ($temp) {

		$this->temp = $temp;
		echo 'Ustawiono temperature '.$temp;

	}

}
</pre>
<p>Teraz zastosujemy omawiany wzorzec w praktyce:</p>
<pre class="brush: php;">
class Obsluga {

	private $tv;
	private $dvd;
	private $light;
	private $aircon;

	public function __construct (Telewizor $a,OdtwarzaczDVD $b,Oswietlenie $c,Klimatyzacja $d) {

		$this->tv = $a;
		$this->dvd = $b;
		$this->light = $c;
		$this->aircon = $d;

	}

	public function Ustaw ($temp) {

		$this->tv->WlaczTV();
		$this->dvd->WlaczDVD();
		$this->dvd->PuscFilm();
		$this->light->Przygas();
		$this->aircon->UstawTemp($temp);

	}

}
</pre>
<p>Oraz użycie:</p>
<pre class="brush: php;">
$fasada = new Obsluga (new Telewizor(),new OdtwarzaczDVD(),new Oswietlenie(),new Klimatyzacja());
$fasada->Ustaw(18);
</pre>
<p>Jak widać jedna metoda wykonuje za nas całą &#8220;brudną&#8221; robotę.</p>
<h3>fasada a adapter</h3>
<p>Różnica tkwi nie w ilości obsługiwanych klas przez oba wzorce! Zapamiętajmy, iż <strong>Adapter</strong> zmienia interfejs, by dostosować się do wymagań klienta, a <strong>Fasada</strong> stara się go uprościć.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2009/03/08/fasada/feed/</wfw:commentRss>
		</item>
		<item>
		<title>serializable</title>
		<link>http://blogophp.com/2009/03/01/serializable/</link>
		<comments>http://blogophp.com/2009/03/01/serializable/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 16:22:06 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
		
		<category><![CDATA[php]]></category>

		<category><![CDATA[serializacja]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=34</guid>
		<description><![CDATA[Oprócz implementacji funkcji magicznych __sleep() i __wakeup() istnieje alternatywne rozwiązanie, pozwalające przejąć kontrolę nad serializacją obiektów. Mowa o interfejsie Serializable. Przyjrzyjmy się mu z bliska:

interface Serializable   {
	abstract public string serialize ( void )
	abstract public mixed unserialize ( string $serialized )
}

Tak więc:

serialize() - wywoływana przy serializacji obiektu klasy. Zwraca string, z danymi które poddaliśmy [...]]]></description>
			<content:encoded><![CDATA[<p>Oprócz implementacji funkcji magicznych <em>__sleep()</em> i <em>__wakeup()</em> istnieje alternatywne rozwiązanie, pozwalające przejąć kontrolę nad serializacją obiektów. Mowa o interfejsie <em>Serializable</em>.<span id="more-34"></span> Przyjrzyjmy się mu z bliska:</p>
<pre class="brush: php;">
interface Serializable   {
	abstract public string serialize ( void )
	abstract public mixed unserialize ( string $serialized )
}
</pre>
<p>Tak więc:</p>
<ul>
<li><em><strong>serialize()</strong></em> - wywoływana przy serializacji obiektu klasy. Zwraca string, z danymi które poddaliśmy temu procesowi.</li>
<li><em><strong>unserialize($data)</strong></em> - wywoływana przy deserializacji. Przesłania konstruktor klasy.</li>
</ul>
<p>Pozostaje napisanie przykładowej klasy korzystającej z możliwości przedstawionego przeze mnie interfejsu. Spójrzmy:</p>
<pre class="brush: php;">
class Example implements Serializable {

	public $a;
	public $b;

	public function __construct () {

		$this->a = 122;
		$this->b = 12;

	}

	public function serialize () {

		return serialize($this->a);

	}

	public function unserialize ($data) {

		$this->a = unserialize($data);

	}

	public function Seta ($setme) {

		$this->a = $setme;

	}

}
</pre>
<p>Oraz użycie:</p>
<pre class="brush: php;">
$obj = new Example();
$obj->Seta(1);
$se = serialize($obj);
var_dump($se);
$un = unserialize($se);
var_dump($un);
</pre>
<p>Zwróćmy uwagę na fakt, iż używając <em>serialize()</em> serializujemy tylko właściwość <em>$this->a</em>. Notomiast wywołanie <em>unserialize()</em> przywraca nam obiekt, ale atrybut <em>$this->b</em> ma wartość NULL, bo nie jest wywoływany konstruktor klasy. Warto o tym pamiętać.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2009/03/01/serializable/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
