<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<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>
	<lastBuildDate>Mon, 26 Dec 2011 22:05:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>traits</title>
		<link>http://blogophp.com/2011/12/27/traits/</link>
		<comments>http://blogophp.com/2011/12/27/traits/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 22:05:29 +0000</pubDate>
		<dc:creator>RalF</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[traits]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=523</guid>
		<description><![CDATA[Cecha to funkcjonalność, która została stworzona, z myślą o tych wszystkich programistach, którym bardzo brakuje możliwości oferowanych przez mechanizm wielokrotnego dziedziczenia. Może się bowiem zdarzyć sytuacja, w której implementowana klasa powinna dziedziczyć, nie po jednej, a po większej ilości klas. Dotychczas rozwiązanie to było niedostępne w PHP, jak i w większości nowoczesnych języków programowania. Cel [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Cecha</strong> to funkcjonalność, która została stworzona, z myślą o tych wszystkich programistach, którym bardzo brakuje możliwości oferowanych przez mechanizm wielokrotnego dziedziczenia. Może się bowiem zdarzyć sytuacja, w której implementowana klasa powinna dziedziczyć, nie po jednej, a po większej ilości klas. Dotychczas rozwiązanie to było niedostępne w PHP, jak i w większości nowoczesnych języków programowania. Cel takiego zagrania wydaje się być oczywisty. Zyskujemy zmniejszenie komplikacji tworzonych projektów, dzięki czemu zdecydowanie łatwiej prześledzić powiązania między klasami i zrozumieć całą strukturę aplikacji. <strong>Traits</strong> są więc panaceum na problemy związane z brakiem wielokrotnego dziedziczenia i będą one dostępne wraz z wydaniem PHP w wersji <strong>5.4</strong>.</p>
<h3>definicja</h3>
<p><strong>Trait</strong> to struktura, która formą deklaracji w dużym stopniu przypomina definicję klasy. Spójrzmy na poniższy przykład:</p>
<pre class="brush:php;">
trait Write {

    public function write () {

        if (isset($this->myName))
            echo $this->myName;

    }

}
</pre>
<p>Słowo kluczowe <em>trait</em> służy do tworzenia cechy. Wewnątrz niej można umieszczać metody i atrybuty. Jak widać na powyższym skrypcie, istnieje tylko jedna funkcja z modyfikatorem dostępu &#8211; publicznym, która wysyła na wyjście wartość zmiennej <em>$this->myName</em>, o ile taką zdefiniowano w klasie, która z cechy korzysta. Sposób użycia ilustruje poniższy fragment kodu:</p>
<pre class="brush:php;">
class Duck {
    use Write;

    private $myName;

    public function __construct ($name) {

        $this->myName = $name;

    }

}

$obj = new Duck ('Donald');
echo $obj->write();
</pre>
<p>Aby klasa mogła w pełni rozkoszować się zaletami cechy <em>Write</em> korzystamy ze słówka kluczowego <em>use</em>.</p>
<h3>przykład praktyczny</h3>
<p>Aby lepiej zrozumieć i wyjaśnić sobie niuanse nowej funkcjonalności napiszmy parę cech, które będą implementować metody o takich samych nazwach:</p>
<pre class="brush:php;">
trait Duck {

    public function write ($message) {

        echo 'Duck ',$message;

    }

}

trait Monkey {

    public function write ($message) {

        echo 'Monkey ',$message;

    }
}

trait Frog {

    public function write ($message) {

        echo 'Frog ',$message;

    }
}

class Animal {
    use Frog,Monkey,Duck;

}

$obj = new Animal();
</pre>
<p>Wykonanie powyższego skryptu skazane jest na porażkę, ponieważ niedozwolone jest korzystanie z wielu cech posiadających takie same nazwy metod. W taki wypadku programista jest zmuszony do wybrania konkretnej funkcji (słowo <em>insteadof</em>), a dla pozostałych skorzystanie z mechanizmu aliasów (słowo <em>as</em>):</p>
<pre class="brush:php;">
//insteadof PRZYKLAD

class Animal {
    use Frog,Monkey,Duck {Monkey::write insteadof Frog,Duck;}

}

$obj = new Animal();
$obj->write('test');
// mozemy uzyc tylko jednej z trzech metod

// as PRZYKLAD

class Animal {
    use Frog,Monkey,Duck {
        Monkey::write insteadof Duck,Frog;
        Duck::write as writeDuck;
        Frog::write as writeFrog;
    }

}

$obj = new Animal();
$obj->writeFrog('test');
$obj->writeDuck('test');
$obj->write('test');
// mozemy skorzystac ze wszystkich trzech metod
</pre>
<p>Oczywiście nic nie stoi na przeszkodzie, by sama klasa <em>Animal</em> posiadała metodę <em>write</em>. W takiej sytuacji w pierwszej kolejności zostanie wywołana właśnie ona. Warto jeszcze wspomnieć o sposobności zmiany modyfikatora dostępu dla cechy. Prezentuje to poniższy przykład:</p>
<pre class="brush:php;">
trait Duck {

    private function write ($message) {

        echo 'Duck ',$message;

    }

}

trait Monkey {

    private function write ($message) {

        echo 'Monkey ',$message;

    }
}

trait Frog {

    private function write ($message) {

        echo 'Frog ',$message;

    }
}

class Animal {
    use Frog,Monkey,Duck {
        Monkey::write insteadof Duck,Frog;
        Duck::write as public writeDuck;
        Frog::write as public writeFrog;
        Monkey::write as public;
    }

}

$obj = new Animal();
$obj->write('test');
$obj->writeFrog('test');
$obj->writeDuck('test');
</pre>
<p>Wypada także zapamiętać, iż nie uda się nam utworzyć obiektu cechy lub skorzystać w jej przypadku z type hinting. Zainteresowanych zachęcam do własnych eksperymentów.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2011/12/27/traits/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>virtual proxy</title>
		<link>http://blogophp.com/2011/10/22/virtual-proxy/</link>
		<comments>http://blogophp.com/2011/10/22/virtual-proxy/#comments</comments>
		<pubDate>Sat, 22 Oct 2011 12:42:06 +0000</pubDate>
		<dc:creator>RalF</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[wzorce projektowe]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[virtual]]></category>
		<category><![CDATA[wzorce]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=464</guid>
		<description><![CDATA[Tym razem zwięźle i lapidarnie na temat virtual proxy. Na początku warto wspomnieć, iż należy on do grupy wzorców strukturalnych i jest przedstawicielem licznej rodziny proxy. W języku polskim określenie to najczęściej tłumaczy się jako pośrednik lub pełnomocnik. Familia proxy skupia się na tworzeniu obiektu, którego zadaniem jest pośrednictwo względem innych obiektów. Wśród najczęściej spotykanych [...]]]></description>
			<content:encoded><![CDATA[<p>Tym razem zwięźle i lapidarnie na temat <strong>virtual proxy</strong>. Na początku warto wspomnieć, iż należy on do grupy wzorców strukturalnych i jest przedstawicielem licznej rodziny proxy. W języku polskim określenie to najczęściej tłumaczy się jako pośrednik lub pełnomocnik. Familia proxy skupia się na tworzeniu obiektu, którego zadaniem jest pośrednictwo względem innych obiektów. Wśród najczęściej spotykanych rodzajów, oprócz omawianego rzecz jasna, można śmiało wymienić:</p>
<ul>
<li><strong>pełnomocnik ochraniający [protection proxy]</strong> &#8211; jego zadaniem jest określanie, czy obiekty chcące uzyskać dostęp do obiektu chronionego posiadają wymagane uprawnienia</li>
<li><strong>pełnomocnik zdalny [remote proxy]</strong> &#8211; jest pośrednikiem w dostępie do obiektów zdalnych</li>
<li><strong>pełnomocnik sprytnego wskaźnika (odwołania) [smart proxy]</strong> &#8211; gdy oprócz dostępu do obiektu konieczne staje się podjęcie dodatkowych akcji &#8211; czynności</li>
</ul>
<p>Powróćmy jednak do głównego bohatera tego wpisu.</p>
<h3>Virtual proxy</h3>
<p>Zadaniem tego wzorca jest reprezentowanie obiektu, którego utworzenie jest kosztowne z punktu widzenia całego systemu. Virtual proxy usiłuje maksymalnie opóźnić ten proces, w międzyczasie starając się w pełni zastąpić właściwy obiekt. Kiedy jest on już dostępny, wszystkie żądania deleguje bezpośrednio do niego. Prześledźmy to na bardzo prostym przykładzie.
</p>
<p>Zakładamy taki oto scenariusz. Na potrzeby naszej aplikacji wykonujemy skomplikowane obliczenia matematyczne. Mamy do tego dedykowaną klasę, jednak utworzenie jej instancji jest bardzo czasochłonne. Jesteśmy też w stanie część obliczeń (głównie tych prostszych) wykonać bez jej udziału. W takim wypadku użycie virtual proxy wydaje się doskonałym rozwiązaniem. Popatrzmy na poniższy fragment kodu, zwracając uwagę na zamieszczone komentarze.</p>
<pre class="brush:php;">
// wspolny interfejs
// implementowany dla posrednika
// i klasy wlasciwej

interface Calculations
{

    public function Sum ($a,$b);
    public function Difference ($a,$b);
    public function Even ($a);

}
</pre>
<p>Gdy posiadamy już interfejs, spójrzmy jak implementuje go klasa właściwa.</p>
<pre class="brush:php;">
// zakladamy ze utworzenie instacji
// tej klasy jest czasochlonne
// i koniecznie tylko dla metody even
class Maths implements Calculations
{

    public function Sum ($a,$b)
    {

        return $a + $b;

    }

    public function Difference ($a,$b)
    {

        return $a - $b;

    }

    public function Even ($a)
    {

        return !($a &#038; 1);

    }

}
</pre>
<p>I jak wygląda kod pośrednika wirtualnego.</p>
<pre class="brush:php;">
// wirtualny posrednik tworzy instancje klasy
// wlasciwej tylko po wywolaniu metody Even. Zakladamy ze
// pozostale funkcje jest w stanie obsluzyc sam.
// Oczywiscie jesli obiekt wlasciwy juz istnieje
// deleguje zadania bezposrednio do niego
class MathsVirtualProxy implements Calculations
{

    private $maths = null;

    public function Sum ($a,$b)
    {

        if ($this->maths instanceof Maths)
            return $this->maths->Sum($a,$b);
        else
            return $a + $b;

    }

    public function Difference ($a,$b)
    {

        if ($this->maths instanceof Maths)
            return $this->maths->Difference($a,$b);
        else
            return $a - $b;

    }

    public function Even ($a)
    {

        if ($this->maths === null) {
            $this->maths = new Maths();
        }
        return $this->maths->Even($a);

    }

}
</pre>
<p>Zatem dopóki nie wywołamy metody <em>Even()</em>, dopóty nie zostanie utworzony obiekt klasy <em>Maths</em>, a <em>VirtualProxyMaths</em> będzie się go starał zastępować. Gdy instancja zostanie stworzona, to wszelkie odwołania będą kierowane już bezpośrednio do niej.</p>
<pre class="brush:php;">
// przyklad aby spradzic jak to wyglada w praktyce
$object = new MathsVirtualProxy();
var_dump($object->Sum(1,2));
var_dump($object);
var_dump($object->Even(1));
var_dump($object);
</pre>
<p><strong>Proszę pamiętać, iż przykład ten jest mocno &#8222;naciągany&#8221;. Miał on bowiem na celu proste wyjaśnienie omawianego wzorca, co mam nadzieję się udało.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2011/10/22/virtual-proxy/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>facebook API</title>
		<link>http://blogophp.com/2011/08/14/facebook-api/</link>
		<comments>http://blogophp.com/2011/08/14/facebook-api/#comments</comments>
		<pubDate>Sun, 14 Aug 2011 15:02:35 +0000</pubDate>
		<dc:creator>RalF</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[facebook]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=56</guid>
		<description><![CDATA[Facebook jest największym serwisem społecznościowym na świecie. Posiada on ogromną ilość aplikacji i gier, które swój żywot zawdzięczają facebook API. We wpisie tym, dokładnie krok po kroku pokażę, jak napisać prostą aplikację z jego użyciem. 1. Rejestracja Choć wydaje się to banalne, to jest to warunek konieczny. Zatem jeśli mamy już własne konto w serwisie, [...]]]></description>
			<content:encoded><![CDATA[<p>Facebook jest największym serwisem społecznościowym na świecie. Posiada on ogromną ilość aplikacji i gier, które swój żywot zawdzięczają <strong>facebook API</strong>. We wpisie tym, dokładnie krok po kroku pokażę, jak napisać prostą aplikację z jego użyciem.</p>
<h3>1. Rejestracja</h3>
<p>Choć wydaje się to banalne, to jest to warunek konieczny. Zatem jeśli mamy już własne konto w serwisie, pomijamy ten krok. Jeśli jest inaczej, zapraszam do formularza rejestracji, który znajdziecie <a href="http://www.facebook.com/" title="tutaj">TUTAJ</a>.</p>
<h3>2. Dodanie aplikacji</h3>
<p>Teraz musimy zgłosić nową aplikację. Po zalogowaniu się, przechodzimy na stronę <a href="http://www.facebook.com/developers" title="deweloperów">deweloperów</a>. Jeśli jesteśmy tu pierwszy raz, to konieczne staje się udzielenie jej odpowiednich uprawnień.</p>
<p style="text-align:center;margin-bottom:0px;padding:0px;"><a target="_blank" href="http://blogophp.com/download/krok1.PNG" title="powieksz"><img style="border:4px solid #B1B1B1;" src="http://blogophp.com/download/krok1_m.PNG" alt="" /></a></p>
<h5 style="text-align:center;margin-top:0px;margin-bottom:10px;">Krok pierwszy &#8211; nadanie uprawnień</h5>
<p style="margin-top:35px;">Teraz należy kliknąć przycisk &#8222;Set Up New App&#8221;.</p>
<p style="text-align:center;margin-bottom:0px;padding:0px;"><a target="_blank" href="http://blogophp.com/download/krok2.PNG" title="powieksz"><img style="border:4px solid #B1B1B1;" src="http://blogophp.com/download/krok2_m.PNG" alt="" /></a></p>
<h5 style="text-align:center;margin-top:0px;margin-bottom:10px;">Krok 2 &#8211; dodawanie nowej aplikacji</h5>
<p style="margin-top:35px;">W pewnych okolicznościach możemy spodziewać się poniższego monitu. Jeśli nasze konto zostanie zweryfikowane, proces będzie kontynuowany. Aby tego dokonać możemy wybrać jedną z dwóch opcji: podpięcie karty płatniczej lub podanie numeru telefonu.</p>
<p style="text-align:center;margin-bottom:0px;padding:0px;"><a target="_blank" href="http://blogophp.com/download/krok3.PNG" title="powieksz"><img style="border:4px solid #B1B1B1;" src="http://blogophp.com/download/krok3_m.PNG" alt="" /></a></p>
<h5 style="text-align:center;margin-top:0px;margin-bottom:10px;">Krok 3 &#8211; monit weryfikacji konta</h5>
<p style="margin-top:35px;">Pozostaje nam  tylko określenie nazwy aplikacji, jej języka i akceptacja regulaminu. Jeśli wszystko przebiegnie bez dodatkowych problemów, to po kliknięciu kontynuuj, zakończymy pomyślnie proces zgłaszania i rejestracji aplikacji na facebooku.</p>
<p style="text-align:center;margin-bottom:0px;padding:0px;"><a target="_blank" href="http://blogophp.com/download/krok4.png" title="powieksz"><img style="border:4px solid #B1B1B1;" src="http://blogophp.com/download/krok4_m.png" alt="" /></a></p>
<h5 style="text-align:center;margin-top:0px;margin-bottom:10px;">Krok 4 &#8211; podstawowe informacje o aplikacji</h5>
<p style="margin-top:35px;">Naszym oczom ukaże się panel zarządzania, identyczny jak na załączonym poniżej obrazku.</p>
<p style="text-align:center;margin-bottom:0px;padding:0px;"><a target="_blank" href="http://blogophp.com/download/krok5.png" title="powieksz"><img style="border:4px solid #B1B1B1;" src="http://blogophp.com/download/krok5_m.png" alt="" /></a></p>
<h5 style="text-align:center;margin-top:0px;margin-bottom:10px;">Krok  5 &#8211; panel zarządzania</h5>
<p style="margin-top:35px;">Po lewej stronie umieszczone zostało menu, składające się z czterech pozycji:<br /><strong>About &#8211; Basic Info</strong> oferuje:
<ul>
<li><strong><em>App ID</em></strong> &#8211; ID naszej aplikacji</li>
<li><strong><em>App Secret</em></strong> &#8211; klucz który będziemy używać w trakcie korzystania z API, nie należy go ujawniać osobom postronnym</li>
<li><strong><em>App Name</em></strong> &#8211; nazwa aplikacji</li>
<li><strong><em>Description</em></strong> &#8211; opis aplikacji</li>
<li><strong><em>Locale</em></strong> &#8211; lokalizacja</li>
<li><strong><em>Icon</em></strong> &#8211; ikona</li>
<li><strong><em>Logo</em></strong> &#8211; logo</li>
<li><strong><em>Contact Email</em></strong> &#8211; email kontaktowy, wykorzystywany przez facebooka do komunikacji z autorem</li>
<li><strong><em>Privacy Policy URL</em></strong> &#8211; adres pod którym umieszczona została polityka prywatności, pole wymagane</li>
<li><strong><em>Terms of Service URL</em></strong> &#8211; adres pod którym znajdują się warunki usługi</li>
<li><strong><em>User Support Email</em></strong> &#8211; email kontaktowy dla użytkowników aplikacji</li>
<li><strong><em>User Support URL</em></strong> &#8211; adres zawierający wsparcie dla użytkowników</li>
</ul>
<p><strong>About &#8211; Roles</strong> pozwala między innymi na określenie administratorów, deweloperów i testerów. Oczywiście jesteśmy w stanie wybrać ich wyłącznie z grupy naszych znajomych. W <strong> About &#8211; Advanced</strong> warto zwrócić uwagę na <em>Sandbox Mode</em>. Aktywowanie ów funkcji, pozwala na używanie napisanego kodu wyłącznie przez deweloperów. Z punktu widzenia bezpieczeństwa, może nas zainteresować pozycja <em>Server Whitelist</em>. Umożliwia ona ustalenie adresów IP, z których będą pochodzić żądania naszej aplikacji. <br/ >
</p>
<p>I teraz przechodzimy do bardzo istotnej rzeczy. Należy sobie zdać sprawę, iż aplikacje na facebooku możemy umieścić na własnej witrynie (opcja menu <strong>Web</strong>) lub &#8222;bezpośrednio&#8221; na facebooku (opcja menu <strong>On facebook</strong>), z wykorzystaniem iframe. Jeśli zdecydujemy się na pierwszą możliwość, to w ustawieniach zobowiązani jesteśmy do określenia dwóch parametrów: <strong>Site URL</strong> (to adres naszej aplikacji) i <strong>Site Domain</strong> (domena naszej aplikacji). Iframe to rozwiązanie alternatywne. Wszelkie opcje z nim związane umieszczono w <strong>On facebook &#8211; canvas settings</strong>:</p>
<ul>
<li><strong><em>Canvas Page</em></strong> &#8211; to wybrany przez nas adres aplikacji na facebooku</li>
<li><strong><em>Canvas URL</em></strong> &#8211; adres pod którym umieściliśmy nasz kod (źródło dla iframe)</li>
<li><strong><em>Secure Canvas URL</em></strong> &#8211; wersja adresu po HTTPS</li>
<li><strong><em>IFrame Size</em></strong> &#8211; rozmiar do wyboru: automatyczny lub z paskiem przewijania</li>
<li><strong><em>Canvas Width</em></strong> &#8211; albo stała szerokość iframe, albo maksymalna dostępna w oparciu o rozdzielczość ekranu użytkownika</li>
<li><strong><em>Bookmark URL</em></strong> &#8211; adres dla zakładki korzystających z aplikacji (po lewej stronie w profilu użytkownika)  &#8211; domyślnie ten sam co <em>Canvas Page</em></li>
<li><strong><em>Social Discovery</em></strong> &#8211; włączona informuje znajomych korzystającego z aplikacji, że jej używa poprzez umieszczenie stosownej informacji na wallu.</li>
<li><strong><em>Tab Name</em></strong> &#8211; w przypadku dodania aplikacji na fanpage&#8217;u, jest to nazwa zakładki jaka się wyświetli po lewej stronie w profilu ów strony &#8211; <a href="http://blogophp.com/download/tabname.png" title="przykład" target="_blank">PRZYKŁAD</a></li>
<li><strong><em>Tab URL</em></strong> &#8211; kliknięcie <em>Tab name</em> otwiera podany tutaj adres</li>
<li><strong><em>Secure Tab URL</em></strong> &#8211; kliknięcie <em>Tab name</em> otwiera podany tutaj adres po HTTPS</li>
<li><strong><em>Edit URL</em></strong> &#8211; adres do edycji ustawień aplikacji dla jej administratorów</li>
</ul>
<p>Zakładka <strong>Facebook Mobile</strong> przeznaczona jest dla programistów oprogramowania na iOS i Android.</p>
<h3>3. Piszemy prostą aplikację</h3>
<p>Dla programistów PHP został udostępniony pakiet SDK, dzięki którego bardzo szybko i prosto jesteśmy w stanie napisać kod wykorzystujący potencjał, jaki oferuje facebook API. Możemy go znaleźć i pobrać <a href="https://github.com/facebook/php-sdk/" title="STĄD">STĄD</a>. Oprócz niezbędnych klas, dostarcza on trywialną ilustrację jego użycia. Najwyższy czas zacząć kodować. Spójrzmy na poniższy skrypt.</p>
<pre class="brush:php;">
// zalaczamy plik
require 'src/facebook.php';

// tworzymy instancje klasy Facebook
// podajac id appki i secret key
$facebook = new Facebook(array(
  'appId'  => 'xxxx',
  'secret' => 'xxxx',
));

// zwraca UID lub 0 w przypadku niepowodzenia
$appUser = $facebook->getUser();
var_dump($appUser);

if ($appUser) {
  try {
    // pobieramy dane o uzytkowniku appki
    $userInfo = $facebook->api('/me');
    var_dump($userInfo);
    // wyswietlamy opcje wylogowania z aplikacji
    echo '<a href="',$facebook->getLogoutUrl(),'">WYLOGUJ</a>';
  } catch (FacebookApiException $e) {
    $appUser = null;
  }
}
if (!$appUser) {
    // jeśli nie to zachecamy do zalogowania
    echo '<a href="',$facebook->getLoginUrl(),'">ZALOGUJ</a>';
}
</pre>
<p>Wydaje się, że powyższy kod nie wymaga dodatkowych wyjaśnień. Zwróćmy jednak uwagę na najważniejsze metody klasy <em>Facebook</em>:</p>
<ul>
<li><em>getLoginUrl($params)</em> &#8211; zwraca adres umożliwiający użytkownikom logowanie się poprzez facebooka</li>
<li><em>getLogoutUrl($params)</em> &#8211; zwraca adres umożliwiający użytkownikom wylogowanie się poprzez facebooka</li>
<li><em>api()</em> &#8211; jedna z najważniejszych funkcji, pozwala korzystać z API facebooka</li>
</ul>
<p>Oczywiście proces logowania nie jest zawsze konieczny. Informacje dostępne publicznie możemy śmiało pobierać poprzez API.</p>
<h3>4. Zwiększanie uprawnień aplikacji</h3>
<p>Introspekcja zmiennej <em>$userInfo</em> pokazuje, iż posiadamy dostęp tylko do podstawowych informacji na temat danego użytkownika. Całe szczęście jesteśmy w stanie poprosić o dostęp do dodatkowych operacji i danych:</p>
<pre class="brush:php;">
// zalaczamy plik
require 'src/facebook.php';

// tworzymy instancje klasy Facebook
// podajac id appki i secret key
$facebook = new Facebook(array(
  'appId'  => 'xxxx',
  'secret' => 'xxxx'
));

// zwraca UID lub 0 w przypadku niepowodzenia
$appUser = $facebook->getUser();

if ($appUser) {
  try {
    // pobieramy dane o uzytkowniku appki
    $userInfo = $facebook->api('/me');
    var_dump($userInfo);
    // wyswietlamy opcje wylogowania z aplikacji
    echo '<a href="',$facebook->getLogoutUrl(),'">WYLOGUJ</a>';
  } catch (FacebookApiException $e) {
    $appUser = null;
  }
}
if (!$appUser) {
    // jeśli nie to zachecamy do zalogowania
    // chcemy miec dostep do emaila i mozliwosci
    // publikacji na wallu usera
    echo '<a href="',$facebook->getLoginUrl(array('scope'=>'email,publish_stream')),'">ZALOGUJ</a>';
}
</pre>
<p>Więcej informacji na temat permissions znajdziecie <a href="http://developers.facebook.com/docs/reference/api/permissions/" target="_blank" title="tutaj">TUTAJ</a>.</p>
<p>Na koniec przykład z umieszczaniem wpisu na wallu użytkownika:</p>
<pre class="brush:php;">
// zalaczamy plik
require 'src/facebook.php';

// tworzymy instancje klasy Facebook
// podajac id appki i secret key
$facebook = new Facebook(array(
  'appId'  => 'xxxx',
  'secret' => 'xxxx'
));

// zwraca UID lub 0 w przypadku niepowodzenia
$appUser = $facebook->getUser();

if ($appUser) {
  try {
    // umieszczamy na wallu wiadomosc test
    $facebook->api('/me/feed','post',array('message'=>'test'));
    // wyswietlamy opcje wylogowania z aplikacji
    echo '<a href="',$facebook->getLogoutUrl(),'">WYLOGUJ</a>';
  } catch (FacebookApiException $e) {
    $appUser = null;
  }
}
if (!$appUser) {
    // jeśli nie to zachecamy do zalogowania
    // chcemy miec dostep do emaila i mozliwosci
    // publikacji na wallu usera
    echo '<a href="',$facebook->getLoginUrl(array('scope'=>'email,publish_stream')),'">ZALOGUJ</a>';
}
</pre>
<p>Aby dobrze zapoznać się z API facebooka, zachęcam do przeglądnięcia dokumentacji udostępnionej pod tym adresem: <a href="https://developers.facebook.com/docs/" title="dokumentacja">DOKUMENTACJA</a>. Oczywiście jest to tylko wstęp do zagadnienia. Obiecuję więc powrót do tego tematu w najbliższym czasie.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2011/08/14/facebook-api/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>bridge</title>
		<link>http://blogophp.com/2011/08/07/bridge/</link>
		<comments>http://blogophp.com/2011/08/07/bridge/#comments</comments>
		<pubDate>Sun, 07 Aug 2011 12:12:47 +0000</pubDate>
		<dc:creator>RalF</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[wzorce projektowe]]></category>
		<category><![CDATA[bridge]]></category>
		<category><![CDATA[projektowe]]></category>
		<category><![CDATA[wzorce]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=304</guid>
		<description><![CDATA[Wpisem tym powracam do tematyki design patterns. Tym razem postaram się wyjaśnić czym jest bridge i w jakich okolicznościach jego użycie może się okazać niezbędne. Jeśli miałbym scharakteryzować most w jednym zdaniu, zapewne przybrałoby ono następującą formę: Jest to wzorzec strukturalny, a jego głównym zadaniem jest oddzielenie implementacji od abstrakcji. W tym lapidarnym stwierdzeniu ukryta [...]]]></description>
			<content:encoded><![CDATA[<p>Wpisem tym powracam do tematyki design patterns. Tym razem postaram się wyjaśnić czym jest <strong>bridge</strong> i w jakich okolicznościach jego użycie może się okazać niezbędne. Jeśli miałbym scharakteryzować <strong>most</strong> w jednym zdaniu, zapewne przybrałoby ono następującą formę: </p>
<blockquote><p>Jest to wzorzec strukturalny, a jego głównym zadaniem jest oddzielenie implementacji od abstrakcji.</p></blockquote>
<p>W tym lapidarnym stwierdzeniu ukryta jest esencja i ogromna moc tego wzorca. Aby go jednak w pełni zrozumieć, najlepiej będzie posłużyć się dwoma prostymi przykładami.</p>
<h3>Przykład pierwszy &#8211; teoretyczny</h3>
<p>Wyobraźmy sobie następującą sytuację. Chcemy stworzyć absolutnie perfekcyjne, pod każdym możliwym względem środowisko graficzne dla systemu operacyjnego. Oczywiście na rynku jest ogromna konkurencja. Każdy ma bowiem prawo stworzyć własny, idealny produkt. W kontekście poruszanego tematu mam na myśli autorską <strong>implementację</strong> ów środowiska, udostępnianego dla systemu operacyjnego &#8211; swego rodzaju klienta. Jak wiadomo cały czas pojawiają się nowsze wersje systemu, w których często wprowadzane są mniejsze lub większe modyfikacje. Aczkolwiek zdecydowana część pozostaje bez zmian. Zastosowanie mostu pomiędzy interfejsem środowiska graficznego a rdzeniem klienta, pozwala na odseparowanie ich od siebie, co niesie za sobą sporo korzyści. Łatwo zauważyć, że zarówno abstrakcja jak i implementacja mogą być rozwijane niezależnie. Poniższy rysunek obrazuje, to co starałem się wyżej wyjaśnić.<br />
<img src="http://blogophp.com/download/most.PNG" alt="" style="width:620px;"/></p>
<h3>Przykład drugi &#8211; praktyczny</h3>
<p>Na ten moment obraz wzorca wydawać się może być nieco mglisty i mało wyraźny. Dlatego też najprościej będzie go zaprezentować, dokonując prostej implementacji. Na starcie stwórzmy sobie interfejs środowiska graficznego:</p>
<pre class="brush:php;">
// interfejs środowiska graficznego
interface Graphics
{

    public function Draw($string);
    public function Ln();
    public function Bold($string);

}
// implementacja srodowiska firmy A
class GraphicsA implements Graphics
{

    public function Draw ($string)
    {

        echo $string;

    }

    public function Ln ()
    {

        echo '';

    }

    public function Bold ($string)
    {

        echo '<strong>',$string,'</strong>';

    }

}

// implementacja srodowiska firmy B
class GraphicsB implements Graphics
{

    public function Draw ($string)
    {

        echo '<em>',$string,'</em>';

    }

    public function Ln ()
    {

        echo '


';

    }

    public function Bold ($string)
    {

        echo '<strong style="color:red;">',$string,'</strong>';

    }

}
</pre>
<p>Teraz czas na abstrakcję:</p>
<pre class="brush:php;">
// abstrakcja rdzenia klienta
// uzywajacego srodowiska graficznego

abstract class System
{
    // MA srodowiska graficzne
    // implementujace interfejs
    // Graphics
    private $graphic;

    public function __construct (Graphics $graphics)
    {

        $this->graphic = $graphics;

    }

    // zwykly setter dla srodowiska
    public function SetGraphics(Graphics $interface)
    {

        $this->graphic = $interface;

    }

    public function Draw ($string)
    {

        $this->graphic->Draw($string);
        $this->graphic->Ln();

    }

    public function Bold ($string)
    {

        $this->graphic->Bold($string);
        $this->graphic->Ln();

    }

}

class MySystem extends System
{

    public function DrawSystemName ()
    {

        $this->Draw(__CLASS__);

    }    

}

class YourSystem extends System
{

    public function DrawMyNameBold ($name)
    {

        $this->Bold($name);

    }

}
</pre>
<p>Oraz wykorzystanie powyższego kodu:</p>
<pre class="brush:php;">
$system = new MySystem(new GraphicsA ());
$system->DrawSystemName();
$system->SetGraphics(new GraphicsB ());
$system->DrawSystemName();

$systemB = new YourSystem(new GraphicsA ());
$systemB->DrawMyNameBold(__FILE__);
$systemB->SetGraphics(new GraphicsB ());
$systemB->DrawMyNameBold(__FILE__);
</pre>
<p>Pragnę zwrócić uwagę na fakt, iż zmiany w interfejsie graficznym nie przełożą się na modyfikacje w klasach rzeczywistych (których może być bardzo dużo!) dziedziczących po <em>System</em>, pod warunkiem hermetyzacji wywołań <em>Graphics</em> w obrębie ów klasy.<br />
Jak zwykle zachęcam do eksperymentów i poszerzania wiedzy w obrębie nie tylko tego, ale również innych wzorców projektowych.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2011/08/07/bridge/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>youtube API</title>
		<link>http://blogophp.com/2011/05/08/youtube-api/</link>
		<comments>http://blogophp.com/2011/05/08/youtube-api/#comments</comments>
		<pubDate>Sun, 08 May 2011 20:01:55 +0000</pubDate>
		<dc:creator>RalF</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[youtube]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=225</guid>
		<description><![CDATA[W trakcie tworzenia przeróżnych aplikacji internetowych zapewne nie raz przyjdzie nam wykorzystać zewnętrzne API, udostępniane przez najpopularniejsze serwisy www w sieci. Mam tu na myśli Facebooka, Twittera czy też właśnie Youtube&#8217;a. Zgodnie z tytułem wpisu, swoją uwagę skupimy dziś na tym ostatnim. Podobnie jak w poście o Amazon S3 i tym razem użyte zostaną odpowiednie [...]]]></description>
			<content:encoded><![CDATA[<p>W trakcie tworzenia przeróżnych aplikacji internetowych zapewne nie raz przyjdzie nam wykorzystać zewnętrzne API, udostępniane przez najpopularniejsze serwisy www w sieci. Mam tu na myśli Facebooka, Twittera czy też właśnie Youtube&#8217;a. Zgodnie z tytułem wpisu, swoją uwagę skupimy dziś na tym ostatnim. Podobnie jak w poście o Amazon S3 i tym razem użyte zostaną odpowiednie biblioteki udostępniane przez Zenda. Osoby nie czujące się w tym temacie zbyt dobrze, odsyłam <a title="t" href="http://blogophp.com/2011/04/16/amazon-s3/">tutaj</a>, gdzie w sposób prosty i klarowny, przedstawiłem najistotniejsze informacje.<span id="more-225"></span></p>
<p>Po tym krótkim wstępie, bez zbędnego owijania w bawełnę, proponuję od razu przejść do kodowania. Aby rozpocząć przygodę z API, wystarczy utworzyć instancję klasy <em>Zend_Gdata_YouTube</em>.</p>
<pre class="brush:php;">require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_YouTube');
$youtubeApi = new Zend_Gdata_YouTube();</pre>
<p>Od teraz możemy swobodnie korzystać z interfejsu, jaki oferuje nam Youtube &#8211; a jest on dość pokaźny. Warto jednak zauważyć, iż wywoływanie niektórych metod, może wymagać autoryzacji, o której jeszcze napiszę parę słów. Na razie skupmy swoją uwagę na czymś prostym i szybkim w implementacji.</p>
<h3>Prosta aplikacja</h3>
<p>Naszym celem będzie napisanie aplikacji oferującej wyszukiwanie filmików Youtube po ich ID i prezentacja danych o ich autorach. Dla osób, które lubią wizualizację w formie use case&#8217;ów zamieszczam poniższą ilustrację.</p>
<p><a href="http://blogophp.com/wp-content/uploads/2011/05/usecase.png"><img class="alignnone size-full wp-image-250" title="usecase" src="http://blogophp.com/wp-content/uploads/2011/05/usecase.png" alt="" width="628" height="276" /></a></p>
<p>Każda aplikacja potrzebuje widoku &#8211; w tym wypadku formularza HTML. Może on wyglądać chociażby tak:</p>
<pre class="brush:plain;">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl" lang="pl"&gt;
    &lt;head&gt;
        &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
        &lt;title&gt;Youtube Api&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;form action="youtubeapp.php" method="post"&gt;
            &lt;fieldset&gt;
                &lt;legend&gt;Wyszukaj po ID&lt;/legend&gt;
                &lt;input type="text" name="videoID" /&gt;
                &lt;input type="submit" value="Szukaj" /&gt;
            &lt;/fieldset&gt;
        &lt;/form&gt;
        &lt;h4&gt;&lt;?php include_once 'data.php'; ?&gt;&lt;/h4&gt;
    &lt;/body&gt;
&lt;/html&gt;</pre>
<p>Co daje nam taki rezultat:</p>
<p><a href="http://blogophp.com/wp-content/uploads/2011/05/Przechwytywanie.png"><img class="alignnone size-full wp-image-258" title="Przechwytywanie" src="http://blogophp.com/wp-content/uploads/2011/05/Przechwytywanie.png" alt="" width="295" height="82" /></a></p>
<p>Żywię nadzieję, iż do tej pory wszystko jest w miarę zrozumiałe. Przed nami bowiem najważniejszy element całej układanki, czyli plik zawierający logikę &#8211; <em>data.php</em>:</p>
<pre class="brush:php;">
if ($_POST) {

    require_once 'Zend/Loader.php';
    Zend_Loader::loadClass('Zend_Gdata_YouTube');
    $youtubeApi = new Zend_Gdata_YouTube();

    try {

        $entryAuthor = $youtubeApi->getVideoEntry($_POST['videoID'])
                                  ->getAuthor();

        foreach ($entryAuthor as $author) {

            echo $author->GetName()
                        ->getText();

        }

    } catch (Zend_Gdata_App_HttpException $e) {

        echo $e->getMessage();

    }

}
</pre>
<p>Jak widać wykonanie aplikacji z <em>Zend_Gdata_YouTube</em> jest trywialne. Pamiętajmy, że na tym nie kończą się możliwości &#8222;read-only&#8221;, klasy użytej w powyższym skrypcie. Wśród wielu oferowanych przez nią metod, warto wymienić tutaj:</p>
<ul>
<li><em>getUserUploads($username)</em> &#8211; zwraca pliki użytkownika <em>$username</em></li>
<li><em>getUserFavorites($username)</em> &#8211; zwraca ulubione użytkownika <em>$username</em></li>
<li><em>getUserProfile($username)</em> &#8211; zwraca profil użytkownika <em>$username</em></li>
<li><em>getTopRatedVideoFeed()</em> &#8211; zwraca listę najwyżej ocenianych plików na Youtube</li>
<li><em>newVideoQuery()</em> &#8211; pozwala tworzyć zapytania do Youtube</li>
</ul>
<p>Jeśli chcemy wykonać operację, która wymaga praw zapisu lub odczytu np. informacji prywatnych, konieczne staje się skorzystanie z procesu autoryzacji.</p>
<h3>Autoryzacja z Youtube API</h3>
<p>Pierwszy krok to rejestracja <a href="http://code.google.com/apis/youtube/dashboard/" title="tutaj">tutaj</a>, w celu uzyskania klucza <em>developer key</em> (konieczne jest rejestracja produktu). Youtube udostępnia dwie metody autoryzacji. Pierwsza <strong>AuthSub</strong> odsyła na witrynę logowania do konta i po pomyślnym procesie przekierowuje na stronę naszej aplikacji, wraz z tokenem niezbędnym do przeprowadzania jakichkolwiek operacji wymagających uwierzytelnienia. Po szczegóły odsyłam do <a href="http://code.google.com/apis/youtube/2.0/developers_guide_php.html#AuthSub_for_Web_Applications" title="">dokumentacji</a>. Druga metoda na której się skupimy to <strong>ClientLogin</strong>. Używa ona bezpośrednio loginu i hasła użytkownika, co odróżnia ją od wcześniej wspomnianego <strong>AuthSub</strong>. Zobaczmy jak wygląda to w praktyce:</p>
<pre class="brush:php;">
    require_once 'Zend/Loader.php';
    Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
    Zend_Loader::loadClass('Zend_Gdata_YouTube');

    // url autoryzacji - pod ten adres idzie POST request - zostawiamy bez zmian!
    $authURL= 'https://www.google.com/accounts/ClientLogin'; 

    try {
        $httpClient = Zend_Gdata_ClientLogin::getHttpClient(
                        // login uzytkownika
                        'adres@gmail.com',
                        // haslo uzytkownika
                        'haselko',
                        // serwis
                        'youtube',
                        null,
                        // krotkiidentyfikator naszej appki (look dokum.)
                        'kroktiIdentyfikatorNaszejAppki',
                        null,
                        null,
                        $authURL,
                        Zend_Gdata_ClientLogin::CLIENTLOGIN_URI,
                        // jesli nasze konto jest polaczone z kontem google to warto
                        // podac GOOGLE w przeciwnym wypadku pomijamy ten parametr
                        'GOOGLE'
                        );

        $devKey = 'tutajDeveloperKey'; // klucz Developer Key naszego produktu
        $applicationId = 'Test123'; // nazwa produktu
        $clientId = 'Moja appka'; // nazwa appki

        $youtubeAPI = new Zend_Gdata_YouTube($httpClient, $applicationId, $clientId, $devKey);

        // przesylamy ID prywatnego wideo wiec wymaga autoryzacji.
        $entryAuthor = $youtubeAPI->getVideoEntry('videoID')
                              ->getAuthor();

          foreach ($entryAuthor as $author) {

              echo $author->GetName()
                          ->getText();

          }

    } catch (Exception $e) {

        echo $e->getMessage();

    }
</pre>
<p>To dokładnie ta sama aplikacja, którą wcześniej zakodowaliśmy, jednak tym razem będzie ona działać również dla prywatnego kontentu (oczywiście musimy mieć do niego dostęp). Na koniec zachęcam do własnych eksperymentów i poszerzania wiedzy w tym temacie, o ile będzie to Wam potrzebne.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2011/05/08/youtube-api/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>fluent interface</title>
		<link>http://blogophp.com/2011/05/03/fluent-interface/</link>
		<comments>http://blogophp.com/2011/05/03/fluent-interface/#comments</comments>
		<pubDate>Tue, 03 May 2011 12:58:01 +0000</pubDate>
		<dc:creator>RalF</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[wzorce projektowe]]></category>
		<category><![CDATA[wzorce]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=59</guid>
		<description><![CDATA[W programowaniu pojęcie fluent interface oznacza stworzenia dla klasy interfejsu, który pozwoli na proste i wygodne z punktu widzenia programisty, wywoływanie wielu metod na pojedynczym obiekcie. Czyni to kod bardziej klarownym, przejrzystym i prostszym w analizie. Można się również pokusić o stwierdzenie, że wygląda to po prostu ładnie. Nie przedłużając, popatrzy na umieszczony poniżej przykład: [...]]]></description>
			<content:encoded><![CDATA[<p>W programowaniu pojęcie fluent interface oznacza stworzenia dla klasy interfejsu, który pozwoli na proste i wygodne z punktu widzenia programisty, wywoływanie wielu metod na pojedynczym obiekcie. Czyni to kod bardziej klarownym, przejrzystym i prostszym w analizie. Można się również pokusić o stwierdzenie, że wygląda to po prostu ładnie.<span id="more-59"></span>
<p style="height:40px;"></p>
<p>Nie przedłużając, popatrzy na umieszczony poniżej przykład:</p>
<pre class="brush: php;">
class Car
{

    private $year;
    private $country;
    private $owner;
    private $counter;

    public function setYear ($year)
    {

        $this->year = $year;

    }

    public function setCountry ($country)
    {

        $this->country = $country;

    }

    public function setOwner ($owner)
    {

        $this->owner = $owner;

    }

    public function setCounter ($counter)
    {

        $this->counter = $counter;

    }

}

$carObject = new Car();
$carObject->setCounter(10);
$carObject->setCountry('PL');
$carObject->setYear(1985);
$carObject->setOwner('ME');
</pre>
<p>Klasa ta posiada zestaw właściwości i odpowiednie metody do nadawania im wartości. Choć używanie ich w ten sposób jest akceptowalne, co nie znaczy, iż procesu tego nie da się uprościć. Jeśli dokonamy małej modyfikacji w implementacji <em>Car</em>, możemy uzyskać omawiany <em>fluent interface</em>:</p>
<pre class="brush: php;">
class Car
{

    private $year;
    private $country;
    private $owner;
    private $counter;

    public function setYear ($year)
    {

        $this->year = $year;
        //zmiana
        return $this;
    }

    public function setCountry ($country)
    {

        $this->country = $country;
        //zmiana
        return $this;

    }

    public function setOwner ($owner)
    {

        $this->owner = $owner;
        //zmiana
        return $this;
    }

    public function setCounter ($counter)
    {

        $this->counter = $counter;
        //zmiana
        return $this;
    }

}

$carObject = new Car();
$carObject->setCounter(10)
          ->setCountry('PL')
          ->setYear(1985)
          ->setOwner('ME');
</pre>
<p>Już na pierwszy rzut oka zastosowanie interfejsu ma sens; upraszcza i ułatwia zrozumienie tak tworzonego kodu. Fluent interface często wykorzystywany jest przy konfiguracji obiektów, choć może mieć też inne zastosowania. Jak zwykle zachęcam do własnych eksperymentów z tym prostym wzorcem.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2011/05/03/fluent-interface/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>amazon s3</title>
		<link>http://blogophp.com/2011/04/16/amazon-s3/</link>
		<comments>http://blogophp.com/2011/04/16/amazon-s3/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 15:28:50 +0000</pubDate>
		<dc:creator>RalF</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[computing]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=122</guid>
		<description><![CDATA[Cloud computing to pojęcie, które ostatnimi czasy elektryzuje wszystkie osoby związane z branżą IT. Niektórzy snują przypuszczenia, iż w niedalekiej przyszłości wyprze on chociażby, dotychczasowy model usługi hostingowej (link). Jednym z liderów na rynku tego typu rozwiązań, jest bez wątpienia Amazon.com. Na przykładzie jednego z oferowanych przez tą firmę produktów - Simple Storage Service (S3), [...]]]></description>
			<content:encoded><![CDATA[<p>Cloud computing to pojęcie, które ostatnimi czasy elektryzuje wszystkie osoby związane z branżą IT. Niektórzy snują przypuszczenia, iż w niedalekiej przyszłości wyprze on chociażby, dotychczasowy model usługi hostingowej (<a title="link" href="http://www.webhosting.pl/Biznes.SaaS.i.chmury.obliczeniowe.czyli.relacja.z.konferencji.WebhostingDay.2009#1" target="_blank">link</a>). Jednym z liderów na rynku tego typu rozwiązań, jest bez wątpienia Amazon.com. Na przykładzie jednego z oferowanych przez tą firmę produktów -<strong> Simple Storage Service (S3)</strong>, chciałbym pokazać przykładowe jego wykorzystanie, w aplikacjach webowych PHP.<span id="more-122"></span> Na początek jednak parę słów o samej chmurze obliczeniowej. Na stronie Wikipedii możemy odnaleźć następującą jej definicję:</p>
<blockquote><p>model przetwarzania oparty na użytkowaniu usług dostarczonych przez zewnętrzne organizacje. Funkcjonalność jest tu  rozumiana jako usługa (dająca wartość dodaną użytkownikowi) oferowana  przez dane oprogramowanie (oraz konieczną infrastrukturę). Oznacza to  eliminację konieczności zakupu licencji czy konieczności instalowania i administracji oprogramowaniem.</p></blockquote>
<p>Osoby zainteresowane poszerzeniem wiedzy w tej tematyce, polecam zapoznanie się z artykułem dostępnym <a title="Cloud computing" href="http://webhosting.pl/Cloud.computing.a.grid.computing.czyli.dlaczego.termin.cloud.computing.nie.jest.kolejnym.buzzword">TUTAJ</a>.</p>
<h3>Case study</h3>
<p>Nasz cel to użycie S3 do przechowywania wszystkich plików przesyłanych za pomocą prostego formularza, umieszczonego na stronie www. W tym celu pierwszym krokiem jest rejestracja na stronie <a title="Amazon webservices" href="http://aws.amazon.com">http://aws.amazon.com</a>. W jej trakcie lub w czasie aktywacji usługi Simple Storage Service, wymaganym etapem będzie dodanie karty kredytowej, jako formy płatności. Wszelkie informacje można uzyskać <a title="Amazon S3" href="http://aws.amazon.com/s3/" target="_blank">TUTAJ</a> &#8211; w tym dokładny opis, system opłat i FAQ. Po pomyślnej rejestracji, logujemy się na nasze konto, przechodzimy do zakładki w której uzyskamy API Key i Secret Key (Account -&gt; Account Activity -&gt; Security Credentials). Będą nam potrzebne w trakcie pisania skryptu.</p>
<p>W tym momencie mamy już wszystko, oprócz odpowiednich bibliotek PHP, których użycie pozwoli nam na szybką implementację usługi Amazonu. W poniższym przykładzie posłużę się rozwiązaniem, udostępnionym przez programistów framework&#8217;a Zend (<a title="http://framework.zend.com//releases/ZendFramework-1.11.5/ZendFramework-1.11.5-minimal.zip" href="http://framework.zend.com//releases/ZendFramework-1.11.5/ZendFramework-1.11.5-minimal.zip">kliknij aby pobrać pliki</a>). Z pobranego archiwum interesuje nas katalog library/Zend.</p>
<h3>Amazon S3</h3>
<p>Zanim przejdziemy do kodowania, parę dość istotnych uwag o samym Simple Storage Service. Wszystkie obiekty przechowywane w S3 są gromadzone w tzw. &#8222;buckets&#8221; &#8211; a ich nazwy są unikalne w obrębie całego systemu, a nie indywidualnego konta. Każdy obiekt w chmurze posiada również zdefiniowane uprawnienia i metadane oraz ścieżkę dostępu: http[s]://[subdomena].amazonaws.com/[unikalna_nazwa_bucket]/[nazwa zasobu]. Oczywiście w nazwach mogą wystąpić tylko określone zestawy znaków. Więcej na ten temat można dowiedzieć się z dokumentacji, do której odsyłam osoby zainteresowane (<a title="http://aws.amazon.com/documentation/s3/" href="http://aws.amazon.com/documentation/s3/" target="_blank">link</a>). Przejdźmy do praktyki!</p>
<h3>Kodujemy</h3>
<p>Na poniższym, archaicznym skrypcie zobrazowałem proces umieszczania plików bezpośrednio w chmurze. Jak widać,  procedura jest dość prosta i nie wymaga dużego nakładu pracy po stronie dewelopera.</p>
<pre class="brush: php;">include_once 'Zend/Service/Amazon/S3.php';

if ($_FILES &amp;&amp; is_uploaded_file($_FILES['test']['tmp_name'])) {

    if ($data = file_get_contents($_FILES['test']['tmp_name'])) {
        // tworzymy obiekt z danymi API KEY i SECRET KEY
        $s3 = new Zend_Service_Amazon_S3('API_KEY', 'API_SECRET');
        // ustalamy permissions - kazdy moze odczytac zasob otwierajac link
        $meta = array(
            Zend_Service_Amazon_S3::S3_ACL_HEADER
            =&gt;
            Zend_Service_Amazon_S3::S3_ACL_PUBLIC_READ
        );
        // Co wazne sciezka musi zawierac nazwe bucketu.
        // Zakladamy tez, ze jest on juz zdefiniowany przez nas,
        // a nazwa pliku nie posiada zakazanych znakow
        if ($s3-&gt;putObject('nazwa_bucketu/'.$_FILES['test']['name'], $data,$meta))
            echo 'UDALO SIE';
        else
            echo 'Nie UDALO SIE';

    }
}</pre>
<p>I do tego formularz:<br />
<code><br />
&lt;form  enctype="multipart/form-data" method="post" action="amazon.php"&gt;<br />
&lt;input type="file" name="test" /&gt;<br />
&lt;input type="submit" value="slij" /&gt;<br />
&lt;/form&gt;<br />
</code><br />
Możliwości klasy <em>Zend_Service_Amazon_S3</em> nie ograniczają się tylko do metody <em>putObject($object,$data,$meta)</em>.<br />
Zarządzanie bucketami:</p>
<ul>
<li><em><strong>createBucket($name)</strong></em> &#8211; tworzenie nowego bucketu o nazwie <em>$name</em></li>
<li><em><strong>cleanBucket($name)</strong></em> &#8211; czyszczenie bucketu <em>$name</em> z wszystkich obiektów</li>
<li><em><strong>removeBucket($name)</strong></em> &#8211; usuwanie bucketu <em>$name</em></li>
<li><em><strong>getBuckets()</strong></em> &#8211; zwraca listę wszystkich bucketów użytkownika</li>
<li><em><strong>isBucketAvailable($name)</strong></em> &#8211; sprawdza dostępność nazwy bucketu</li>
</ul>
<p>Zarządzanie obiektami:</p>
<ul>
<li><strong><em>putObject($object, $data, $meta)</em></strong> &#8211; umieszczanie zasobu w chmurze, musi zawierać w prefiksie nazwę bucketu użytkownika.</li>
<li><strong><em>getObject($object)</em></strong> &#8211; pobranie obiektu o nazwie <em>$object</em>, musi zawierać w prefiksie nazwę bucketu użytkownika.</li>
<li><strong><em>removeObject($object)</em></strong> &#8211; usuwanie obiektu o nazwie <em>$object</em>, musi zawierać w prefiksie nazwę bucketu użytkownika.</li>
</ul>
<p>Z pozostałymi metodami klasy Zend&#8217;a można się zapoznać, przeglądając dokumentację. Zachęcam do eksperymentów i tworzenia bardziej zaawansowanych implementacji w oparciu o cloud computing.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2011/04/16/amazon-s3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>observer</title>
		<link>http://blogophp.com/2011/02/05/observer/</link>
		<comments>http://blogophp.com/2011/02/05/observer/#comments</comments>
		<pubDate>Sat, 05 Feb 2011 13:44:59 +0000</pubDate>
		<dc:creator>RalF</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[wzorce projektowe]]></category>
		<category><![CDATA[wzorce]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=58</guid>
		<description><![CDATA[Obserwator jest wzorcem projektowym, należącym do kategorii czynnościowych. Jak każdy design pattern składa się z kilku elementów, tworzących razem spójną i logiczną całość. Zanim jednak przejdziemy do jego implementacji, na wstępie trochę teorii, celem wyjaśnienia zasad jego działania. Aby proces ten maksymalnie uprościć, posłużmy się przykładem z życia wziętym. obserwator w życiu Często bowiem zdarza [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Obserwator</strong> jest wzorcem projektowym, należącym do kategorii czynnościowych. Jak każdy design pattern składa się z kilku elementów, tworzących razem spójną i logiczną całość. Zanim jednak przejdziemy do jego implementacji, na wstępie trochę teorii, celem wyjaśnienia zasad jego działania. <span id="more-58"></span>Aby proces ten maksymalnie uprościć, posłużmy się przykładem z życia wziętym.</p>
<h3>obserwator w życiu</h3>
<p>Często bowiem zdarza się tak, iż chcemy na bieżąco śledzić wynik jakiegoś meczu, jednak nie mamy na to czasu lub nieszczęśliwy splot wydarzeń nam to uniemożliwia. Jeśli posiadamy telefon komórkowy jest szansa, że nasz operator oferuje usługę śledzenia jego przebiegu, a co najbardziej interesujące &#8211; strzelanych bramek. Jeśli tak, to jesteśmy uratowani. Wystarczy wysłanie odpowiedniej wiadomości sms na konkretny numer. Od tego momentu pozostaje nam tylko czekać na informacje zwrotne, o interesującym nas wydarzeniu. Oczywiście na taką subskrypcję operator nakłada odpowiednie obostrzenia. Po pierwsze każe sobie za to słono płacić, a po drugie &#8211; nic nie trwa wiecznie.</p>
<h3>obserwator w programowaniu</h3>
<p>Obserwator składa się z dwóch podstawowych elementów. Mowa o podmiocie, czyli obiekcie obserwowanym oraz obserwatorach, zwanych obiektami obserwującymi. Zadaniem tego pierwszego jest:</p>
<ul>
<li>dodanie obiektu do listy obiektów obserwujących</li>
<li>usunięcie obiektu z listy obiektów obserwujących</li>
<li>informowanie obiektów obserwujących o konkretnym zdarzeniu (np. zmiana stanu obiektu &#8211; podmiotu)</li>
</ul>
<p>Oczywiście obiekty obserwujące muszą posiadać odpowiedni interfejs za pośrednictwem którego, podmiot poinformuje ich o wszelakich zmianach.</p>
<p>Odnosząc się do przykładu opisanego przeze mnie wyżej, za podmiot w takim ujęciu można uznać operatora komórkowego (dodaje i usuwa nas z listy użytkowników danej usługi, oraz wysyła powiadomienia dotyczące konkretnej tematyki) a obiektami obserwującymi jesteśmy my sami &#8211; dane odbieramy za pośrednictwem naszych telefonów komórkowych.</p>
<h3>obserwator w praktyce</h3>
<p>Wzorzec ten zbudowany jest z dwóch interfejsów. Pierwszy dotyczy podmiotu i możemy go zdefiniować w następujący sposób:</p>
<pre class="brush: php;">interface Subject
{

    public function AddObserver(Observer $obj);
    public function DeleteObserver(Observer $obj);
    public function SendToObservers();

}</pre>
<p>Drugi obiektów obserwujących:</p>
<pre class="brush: php;">interface Observer
{

    public function Update ();

}</pre>
<p>Poniżej przykładowa implementacja klasy, korzystająca z interfejsu <em>Subject</em>:</p>
<pre class="brush: php;">class MySubject implements Subject
{
    private $_objectsList;

    public function AddObserver (Observer $obj) {

        $this-&gt;_objectsList[] = $obj;

    }

    public function DeleteObserver (Observer $obj) {

        $size = count($this-&gt;_objectsList);
        for ($i = 0;$i&lt;$size;$i++)
            if ($this-&gt;_objectsList[$i] === $obj) {
                    unset($this-&gt;_objectsList[$i]);
                    break;
            }

    }

    public function SendToObservers () {

        foreach ($this-&gt;_objectsList as $obj)
            $obj-&gt;Update();

    }
}</pre>
<p>Jak widać <em>SendToObservers()</em> dla wszystkich obiektów obserwujących wywołuje metodę interfejsu <em>Observer</em> &#8211; zatem nasuwa się prosty wniosek, nakazujący wszystkim zainteresowanym śledzeniem obiektów klasy <em>MySubject</em>, jego implementację.</p>
<pre class="brush: php;">class MyObserver implements Observer
{

    public function Update () {

        echo __CLASS__;

    }   

}

class MyObserver2 implements Observer
{

    public function Update () {

        echo __CLASS__;

    }   

}</pre>
<p>I na koniec przykład użycia:</p>
<pre class="brush: php;">// tworzymy podmiot - obiekt obserwowany
$subject = new MySubject();

// tworzymy obiekty obserwujace
$observer1 = new MyObserver();
$observer2 = new MyObserver2();

// dodajemy obiekty obserwujace do podmiotu
$subject-&gt;AddObserver($observer1);
$subject-&gt;AddObserver($observer2);

// wyslanie powiadomien
$subject-&gt;SendToObservers();

// usuniecie z listy obserwujacych
$subject-&gt;DeleteObserver($observer1);

// ponowne wyslanie powiadomien
$subject-&gt;SendToObservers();</pre>
<h3>obserwator w standard php library &#8211; czyli najlepsze rozwiązanie</h3>
<p>Zamiast tworzyć własne interfejsy, możemy skorzystać z tych zdefiniowanych w SPL (co jest wygodniejsze) i dostępnych od wersji <strong>PHP 5.1</strong>. Mam tu na myśli <a title="zobacz" href="http://php.net/manual/pl/class.splsubject.php" target="_blank">SplSubject</a> i <a title="zobacz" href="http://www.php.net/manual/pl/class.splobserver.php" target="_blank">SplObserver</a>:</p>
<pre class="brush: php;">class MySubject implements SplSubject
{
    private $_objectsList;

    public function attach (SplObserver $obj) {

        $this-&gt;_objectsList[] = $obj;

    }

    public function detach (SplObserver $obj) {

        $size = count($this-&gt;_objectsList);
        for ($i = 0;$i&lt;$size;$i++)
            if ($this-&gt;_objectsList[$i] === $obj) {
                    unset($this-&gt;_objectsList[$i]);
                    break;
            }

    }

    public function notify () {

        foreach ($this-&gt;_objectsList as $obj)
            $obj-&gt;update($this);

    }
}

class MyObserver implements SplObserver
{

    public function update (SplSubject $subject) {

        echo __CLASS__;

    }  

}

class MyObserver2 implements SplObserver
{

    public function update (SplSubject $subject) {

        echo __CLASS__;

    }   

}
// tworzymy podmiot - obiekt obserwowany
$subject = new MySubject();

// tworzymy obiekty obserwujace
$observer1 = new MyObserver();
$observer2 = new MyObserver2();

// dodajemy obiekty obserwujace do podmiotu
$subject-&gt;attach($observer1);
$subject-&gt;attach($observer2);

// wyslanie powiadomien
$subject-&gt;notify();

// usuniecie z listy obserwujacych
$subject-&gt;detach($observer1);

// ponowne wyslanie powiadomien
$subject-&gt;notify();</pre>
<p>Jak zwykle zachęcam do pogłębiania wiedzy na temat wzorców. Więcej informacji na ich temat znajdziecie w google, jak również w innych moich wpisach poruszających ich tematykę.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2011/02/05/observer/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>countable</title>
		<link>http://blogophp.com/2011/01/29/countable/</link>
		<comments>http://blogophp.com/2011/01/29/countable/#comments</comments>
		<pubDate>Sat, 29 Jan 2011 12:59:02 +0000</pubDate>
		<dc:creator>RalF</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[countable]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=57</guid>
		<description><![CDATA[Standard PHP Library (SPL) posiada jeden bardzo ciekawy interfejs. Mowa o countable, który pozwala na obiektach klas jego implementujących, wywoływać funkcję count($countableObject). W tym krótkim wpisie pokażę jak tego dokonać, ilustrując to prostym przykładem. Countable składa się z prototypu tylko jednej metody &#8211; count(). Zatem stworzenie przykładowej klasy, korzystającej z dobrodziejstw tegoż interfejsu nie powinno [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Standard PHP Library</strong> (SPL) posiada jeden bardzo ciekawy interfejs. Mowa o <em>countable</em>, który pozwala na obiektach klas jego implementujących, wywoływać funkcję <em>count($countableObject)</em>. W tym krótkim wpisie pokażę jak tego dokonać, ilustrując to prostym przykładem.<span id="more-57"></span></p>
<p><em>Countable</em> składa się z prototypu tylko jednej metody &#8211; <em>count()</em>. Zatem stworzenie przykładowej klasy, korzystającej z dobrodziejstw tegoż interfejsu nie powinno przysporzyć większych problemów. Spójrzmy na poniższą definicję:</p>
<pre class="brush: php;">class Test implements Countable {

	private $_testArray = array ();

	public function __construct(array $newArray) {

		$this-&gt;_testArray = $newArray;

	}

	public function getArray () {

		return $this-&gt;_testArray;

	}

	public function setArray(array $newArray) {

		$this-&gt;_testArray = $newArray;

	}

	// implementacja interfejsu
	// zwracana wartosc wykorzystuje metoda count
	// wywolywana dla obiektow tej klasy
	public function count () {

		return count($this-&gt;_testArray);

	}

}</pre>
<p>No i użycie:</p>
<pre class="brush: php;">$testObject = new Test(array(1,2,3,4,5,6));
echo count($testObject);</pre>
<p>Na wyjściu otrzymujemy:</p>
<p><code>6</code></p>
<p>Osoby zainteresowane SPL zapraszam do zapoznania się z dokumentacją lub moimi poprzednimi wpisami o <strong>DirecotryIterator</strong>, <strong>Serializable</strong>, <strong>ArrayAccess</strong> i <strong>SPL Exceptions</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2011/01/29/countable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SPL exceptions</title>
		<link>http://blogophp.com/2010/12/27/spl-exceptions/</link>
		<comments>http://blogophp.com/2010/12/27/spl-exceptions/#comments</comments>
		<pubDate>Mon, 27 Dec 2010 19:21:24 +0000</pubDate>
		<dc:creator>RalF</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[exceptions]]></category>
		<category><![CDATA[wyjątki]]></category>

		<guid isPermaLink="false">http://blogophp.com/?p=55</guid>
		<description><![CDATA[Wyjątki w PHP zostały wprowadzone wraz z wersją 5.0 tegoż języka. Mechanizm ten bazuje na klasie Exception, która jest podstawowym nośnikiem informacji o błędach, jakie mogą zostać zasygnalizowane przez aplikację. Sam interpreter PHP nie zgłasza wyjątków. Cała praca spoczywa więc po stronie programisty, który musi ów exception wygenerować, a następnie przechwycić i odpowiednio obsłużyć. W [...]]]></description>
			<content:encoded><![CDATA[<p>Wyjątki w PHP zostały wprowadzone wraz z wersją <strong>5.0</strong> tegoż języka. Mechanizm ten bazuje na klasie <em>Exception</em>, która jest podstawowym nośnikiem informacji o błędach, jakie mogą zostać zasygnalizowane przez aplikację. Sam interpreter PHP nie zgłasza wyjątków. <span id="more-55"></span>Cała praca spoczywa więc po stronie programisty, który musi ów exception wygenerować, a następnie przechwycić i odpowiednio obsłużyć. W ramach szybkiego przypomnienia, zapraszam do analizy poniższego przykładu:</p>
<pre class="brush: php;">class Test {

	public function Exception () {

		throw new Exception (__METHOD__);

	}

}

try {
	$obj = new Test();
	$obj-&gt;Exception();
} catch (Exception $e) {
	echo $e-&gt;getMessage();
}</pre>
<p>Oczywiście możemy tworzyć własne klasy, dziedziczące po <em>Exception</em>:</p>
<pre class="brush: php;">class MyFirstException extends Exception {}
class MySecondException extends Exception {}

class Test {

	public function Exception () {

		throw new MySecondException ('MYSECOND '.__METHOD__);

	}

}

try {
	$obj = new Test();
	$obj-&gt;Exception();
} catch (MyFirstException $e) {
	echo $e-&gt;getMessage();
} catch (MySecondException $e) {
	echo $e-&gt;getMessage();
}</pre>
<p>PHP pozwala również napisać własną obsługę wyjątków, które nie zostaną przechwycone. Wystarczy zdefiniować swoją funkcję i zarejestrować ją z wykorzystaniem <em>set_exception_handler($function_name)</em>:</p>
<pre class="brush: php;">function my_exception_handler ($exc) {

	echo 'MY HANDLER EXCEPTION MESSAGE: ',$exc-&gt;getMessage();

}

set_exception_handler('my_exception_handler');

class Test {

	public function Exception () {

		throw new Exception (__METHOD__);

	}

}

$obj = new Test();
$obj-&gt;Exception();
echo 'NIE WYKONA SIE';</pre>
<p>Od wersji <strong>5.3</strong> udostępniono zagnieżdżanie wyjątków (<strong>nesting of exceptions</strong>). Wygląda to mniej więcej tak:</p>
<pre class="brush: php;">class Other_Exception extends Exception {}
class Test_Exception extends Exception {}

class Test {

	public function Exception () {

		throw new Test_Exception(__LINE__);

	}

}

try {

	try {

		$obj = new Test();
		$obj-&gt;Exception();

	} catch (Test_Exception $e) {

		// przekazujemy wyjatek Test_Exception "wyzej"
		throw new Other_Exception(__LINE__,-1,$e);

	}

} catch (Other_Exception $e) {

	// jestesmy w stanie odwolac sie do
	// wyjatku Test_Exception
	// metoda getPrevious
	echo $e-&gt;getPrevious()-&gt;getMessage(),' ',$e-&gt;getMessage();

}</pre>
<h3>SPL</h3>
<p>Standard PHP Library czyli w skrócie <strong>SPL</strong> stanowi zbiór klas i interfejsów, które pozwalają na tworzenie zaawansowanych i ciekawych rozwiązań, w miarę prosty sposób. O elementach tej biblioteki, miałem okazję pisać już niejednokrotnie:</p>
<ul>
<li>klasa <strong>DirectoryIterator</strong> &#8211; <a href="http://blogophp.com/2009/03/30/directoryiterator">TUTAJ</a></li>
<li>interfejs <strong>Serializable</strong> &#8211; <a href="http://blogophp.com/2009/03/01/serializable">TUTAJ</a></li>
<li>interfejs <strong>ArrayAccess</strong> &#8211; <a href="http://blogophp.com/2008/08/10/obiekty-jak-tablice-w-php">TUTAJ</a></li>
</ul>
<p>Wracając do meritum sprawy, w <strong>SPL</strong> zdefiniowano trzynaście klas wyjątków. Najważniejsze dwa to: <em>LogicException</em> i <em>RuntimeException</em>. Oba dziedziczą z <em>Exception</em> i grupują pozostałe jedenaście klas. Cała struktura przedstawia się następująco:</p>
<ul>
<li style="color: red; font-weight: bold;">Exception
<ul style="margin-bottom: 0px;">
<li style="color: blue; font-weight: bold;">LogicException
<ul style="margin-bottom: 0px;">
<li>BadFunctionCallException
<ul style="margin-bottom: 0px;">
<li>BadMethodCallException</li>
</ul>
</li>
<li>DomainException</li>
<li>InvalidArgumentException</li>
<li>LengthException</li>
<li>OutOfRangeException</li>
</ul>
</li>
<li style="color: green; font-weight: bold;">RuntimeException
<ul style="margin-bottom: 0px;">
<li>OutOfBoundsException</li>
<li>OverflowException</li>
<li>RangeException</li>
<li>UnderflowException</li>
<li>UnexpectedValueException</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Wyjątki z grupy <span style="color: blue; font-weight: bold;">LogicalException</span> powinny być zgłaszane w sytuacji zmiany stanu obiektu albo jako konsekwencja przekazania nieprawidłowych argumentów do metod lub funkcji. Odstępstwo od tej reguły stanowią: <em>BadFunctionCallException</em> i <em>BadMethodCallException</em> &#8211; ich użycie wskazane jest w przypadku braku danej funkcji lub metody. Wyjątki należące do <span style="color: green; font-weight: bold;">RuntimeException</span> wyrzucamy w czasie wykonywania się metod lub funkcji. Na koniec praktyczna prezentacja możliwości SPL exceptions:</p>
<pre class="brush: php;">class Test {

	private $intValue;

	public function __construct($intValue) {

		// bledny argument
		// to blad logiczny
		// zwiazany ze stanem obiektu
		if (!is_int($intValue))
			throw new InvalidArgumentException('NOT INTEGER');

		$this-&gt;intValue = $intValue;

	}

	public function __call($method,$args) {

		// taka metoda nie istnieje
		// lub nie jest dostepna
		// czyli blad logiczny
		throw new BadMethodCallException('BAD METHOD');

	}

	public function doSomething () {

		// zakladamy ze cos przebiega nieprawidlowo
		// i wtedy blad czasu wykonania - runtime
		// np niespodziewana wartosc:
		throw new UnexpectedValueException('BAD VALUE');

	}

}

try {

// 	poprawnie bez wyjatkow
	$obj = new Test(4);

//	generuje InvalidArgumentException
//	$obj = new Test('4');

//	generuje BadMethodCallException
//	$obj-&gt;Test();

//	generuje UnexpectedValueException
//	$obj-&gt;doSomething();

} catch (InvalidArgumentException $e) {

	echo $e-&gt;getMessage();

} catch (BadMethodCallException $e) {

	echo $e-&gt;getMessage();

} catch (UnexpectedValueException $e) {

	echo $e-&gt;getMessage();

}</pre>
<p>Osoby zainteresowane poznaniem wszystkich możliwości jakie oferuje SPL, odsyłam do dokumentacji, którą znajdziecie <a title="tutaj" href="http://www.php.net/~helly/php/ext/spl/">TUTAJ</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogophp.com/2010/12/27/spl-exceptions/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

