<?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>&#60;?blog &#187; __wakeup().</title>
	<atom:link href="http://blog.visionsoftware.pl/tag/__wakeup/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.visionsoftware.pl</link>
	<description>...nie tylko o programowaniu</description>
	<lastBuildDate>Sun, 23 Mar 2014 19:23:43 +0000</lastBuildDate>
	<language>pl-PL</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>Metody magiczne w PHP, część druga</title>
		<link>http://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-druga.html</link>
		<comments>http://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-druga.html#comments</comments>
		<pubDate>Tue, 20 Dec 2011 21:25:04 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[metody magiczne]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[__clone()]]></category>
		<category><![CDATA[__sleep()]]></category>
		<category><![CDATA[__toStrnig()]]></category>
		<category><![CDATA[__wakeup().]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=455</guid>
		<description><![CDATA[Jakiś czas temu przedstawiłem pierwszą część z serii artykułów opisujących metody magiczne w PHP. Dzięki ich zastosowaniu możemy uzyskać wiele dodatkowych możliwości podczas korzystania z obiektów. Dziś kolej na opisanie następnych z nich: __toStrnig(), __clone(), __sleep() oraz __wakeup(). Metoda __toString Niniejsza metoda zwraca tekstową reprezentację obiektu i zostanie wywołana w momencie, gdy będziemy chcieli go wyświetlić, na przykład przy pomocy instrukcji echo lub print. Gdy nie zdefiniujemy __toString(), efektem takiego działania będzie błąd i zatrzymanie [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Jakiś czas temu przedstawiłem <a href="http://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-pierwsza.html" title="Metody magiczne PHP">pierwszą część</a> z serii artykułów opisujących metody magiczne w PHP. Dzięki ich zastosowaniu możemy uzyskać wiele dodatkowych możliwości podczas korzystania z obiektów. Dziś kolej na opisanie następnych z nich: <code>__toStrnig()</code>, <code>__clone()</code>, <code>__sleep()</code> oraz <code>__wakeup()</code>.<span id="more-455"></span></p>
<h3>Metoda <code>__toString</code></h3>
<p>Niniejsza metoda zwraca tekstową reprezentację obiektu i zostanie wywołana w momencie, gdy będziemy chcieli go wyświetlić, na przykład przy pomocy instrukcji <code>echo</code> lub <code>print</code>. Gdy nie zdefiniujemy <code>__toString()</code>, efektem takiego działania będzie błąd i zatrzymanie skryptu:</p>
<pre class="brush: php; light: true; title: ; notranslate">
Catchable fatal error: Object of class MyClass could not be converted to string in /sciezka/do/skryptu/skrypt.php on line 13
</pre>
<p>Ważną rzeczą jest, że metoda musi na koniec działania zwracać wartość tekstową. Jeśli będzie to liczba, tablica lub obiekt, wygenerowany zostanie błąd. Można w takim przypadku skorzystać z konwersji typów (rzutowania). Na poniższym skrypcie przedstawiono zastosowanie omawianej metody:</p>
<pre class="brush: php; title: ; notranslate">
class MyClass
{
	private $variable;
	
	public function __construct($parametr)
	{
		$this-&gt;variable = $parametr;
	}
	
	public function __toString()
	{
		return $this-&gt;variable;		
	}
}

$object = new MyClass(&quot;abc&quot;);
echo $object;
</pre>
<p>Efektem działania skryptu będzie po prostu wyświetlenie zawartości właściwości <code>$variable</code>, czyli <code>abc</code>.</p>
<h3>Metoda <code>__clone()</code></h3>
<p>W PHP5 w odróżnieniu od wersji 4 wszystkie obiekty reprezentowane są przez referencję. Nie jest więc możliwe bezpośrednie tworzenie kopii obiektów. Poniższy kod spowoduje przypisanie pod  <code>$anotherObject</code> referencji do <code>$object</code>:</p>
<pre class="brush: php; light: true; title: ; notranslate">
$object = new MyClass();
$anotherObject = $object;
</pre>
<p>W takim przypadku zmiana jednego z obiektów spowoduje więc jednoczesną zmianę drugiego.</p>
<p>Aby utworzyć kopię, musimy skorzystać z instrukcji <code>clone</code>:</p>
<pre class="brush: php; light: true; title: ; notranslate">
$object = new MyClass();
$anotherObject = clone $object;
</pre>
<p>Utworzenie obiektu w powyższy sposób spowoduje, że w przypadku jakiejkolwiek modyfikacji, zmieniamy tylko jeden z nich.</p>
<p>Metoda <code>__clone()</code> jest wywoływana właśnie podczas klonowania obiektu. Dzięki temu możemy wprowadzić w nim określone zmiany. Przedstawiono to na poniższym przykładzie:</p>
<pre class="brush: php; title: ; notranslate">
class MyClass
{
	private $id;
	
	private $variable;
		
	public function __construct($variable)
	{
		$this-&gt;id = md5(rand());
		$this-&gt;variable = $variable;
	}
	
	public function __clone()
	{
		$this-&gt;id = md5(rand());				
	}
}

$object = new MyClass(&quot;abc&quot;);
$object = clone $object;

var_dump($object);
var_dump($object);
</pre>
<p>Wynik działania skryptu będzie następujący:</p>
<pre class="brush: php; light: true; title: ; notranslate">
object(MyClass)#2 (2) {
  [&quot;id&quot;:&quot;MyClass&quot;:private]=&gt;
  string(32) &quot;d204e0411e7921f0b468ddb52ea87fc7&quot;
  [&quot;variable&quot;:&quot;MyClass&quot;:private]=&gt;
  string(3) &quot;abc&quot;
}
object(MyClass)#2 (2) {
  [&quot;id&quot;:&quot;MyClass&quot;:private]=&gt;
  string(32) &quot;d204e0411e7921f0b468ddb52ea87fc7&quot;
  [&quot;variable&quot;:&quot;MyClass&quot;:private]=&gt;
  string(3) &quot;abc&quot;
}
</pre>
<p>Po utworzeniu obiektu <code>$object</code> z podaniem jednego parametru, następuje jego sklonowanie. Konstruktor klasy przypisuje przekazany parametr do odpowiedniej właściwości oraz dodatkowo generuje unikalny identyfikator. Jak jednak widać metoda <code>__clone()</code> wywoływana podczas kopiowania obiektu generuje nowy identyfikator. Widać to wyraźnie po wyświetleniu zawartości obiektów: oba mają tę samą wartość zmiennej <code>$variable</code>, jednak różne <code>$id</code>.</p>
<h3>Metody <code>__sleep()</code> i <code>__wakeup()</code></h3>
<p>Kolejne dwie metody magiczne wywoływane są w przypadku serializacji obiektów. Polega ona (tak samo jak w przypadku tablic), na przekształceniu struktury danych na postać łańcucha znaków, możliwego do ponownego przekształcenia w obiekt. Wykorzystuje się do tego celu funkcje <code>serialize()</code> oraz <code>unserialize()</code>.</p>
<p>Dzięki metodom <code>__sleep()</code> oraz <code>__wakeup()</code> możemy dokonać modyfikacji obiektu oraz wybrać właściwości, które będą poddane serializacji. Metody te nie przyjmują żadnych parametrów, ale <code>__sleep()</code> powinna zwracać indeksowaną tablicę zawierającą nazwy właściwości, jakie poddane zostaną operacji.</p>
<p>Na poniższym przykładzie przedstawiono działanie metod:</p>
<pre class="brush: php; title: ; notranslate">
class MyClass
{
	private $id;
	private $variable1;
	private $variable2;
		
	public function __construct($variable1, $variable2)
	{
		$this-&gt;id = md5(rand());
		$this-&gt;variable1 = $variable1;
		$this-&gt;variable2 = $variable2;
	}
	
	public function __sleep()
	{
		return array(&quot;variable1&quot;);		
	}
	
	public function __wakeup()
	{
		$this-&gt;id = md5(rand());				
	}
}

$object = new MyClass(123, &quot;abc&quot;);
$object_s = serialize($object);
$object_u = unserialize($object_s);

echo &quot;Obiekt:&quot;;
var_dump($object);

echo &quot;Obiekt po serialize():&quot;;
var_dump($object_s);

echo &quot;Obiekt po unserialize():&quot;;
var_dump($object_u);
</pre>
<p>Efekt działania skryptu będzie następujący:</p>
<pre class="brush: php; light: true; title: ; notranslate">
Obiekt:object(MyClass)#1 (3) {
  [&quot;id&quot;:&quot;MyClass&quot;:private]=&gt;
  string(32) &quot;c57ec22b3055e619b765e52dbe9dc5f1&quot;
  [&quot;variable1&quot;:&quot;MyClass&quot;:private]=&gt;
  int(123)
  [&quot;variable2&quot;:&quot;MyClass&quot;:private]=&gt;
  string(3) &quot;abc&quot;
}

Obiekt po serialize():string(50) &quot;O:7:&quot;MyClass&quot;:1:{s:18:&quot;MyClassvariable1&quot;;i:123;}&quot;

Obiekt po unserialize():object(MyClass)#2 (3) {
  [&quot;id&quot;:&quot;MyClass&quot;:private]=&gt;
  string(32) &quot;857590827074cb64b4c0df198ecdc431&quot;
  [&quot;variable1&quot;:&quot;MyClass&quot;:private]=&gt;
  int(123)
  [&quot;variable2&quot;:&quot;MyClass&quot;:private]=&gt;
  NULL
}

</pre>
<p>Na początku tworzony jest obiekt, którego konstruktor przypisuje do dwóch właściwości przekazane parametry, oraz dodatkowo ustala pseudolosowy identyfikator. Następuje później serializacja obiektu, która zmienia jego postać na łańcuch znaków. W tym momencie wywoływana jest metoda <code>__sleep()</code>, która wybiera tylko jedną z właściwości do przechowania. W kolejnym kroku wykonywana jest czynność przywrócenia obiektu, w wyniku której uruchomiona zostaje <code>__wakeup()</code>. Dzięki temu <code>$variable1</code> zostaje odzyskana, jednak druga właściwość <code>$variable2</code> już nie (została pominięta w <code>__sleep()</code>). Dodatkowo wylosowany zostaje nowy identyfikator.</p>
<p><strong>Ciąg dalszy nastąpi&#8230;</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-druga.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
