<?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; php</title>
	<atom:link href="https://blog.visionsoftware.pl/tag/php/feed" rel="self" type="application/rss+xml" />
	<link>https://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>Method chaining w PHP</title>
		<link>https://blog.visionsoftware.pl/programowanie-php/method-chaining-w-php.html</link>
		<comments>https://blog.visionsoftware.pl/programowanie-php/method-chaining-w-php.html#comments</comments>
		<pubDate>Tue, 31 Jul 2012 20:03:08 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[fluent interface]]></category>
		<category><![CDATA[method chaining]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programowanie obiektowe]]></category>
		<category><![CDATA[wzorce projektowe]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=617</guid>
		<description><![CDATA[Zawarta  w tytule nazwa określa implementację wzorca Fluent interface, który odpowiednio zastosowany może uprościć i skrócić tworzony kod. Użycie Method chaining umożliwia cykliczne wywoływanie metod dla obiektu bez jawnego podawania go za każdym razem. Stąd właśnie wzięła się nazwa tej techniki, gdyż wygląda to jak łańcuszek. Jak wygląda uzycie Method chaining w praktyce? Jest on stosowany w wielu różnych językach, a webdeveloperzy mogą go znaleźć między innymi w jQuery lub frameworkach PHP. Upraszcza to znacznie [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Zawarta  w tytule nazwa określa implementację wzorca Fluent interface, który odpowiednio zastosowany może uprościć i skrócić tworzony kod. Użycie Method chaining umożliwia cykliczne wywoływanie metod dla obiektu bez jawnego podawania go za każdym razem. Stąd właśnie wzięła się nazwa tej techniki, gdyż wygląda to jak łańcuszek.<span id="more-617"></span></p>
<h3>Jak wygląda uzycie Method chaining w praktyce?</h3>
<p>Jest on stosowany w wielu różnych językach, a webdeveloperzy mogą go znaleźć między innymi w jQuery lub frameworkach PHP. Upraszcza to znacznie tworzenie kodu, co można zobaczyć na poniższym przykładzie:</p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;p&quot;).removeClass(&quot;class&quot;)
	.addClass(&quot;another_class&quot;)
	.css(&quot;color&quot;,&quot;red&quot;)
	.fadeOut(&quot;slow&quot;);
</pre>
<h3>Jak zaimplementować Method chaining w PHP?</h3>
<p>Bardzo podobnie możemy powyższe rozwiązanie wykorzystać w PHP. Jest to niezwykle proste do osiągnięcia, wystarczy, że poszczególne wywoływane metody będą zwracały cały obiekt. Przez to nie będzie trzeba go podawać za każdym razem, lecz utworzyć odpowiedni łańcuch.</p>
<p>Na poniższym przykładzie przedstawiono implementację Method chaining. Jest to klasa bardzo uproszczonego kalkulatora, dzięki któremu możemy wykonywać podstawowe działania matematyczne.</p>
<pre class="brush: php; title: ; notranslate">
class Calculator{
	private $_result = 0;

	public function __construct($value = 0) {
		$this-&gt;_result = $value;
		return $this;
	}

	public function add($value){
		$this-&gt;_result+=$value;
		return $this;
	}

	public function subtract($value){
		$this-&gt;_result-=$value;
		return $this;
	}

	public function multiply($value){
		$this-&gt;_result*=$value;
		return $this;
	}

	public function divide($value){
		$this-&gt;_result/=$value;
		return $this;
	}

	public function getResult(){
		return $this-&gt;_result;
	}
}
</pre>
<p>Implementacja Metchod chaining kryje się w wywołaniu <code>return $this</code> na końcu każdej metody odpowiedzialnej za działania matematyczne. Dzięki temu będzie możliwe niezwykle proste wykonanie obliczeń:</p>
<pre class="brush: php; title: ; notranslate">
$calc = new Calculator(5);
print $calc-&gt;add(2)
		-&gt;subtract(1)
		-&gt;divide(2)
		-&gt;multiply(3)
		-&gt;getResult();
</pre>
<h3>Pominięcie osobnego tworzenia obiektu</h3>
<p>Możliwe jest także zastosowanie Method chaining bezpośrednio przy wywołaniu obiektu, dzięki czemu nie będziemy musieli tworzyć go w osobnej linii. Wystarczy w tym celu dodać do klasy <code>Calculator</code> statyczną metodę <code>start()</code>, która zwróci nam utworzony obiekt:</p>
<pre class="brush: php; title: ; notranslate">
public static function start($value = 0){
	return new Calculator($value);
}
</pre>
<p>Dzięki takiemu rozwiązaniu możemy jeszcze bardziej uprościć wywołanie kalkulatora:</p>
<pre class="brush: php; title: ; notranslate">
print Calculator::start(5)-&gt;add(4)-&gt;divide(3)-&gt;getResult();
</pre>
]]></content:encoded>
			<wfw:commentRss>https://blog.visionsoftware.pl/programowanie-php/method-chaining-w-php.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP 5.4.3 i PHP 5.3.13 wydane z problemami</title>
		<link>https://blog.visionsoftware.pl/programowanie-php/php-5-4-3-i-php-5-3-13-wydane-z-problemami.html</link>
		<comments>https://blog.visionsoftware.pl/programowanie-php/php-5-4-3-i-php-5-3-13-wydane-z-problemami.html#comments</comments>
		<pubDate>Wed, 09 May 2012 21:50:56 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[PHP 5.3]]></category>
		<category><![CDATA[PHP 5.4]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=591</guid>
		<description><![CDATA[W ostatnich dniach pojawiło się małe zamieszanie przy okazji aktualizacji PHP. 3 maja wypuszczono wersje 5.4.2 i 5.3.12, poprawiające niewykrytą od 8 lat lukę w bezpieczeństwie, obecną w PHP pracującym w trybie CGI. Jak się jednak szybko okazało, nie rozwiązało to problemu i niektóre systemy nadal pozostały na nią podatne. Najnowsze wersje 5.4.3 oraz 5.3.13 mają już rozwiązywać ten problem całkowicie. Na czym polega błąd CVE-2012-182 zgłoszony przez De Eindbazen&#8217;a? Jeśli PHP działa w trybie [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>W ostatnich dniach pojawiło się małe zamieszanie przy okazji aktualizacji PHP. 3 maja wypuszczono wersje 5.4.2 i 5.3.12, poprawiające niewykrytą od 8 lat lukę w bezpieczeństwie, obecną w PHP pracującym w trybie CGI. Jak się jednak szybko okazało, nie rozwiązało to problemu i niektóre systemy nadal pozostały na nią podatne. Najnowsze wersje 5.4.3 oraz 5.3.13 mają już rozwiązywać ten problem całkowicie.<span id="more-591"></span></p>
<p>Na czym polega błąd CVE-2012-182 zgłoszony przez De Eindbazen&#8217;a? Jeśli PHP działa w trybie CGI (np. Apache mod_cgid), możliwe jest przekazywanie dodatkowych parametrów wykonania skryptu. Niestety, z powodu błędnego przetwarzania parametrów w URL, które nie zawierają znaku &#8222;=&#8221;, umożliwia to potencjalnemu intruzowi wykonanie wielu niebezpiecznych czynności. Jedną z nich może być na przykład wyświetlenie kodu przetwarzanego skryptu, czego można dokonać, używając parametru <code>-s</code> w następujący sposób:</p>
<pre class="brush: xml; light: true; title: ; notranslate">

http://localhost/index.php?-s

</pre>
<p>Parametr w postaci <code>?-s&amp;=1</code> jest jednak całkowicie bezpieczny.</p>
<p>Po wydaniu poprawki 5.4.2 i 5.3.12, która miała rozwiązać problem okazało się, że część systemów bazujących na PHP w konfiguracji CGI jest nadal podatna na niebezpieczeństwo. Opublikowane 8 maja wersje PHP 5.4.3 i 5.3.13 powinny ostatecznie rozwiązywać ten problem.</p>
<p>Ci, którzy nie mogą dokonać aktualizacji, powinni do zabezpieczenia się wykorzystać odpowiednie reguły <code>mod_rewrite</code> Apache. Jak podano na php.net, można skorzystać z następującego rozwiązania:</p>
<pre class="brush: xml; light: true; title: ; notranslate">
RewriteCond %{QUERY_STRING} ^[^=]*$
RewriteCond %{QUERY_STRING} %2d|\- [NC]
RewriteRule .? - [F,L]
</pre>
<p>Należy jednak uważać, gdyż powyższe reguły mogą zablokować część poprawnych Urli (np. ?top-40). Z tego względu należy je przetestować i dopasować do swoich potrzeb.</p>
<p>Wersja PHP 5.4.3 dodatkowo rozwiązuje problem z przepełnianiem bufora w <code>apache_request_headers()</code> (CVE-2012-2329). PHP 5.3 nie jest podatne na ten błąd.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.visionsoftware.pl/programowanie-php/php-5-4-3-i-php-5-3-13-wydane-z-problemami.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wydano PHP 5.4.1 i 5.3.11</title>
		<link>https://blog.visionsoftware.pl/programowanie-php/wydano-php-5-4-1-i-5-3-11.html</link>
		<comments>https://blog.visionsoftware.pl/programowanie-php/wydano-php-5-4-1-i-5-3-11.html#comments</comments>
		<pubDate>Fri, 27 Apr 2012 17:53:26 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[PHP 5.3]]></category>
		<category><![CDATA[PHP 5.4]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=568</guid>
		<description><![CDATA[Najnowsza wersja PHP 5.4 doczekała się po niespełna dwóch miesiącach swojej pierwszej poprawki. Także gałąź 5.3 została uaktualniona, lista wszystkich zmian obejmuje poprawę stabilności poprzez poprawienie ponad 60 błędów, z których część związana jest z kwestiami bezpieczeństwa. Lista poprawek odnosi się zarówno do jądra języka, jak i niektórych rozszerzeń. Pełną listę zmian, jakie zostały dokonane w wersjach PHP 5.4.1.oraz 5.3.11, można znaleźć tutaj. Oczywiście wszystkim użytkownikom zaleca się ze względów bezpieczeństwa jak najszybsze uaktualnienie do [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Najnowsza wersja PHP 5.4 doczekała się po niespełna dwóch miesiącach swojej pierwszej poprawki. Także gałąź 5.3 została uaktualniona, lista wszystkich zmian obejmuje poprawę stabilności poprzez poprawienie ponad 60 błędów, z których część związana jest z kwestiami bezpieczeństwa.<span id="more-568"></span></p>
<p>Lista poprawek odnosi się zarówno do jądra języka, jak i niektórych rozszerzeń. Pełną listę zmian, jakie zostały dokonane w wersjach PHP 5.4.1.oraz 5.3.11, można znaleźć <a title="Lista zmian w PHP 5.4.1. i 5.3.11" href="http://www.php.net/ChangeLog-5.php#5.4.1">tutaj</a>. Oczywiście wszystkim użytkownikom zaleca się ze względów bezpieczeństwa jak najszybsze uaktualnienie do najnowszej wersji.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.visionsoftware.pl/programowanie-php/wydano-php-5-4-1-i-5-3-11.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Podpowiadanie typów w PHP</title>
		<link>https://blog.visionsoftware.pl/programowanie-php/podpowiadanie-typow-w-php.html</link>
		<comments>https://blog.visionsoftware.pl/programowanie-php/podpowiadanie-typow-w-php.html#comments</comments>
		<pubDate>Sat, 31 Mar 2012 12:08:32 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[callable]]></category>
		<category><![CDATA[interfejs]]></category>
		<category><![CDATA[obiekt]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[podpowiadanie typów]]></category>
		<category><![CDATA[tablica]]></category>
		<category><![CDATA[type hinting]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=554</guid>
		<description><![CDATA[PHP nie wymaga precyzowania typu podczas definicji zmiennej. Jest on określany na podstawie kontekstu, w jakim ta zmienna została użyta, z możliwością automatycznych konwersji. Możemy także samodzielnie zmieniać typ zmiennej poprzez rzutowanie lub odpowiednie funkcje. Rodzi to problemy szczególnie przy przekazywaniu parametrów do funkcji, jednak w tym przypadku można dla niektórych stosować podpowiadanie typów (ang. type hinting). W PHP mamy do dyspozycji łącznie 9 typów zmiennych: 4 typy proste &#8211; logiczny, całkowity, zmiennoprzecinkowy i znakowy [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>PHP nie wymaga precyzowania typu podczas definicji zmiennej. Jest on określany na podstawie kontekstu, w jakim ta zmienna została użyta, z możliwością automatycznych konwersji. Możemy także samodzielnie zmieniać typ zmiennej poprzez rzutowanie lub odpowiednie funkcje. Rodzi to problemy szczególnie przy przekazywaniu parametrów do funkcji, jednak w tym przypadku można dla niektórych stosować podpowiadanie typów (ang. <em>type hinting</em>).<span id="more-554"></span></p>
<p>W PHP mamy do dyspozycji łącznie 9 typów zmiennych:</p>
<ul>
<li>4 typy proste &#8211; logiczny, całkowity, zmiennoprzecinkowy i znakowy</li>
<li>2 złożone – tablicowy i obiektowy</li>
<li>3 specjalne – identyfikator zasobu (<code>resorce</code>), pusty (<code>NULL</code>) oraz wywoływalny (<code>callable</code>)</li>
</ul>
<p>Podpowiadanie typów w PHP nie umożliwia niestety rozpoznawania wszystkich wymienionych powyżej. Od wersji 5 języka możemy to robić dla obiektów, interfejsów, tablic (od PHP 5.1), oraz parametrów wywoływalnych (PHP 5.4).</p>
<p>Podpowiadanie typów możemy stosować w zwykłych funkcjach, oraz metodach klas. Wystarczy w tym celu przed nazwą zmiennej podać oczekiwany typ (<code>array</code>, <code>callable</code>, nazwę konkretnej klasy lub interfejsu)</p>
<h3>Podpowiadanie typów &#8211; obiekty</h3>
<p>W przypadku podpowiadania typów obiektowych należy pamiętać o bardzo ważnej rzeczy: jeśli parametrem musi być konkretna klasa lub interfejs, dozwoleni są także ich potomkowie, uczestniczący w hierarchii dziedziczenia.</p>
<p>Gdy zostanie określony wymagany typu obiektu, przekazanie innego spowoduje powstanie błędu. Zostało to pokazane na poniższym przykładzie:</p>
<pre class="brush: php; title: ; notranslate">
class Factory{
	public function produce(Product $product){
		print &quot;Produkuję &quot; . get_class($product);
	}
}

class Stock{
	/* ... */
}

class Product{
	/* ... */
}

class Car extends Product{
	/* ... */
}

class Motorbike extends Product{
	/* ... */
}

$factory = new Factory();
$stock = new Stock();
$car = new Car();
$motorbike = new Motorbike();

$factory-&gt;produce($car);
$factory-&gt;produce($motorbike);
$factory-&gt;produce($stock);
</pre>
<p>Zdefiniowane zostały klasy: <code>Factory</code>, <code>Stock</code>, <code>Product</code> oraz dziedziczące po nim <code>Car</code> oraz <code>Motorbike</code>. Klasa fabryki posiada zdefiniowaną jedną metodę, odpowiadającą za produkcję. Wymaga ona przekazania obiektu typu <code>Product</code>. Na powyższym listingu przekazano do niej natomiast dozwolone parametry wywodzące się z klasy <code>Product</code>, ale na koniec omyłkowo także <code>Stock</code>. Efekt będzie następujący:</p>
<pre class="brush: xml; light: true; title: ; notranslate">
Produkuję Car
Produkuję Motorbike
Fatal error: Argument 1 passed to Factory::produce() must be an instance of 
Product, called in typehinting.php on line 31 and defined in typehinting.php 
on line 3
</pre>
<p>Jak wspomniano już wcześniej, podpowiadanie typów w przypadku obiektów działa zarówno dla utworzonych bezpośrednio, jak i dziedziczących po określonym w definicji. Poprawne będzie więc też następujące wywołanie:</p>
<pre class="brush: php; title: ; notranslate">
$factory = new Factory();
$product = new Product();

$factory-&gt;produce($product);
</pre>
<p>W powyższym przypadku może nie jest to do końca pożądane, jednak w praktyce częściej będziemy oczekiwali obiektów klas dziedziczących. Oczywiście, gdy tego chcemy, możemy zawęzić wymagany typ tylko do klasy pochodnej.</p>
<pre class="brush: php; title: ; notranslate">
class Factory{
	public function produce(Car $product){
		print &quot;Produkuję tylko samochody&quot;;
	}
}
</pre>
<p>W przypadku podpowiadania typów można stosować także wartości domyślne. Jeśli w naszej fabryce przewidujemy strajk, możemy posłużyć się następującą definicją:</p>
<pre class="brush: php; title: ; notranslate">
class Factory{
	public function produce(Product $product = null){
		print &quot;Produkuję&quot; . get_class($product);
	}
}

$factory = new Factory();
$factory-&gt;produce();
</pre>
<p>Analogicznie do powyższych informacji, podpowiadanie typów może być używane także w przypadku interfejsów. Wystarczy określić, że parametr musi implementować jeden ze zdefiniowanych. Aby zobrazować tą możliwość, dokonamy pewnych zmian klas z pierwszego przykładu. Otóż w naszej fabryce w Indiach zamierzamy wyprodukować limitowaną wersję samochodu, o zwiększonej mocy silnika. Klasa fabryki otrzyma więc dodatkową możliwość produkcji, a specyfikacja samochodu zostanie odpowiednio zmodyfikowana poprzez implementację interfejsu (pominięto tu klasy zdefiniowane w pierwszym przykładzie):</p>
<pre class="brush: php; title: ; notranslate">
interface limitedEdition{
	public function engineImprovements();
}

class carSpecial extends car implements limitedEdition{
	public function engineImprovements(){
		print &quot;Zwiększona moc silnika&quot;;
	}
}

class FactoryIndia extends Factory {
	public function produceSpecialCar(limitedEdition $car){
		print &quot;Produkuję limitowaną wersję samochodu.&quot;;
	}
}

$factoryIndia = new FactoryIndia();
$car = new car();
$carSpecial = new carSpecial();

$factoryIndia-&gt;produceSpecialCar($carSpecial);
$factoryIndia-&gt;produce($car);
$factoryIndia-&gt;produceSpecialCar($car);
</pre>
<p>Efekt wywołania kodu będzie następujący:</p>
<pre class="brush: xml; light: true; title: ; notranslate">
Produkuję limitowaną wersję samochodu.
Produkuję Car
Fatal error: Argument 1 passed to FactoryIndia::produceSpecialCar() must implement 
interface limitedEdition, called in typehinting.php5 on line 43 and defined in 
typehinting.php on line 32
</pre>
<p>Jak widać, najpierw wyprodukowano edycję limitowaną samochodu przy użyciu nowej linii produkcyjnej, a następnie powrócono do wersji zwykłej. W kolejnym kroku, w wyniku błędu pracownika, uruchomiono jednak ponownie zmodyfikowaną linię produkcyjna dla wersji podstawowej samochodu, co oczywiście zostało szybko wychwycone przez inspektorów kontroli jakości.</p>
<h3>Podpowiadanie typów &#8211; tablice</h3>
<p>Sytuacja jest analogiczna do opisywanych powyżej możliwości w przypadku obiektów. Poniższy przykład obrazuje w jaki sposób zastrzec, aby zdefiniowana funkcja akceptowała jako parametr tylko tablicę:</p>
<pre class="brush: php; title: ; notranslate">
function needArray(array $param){
	print_r($param);
}

$array = array(1, 2, 3);

needArray($array);
</pre>
<p>Możemy także określić domyślą tablicę, dzięki czemu możliwe będzie wywołanie funkcji bez żadnego parametru:</p>
<pre class="brush: php; title: ; notranslate">
function needArray(array $param = array(7, 8, 9)){
	print_r($param);
}
</pre>
<h3>Podpowiadanie typów &#8211; callable</h3>
<p>Jest to najnowsza możliwość podpowiadania typów, wprowadzona w PHP 5.4. Dzięki niej można określić, że parametr przekazywany do funkcji lub metody musi być wywoływalny. Ma to zastosowanie w przypadku stosowania callbacków oraz funkcji anonimowych.</p>
<pre class="brush: php; title: ; notranslate">
function myFunction(callable $callback) {
	echo &quot;Wywołuję callback: &quot; . $callback();
}

myFunction(function() { return 'Witaj!'; });
</pre>
<h3>Podsumowanie</h3>
<p>Jak widać na przedstawionych przykładach, wykorzystanie podpowiadania typów jest niezwykle przydatne i znacznie upraszcza tworzony kod. Nie musimy aż tak wnikliwie sprawdzać przekazywanych argumentów przy pomocy <code>is_array()</code> lub <code>instanceof</code>. Mam nadzieję, że w <em>type hinting</em> w kolejnych wersjach PHP zostanie rozszerzone o typy proste.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.visionsoftware.pl/programowanie-php/podpowiadanie-typow-w-php.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP 5.4 w wersji finalnej wydane!</title>
		<link>https://blog.visionsoftware.pl/programowanie-php/php-5-4-w-wersji-finalnej-wydane.html</link>
		<comments>https://blog.visionsoftware.pl/programowanie-php/php-5-4-w-wersji-finalnej-wydane.html#comments</comments>
		<pubDate>Fri, 02 Mar 2012 22:23:05 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[array dereferencing]]></category>
		<category><![CDATA[callable]]></category>
		<category><![CDATA[closures]]></category>
		<category><![CDATA[indirect method call]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[PHP 5.4]]></category>
		<category><![CDATA[traits]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=527</guid>
		<description><![CDATA[1 marca 2012, po ośmiu kolejnych wydaniach kandydujących i wielu miesiącach pracy, PHP 5.4 zostało wydane w finalnej wersji. Lista dokonanych zmian jest bardzo długa, wprowadzonych zostało sporo nowych elementów, poprawiono wydajność oraz ponad 100 bugów. O większości z tych rzeczy rozpisywano się już nie raz, dlatego postaram się tylko w skrócie podsumować najciekawsze zmiany w PHP 5.4. Większa wydajność Według opinii zamieszczonych w sieci, PHP 5.4 jest nawet o połowę szybsze i zużywa o  [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>1 marca 2012, po ośmiu kolejnych wydaniach kandydujących i wielu miesiącach pracy, PHP 5.4 zostało wydane w finalnej wersji. Lista dokonanych zmian jest bardzo długa, wprowadzonych zostało sporo nowych elementów, poprawiono wydajność oraz ponad 100 bugów. O większości z tych rzeczy rozpisywano się już nie raz, dlatego postaram się tylko w skrócie podsumować najciekawsze zmiany w PHP 5.4.<span id="more-527"></span></p>
<h3>Większa wydajność</h3>
<p>Według opinii zamieszczonych w sieci, PHP 5.4 jest nawet o połowę szybsze i zużywa o  połowę mniej pamięci w stosunku do wersji 5.3.</p>
<h3>Wbudowany serwer WWW</h3>
<p>Do PHP 5.4 jest dołączany uproszczony web serwer, dostępny z poziomu linii komend. Został stworzony tylko do celów developerskich i nie powinien być wykorzystywany w środowisku produkcyjnym.</p>
<h3>Cechy (traits)</h3>
<p>Jedna z najbardziej komentowanych nowości w PHP 5.4, wprowadza możliwość dziedziczenia po wielu klasach. Cechy definiowane są analogicznie do normalnych klas, z wykorzystaniem słowa <code>trait</code>.</p>
<p>Klasy mogą korzystać z wielu cech, które są wymieniane po przecinkach po słowie <code>use</code>. Same cechy także mogą zawierać inne, tworząc ich zbiory. Aby uniknąć konfliktu nazw, możemy wykorzystać składnię <code>insteadof</code>, dzięki której okreslimy, która metoda jest ważniejsza. Oprócz tego możemy z wykorzystaniem słowa <code>use</code> tworzyć dla nich aliasy.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
trait A {
    public function smallTalk() {
        echo 'a';
    }
    public function bigTalk() {
        echo 'A';
    }
}

trait B {
    public function smallTalk() {
        echo 'b';
    }
    public function bigTalk() {
        echo 'B';
    }
}

class Talker {
    use A, B {
        B::smallTalk insteadof A;
        A::bigTalk insteadof B;
    }
}

class Aliased_Talker {
    use A, B {
        B::smallTalk insteadof A;
        A::bigTalk insteadof B;
        B::bigTalk as talk;
    }
}
?&gt;
</pre>
<p>Oprócz tego słowo <code>use</code> może być wykorzystane do zmiany widoczności metody w klasie. Widać to na poniższym przykładzie:</p>
<pre class="brush: php; title: ; notranslate">
public function sayHello() {
        echo 'Hello World!';
    }
}

class MyClass1 {
    use HelloWorld { sayHello as protected; }
}

class MyClass2 {
    use HelloWorld { sayHello as private myPrivateHello; }
}
</pre>
<p>W związku z traits, wprowadzono także nową funkcję <code>class_uses()</code>, która generuje tablicę z cechami, jakich używa dana klasa:</p>
<pre class="brush: php; title: ; notranslate">
trait foo{}
class bar{
use foo;
}
print_r(class_uses(new bar));
print_r(class_uses('bar'));
</pre>
<p>Możliwości traits są znacznie bardziej rozbudowane, przedstawiłem tu jedynie podstawowe informacje. Cechy są jedną z nowości, które wzbudzają dużo emocji. Są bardzo oczekiwanym elementem, który może znacznie poprawić możliwości PHP. Jednak z drugiej strony wiele osób przestrzega przed nadużywaniem cech, co może doprowadzić do pogorszenia jakości kodu.</p>
<h3>Skrócona składnia definiowania tablic</h3>
<p>Dodany został nowy sposób na definiowanie tablic, z zastosowaniem nawiasów kwadratowych:</p>
<pre class="brush: php; title: ; notranslate">
$array1 = [&quot;foo&quot; =&gt; &quot;bar&quot;, &quot;bar&quot; =&gt; &quot;foo&quot;];
$array2 = [1, 23, 34, &quot;foo&quot;];
$array3 = [1, 2, 3, [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;], &quot;x&quot; =&gt; [7, 8, 9]];
</pre>
<h3>Bezpośredni dostęp do elementu tablicy zwracanej przez funkcję (array dereferencing)</h3>
<p>Dotychczas, aby odwołać się do konkretnego elementu tablicy zwracanej przez funkcję, należało najpierw pobrać ją całą do zmiennej, a następnie wybrać ten, który nas interesuje. W PHP 5.4 można to zrobić od razu, wskazując element tablicy bezpośrednio w wywołaniu funkcji:</p>
<pre class="brush: php; title: ; notranslate">
function myFunction() {
   return array(1, 2, 3);
}

echo myFunction()[1];
</pre>
<h3>Wywoływanie metody klasy w zapisie tablicowym (indirect method call)</h3>
<p>Istnieje obecnie możliwość wywołania funkcji danej klasy, podając w tablicy nazwę klasy oraz metodę. Obrazuje to poniższy przykład:</p>
<pre class="brush: php; title: ; notranslate">
class MyClass {
    public function myFunction($name) {
        echo &quot;Witaj $name!&quot;;
    }
}

$fn = array('MyClass', 'myFunction');
$fn(&quot;Marcin&quot;);
</pre>
<h3>Podpowiadanie typów dla callbacków (callable typehint)</h3>
<p>W przypadku callbacków możemy teraz stosować określenie typu parametru za pomocą słowa <code>callable</code>. Na poniższym przykładzie pokazano, jak można w ten sposób wymagać określonego parametru przez zdefiniowana funkcję:</p>
<pre class="brush: php; title: ; notranslate">
function myFunction(callable $callback) {
   echo &quot;Wywołuję callback: &quot; . $callback();
}

myFunction(function() { return 'Witaj!'; });
</pre>
<p>W przypadku, gdy do funkcji zostanie przekazana zmienna innego typu, otrzymamy odpowiedni błąd:</p>
<p>Catchable fatal error: Argument 1 passed to myFunction() must be callable, integer given, called in &#8230;</p>
<h3>Możliwość użycia <code>$this</code> przy funkcjach anonimowych (closures)</h3>
<p>W przypadku stosowania closure i obiektów, nie było możliwe normalne korzystanie z konstrukcji <code>$this</code> (istnieją pewne obejścia tego problemu). Kończyło się to odpowiednim błędem:</p>
<p>Fatal error: Using $this when not in object context in …</p>
<p>Najnowsza wersja PHP rozwiązuje ten problem, wynikiem działania skryptu będzie wyświetlenie zawartości zmiennej <code>$value</code>.</p>
<pre class="brush: php; title: ; notranslate">
class MyClass 
{
  private $value = „PHP 5.4”;
  public function myFunction()
  {
    return function() { return $this-&gt;value; };
  }
}
 
$a = new MyClass;
$fn = $a-&gt;myFunction();
echo $fn();
</pre>
<h3>Notacja binarna dla liczb całkowitych</h3>
<p>Dotychczas możliwe było definiowanie liczb całkowitych w systemie dziesiętnym, ósemkowym oraz szesnastkowym, stosując odpowiednie przedrostki. PHP 5.4 wprowadza taką możliwość także dla liczb binarnych, z wykorzystaniem <code>0b</code>. Poniżej przedstawiono liczbę 28 w różnych notacjach, ostatnia jest możliwa tylko w najnowszej wersji PHP:</p>
<pre class="brush: php; title: ; notranslate">
$dec = 28;
$oct = 034;
$hex = 0x1c;
$bin = 0b11100;
</pre>
<h3>Śledzenie postępu uploadu</h3>
<p>W PHP wbudowano możliwość śledzenia postępu wysyłania danych poprzez formularze. Funkcjonalność jest domyślnie włączona, jej konfiguracja opiera się na grupie zmiennych <code>session.upload_progress.*</code> w <code>php.ini</code>. Dzięki niej możemy określić, jaka ilość danych została już wysłana.</p>
<h3>Inne nowości</h3>
<p>Na zakończenie kilka innych zmian, nie wymagających szczegółowego opisu:</p>
<ul>
<li>Instrukcje <code>break</code> i <code>continue</code> nie będą już przyjmować zmiennych, należy w tym celu stosować stałe</li>
<li>Konstrukcja <code>&lt;?=</code> jest obecnie dostępna niezależnie od ustawienia <code>short_open_tag</code> w <code>php.ini</code></li>
<li>Usunięcie opcji <code>register_globals</code> &#8211; definitywny koniec zmiennych globalnych, które zostały domyślnie wyłączone już PHP 4.2</li>
<li>Usunięcie opcji <code>register_long_arrays</code> z <code>php.ini</code> &#8211; całkowite zrezygnowanie ze starych tablic <code>$HTTP_*_VARS</code> na rzecz krótkiego zapisu (np. <code>$_GET</code> zamiast <code>$HTTP_GET_VARS</code>)</li>
<li>Konwersja tablicy na string powoduje Notice</li>
</ul>
<h3>Podsumowanie</h3>
<p>Jak już wcześniej wspomniałem, pełna <a title="PHP 5.4 Changelog" href="http://php.net/ChangeLog-5.php" target="_blank">lista zmian w PHP 5.4</a> jest niezwykle długa. Wszystkich zainteresowanych odsyłam do dokumentacji. Warto je testować, gdyż wiele z nich może być bardzo pomocna. Oczywiście jak w każdej dziedzinie należy także i tu stosować rozwagę. Pozostaje tylko pytanie, kiedy osoby korzystające z wirtualnych serwerów WWW będą mogly skorzystać z nowych funkcjonalności PHP. Biorąc pod uwagę zwiększenie wydajności nowej wersji (co podoba się hostingodawcom), miejmy nadzieję, że nie będą musiały czekać zbyt długo.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.visionsoftware.pl/programowanie-php/php-5-4-w-wersji-finalnej-wydane.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Odczyt danych GPS ze zdjęcia w PHP</title>
		<link>https://blog.visionsoftware.pl/programowanie-php/odczyt-danych-gps-ze-zdjecia-w-php.html</link>
		<comments>https://blog.visionsoftware.pl/programowanie-php/odczyt-danych-gps-ze-zdjecia-w-php.html#comments</comments>
		<pubDate>Wed, 28 Dec 2011 22:19:18 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[EXIF]]></category>
		<category><![CDATA[GPS]]></category>
		<category><![CDATA[JPG]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zdjęcie]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=465</guid>
		<description><![CDATA[Wykonanie zdjęcia urządzeniem posiadającym GPS, spowoduje zapisanie w nim dodatkowych informacji na temat lokalizacji. Są one przechowywane w metadanych obrazu (EXIF), zatem można je bardzo łatwo odczytać przy pomocy odpowiedniej funkcji dostępnej w PHP. Rozszerzenie do obsługi EXIF zawiera w PHP kilka ciekawych funkcji. Aby było ono dostępne, PHP musi zostać skompilowane z opcją -–enable-exif. Najbardziej przydatną w omawianym przykładzie będzie oczywiście exif_read_data(), która odczytuje nagłówek z plików JPG oraz TIFF. Zwraca ona tablicę z [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Wykonanie zdjęcia urządzeniem posiadającym GPS, spowoduje zapisanie w nim dodatkowych informacji na temat lokalizacji. Są one przechowywane w metadanych obrazu (<code>EXIF</code>), zatem można je bardzo łatwo odczytać przy pomocy odpowiedniej funkcji dostępnej w PHP.<span id="more-465"></span></p>
<p>Rozszerzenie do obsługi <code>EXIF</code> zawiera w PHP kilka ciekawych funkcji. Aby było ono dostępne, PHP musi zostać skompilowane z opcją <code>-–enable-exif</code>. Najbardziej przydatną w omawianym przykładzie będzie oczywiście <code>exif_read_data()</code>, która odczytuje nagłówek z plików JPG oraz TIFF. Zwraca ona tablicę z danymi określającymi urządzenie oraz szczegółowe parametry zdjęcia. Funkcja przyjmuje następujące parametry:</p>
<pre class="brush: php; light: true; title: ; notranslate">
array exif_read_data ( string $filename [, string $sections = NULL [, bool $arrays = false [, bool $thumbnail = false ]]] )
</pre>
<p>Kolejno oznaczają one:</p>
<ul>
<li>filename &#8211; nazwa pliku, z którego odczytujemy dane</li>
<li>sections &#8211; lista sekcji, jakie mają zostać odczytane, np. <code>FILE</code>, <code>COMPUTED</code>, <code>THUMBNAIL</code>, itd. Gdy parametr nie zostanie określony, odczytane zostaną wszystkie</li>
<li>arrays &#8211; określa, czy poszczególne sekcje mają zostać tablicami. <code>COMPUTED</code>, <code>THUMBNAIL</code> oraz <code>COMMENT</code> zawsze zostają zwrócone w ten sposób, gdyż mogą zawierać nazwy powodujące konflikt z innymi sekcjami.</li>
<li>thumbnail &#8211; gdy ustawiony na <code>true</code>, zostanie odczytana miniaturka</li>
</ul>
<p>Standardowe wywołanie funkcji spowoduje pobranie wszystkich danych ze zdjęcia. W przypadku, gdy wykonano je urządzeniem z GPS, pojawią się dodatkowe pola. Pierwszym miejscem, gdzie je zauważymy, jest lista sekcji:</p>
<pre class="brush: php; light: true; title: ; notranslate">
[SectionsFound] =&gt; ANY_TAG, IFD0, THUMBNAIL, EXIF, GPS
</pre>
<p>Wystarczy sprawdzić poszczególne pola, aby oprócz informacji na temat urządzenia oraz parametrów wykonanego zdjęcia, znaleźć także dane GPS. Mogą one wyglądać następująco:</p>
<pre class="brush: php; light: true; title: ; notranslate">
    [GPSLatitudeRef] =&gt; N
    [GPSLatitude] =&gt; Array
        (
            [0] =&gt; 33/1
            [1] =&gt; 52/1
            [2] =&gt; 129675/4096
        )

    [GPSLongitudeRef] =&gt; W
    [GPSLongitude] =&gt; Array
        (
            [0] =&gt; 116/1
            [1] =&gt; 18/1
            [2] =&gt; 23882/4096
        )

    [GPSAltitudeRef] =&gt; 
    [GPSAltitude] =&gt; 304/1
</pre>
<p>Jak widać na przedstawionym przykładzie, możemy odczytać szczegółowe dane na temat współrzędnych geograficznych miejsca, w którym wykonano zdjęcie. Są one wyrażone w stopniach, <code>GPSLatitude</code> oraz <code>GPSLongitude</code> zawierają tablice z odpowiednimi danymi: [0] &#8211; stopnie, [1] &#8211; minuty, [2] &#8211; sekundy (należy podzielić dane liczby). Aby uzyskać stosowane częściej w Google Maps oraz innych serwisach wartości dziesiętne, musimy odpowiednio przeliczyć powyższe dane. Należy w tym celu skorzystać ze wzoru:</p>
<pre class="brush: php; light: true; title: ; notranslate">
DD = D + M/60 + S/3600
</pre>
<p>gdzie D to stopnie, M to minuty, a S to sekundy.</p>
<p>Należy także pamiętać, że w zależności od szerokości i długości geograficznej określonej w <code>GPSLatitudeRef</code> oraz <code>GPSLongitudeRef</code> musimy postawić odpowiednio znak minus. W tym przypadku jest tak dla drugiej wartości, która wskazuje na zachód (podobnie należy zrobić dla południa).</p>
<p>Ostatecznie przeliczone współrzędne posiadają następujące wartości 33.87555556 oraz -116.30166667 (dla 33&deg; 52&apos; 32&quot; N i 116&deg; 18&apos; 06&quot; W).</p>
<p>Tablica z danymi GPS zawiera także wartość <code>GPSAltitude</code>, która określa wysokość w metrach, na jakiej wykonano zdjęcie.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.visionsoftware.pl/programowanie-php/odczyt-danych-gps-ze-zdjecia-w-php.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Metody magiczne w PHP, część druga</title>
		<link>https://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-druga.html</link>
		<comments>https://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>https://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-druga.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wydano PHP 5.4 RC2</title>
		<link>https://blog.visionsoftware.pl/programowanie-php/wydano-php-5-4-rc2.html</link>
		<comments>https://blog.visionsoftware.pl/programowanie-php/wydano-php-5-4-rc2.html#comments</comments>
		<pubDate>Wed, 30 Nov 2011 21:53:02 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=445</guid>
		<description><![CDATA[Oczekiwane przez wszystkich PHP 5.4 zbliża się coraz większymi krokami. Opublikowane zostało drugie już wydanie kandydujące, w którym poprawiono kolejne błędy i poprawiono stabilność działania. W stosunku do poprzedniej wersji RC1 poprawiono błędy w jądrze PHP oraz Zend Engine. Dodatkowo od tej edycji PHP-FPM nie będzie oznaczone jako eksperymentalne. Pełną listę zmian można znaleźć tutaj. Do czasu wydania ostatecznej wersji PHP 5.4.0 nie będą już dodawane nowe funkcjonalności, a prowadzone prace mają się skupić wyłącznie [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Oczekiwane przez wszystkich PHP 5.4 zbliża się coraz większymi krokami. Opublikowane zostało drugie już wydanie kandydujące, w którym poprawiono kolejne błędy i poprawiono stabilność działania.<span id="more-445"></span></p>
<p>W stosunku do poprzedniej wersji RC1 poprawiono błędy w jądrze PHP oraz Zend Engine. Dodatkowo od tej edycji PHP-FPM nie będzie oznaczone jako eksperymentalne. Pełną listę zmian można znaleźć <a title="PHP 5.4 RC2" href="https://svn.php.net/repository/php/php-src/tags/php_5_4_0RC2/NEWS">tutaj</a>.</p>
<p>Do czasu wydania ostatecznej wersji PHP 5.4.0 nie będą już dodawane nowe funkcjonalności, a prowadzone prace mają się skupić wyłącznie na wyeliminowaniu występujących błędów i poprawieniu stabilności działania.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.visionsoftware.pl/programowanie-php/wydano-php-5-4-rc2.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Metody magiczne w PHP, część pierwsza</title>
		<link>https://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-pierwsza.html</link>
		<comments>https://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-pierwsza.html#comments</comments>
		<pubDate>Wed, 30 Nov 2011 21:22:07 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[destruktor]]></category>
		<category><![CDATA[konstruktor]]></category>
		<category><![CDATA[metody magiczne]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[__call().]]></category>
		<category><![CDATA[__construct()]]></category>
		<category><![CDATA[__destruct()]]></category>
		<category><![CDATA[__get()]]></category>
		<category><![CDATA[__set()]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=430</guid>
		<description><![CDATA[Programując obiektowo w PHP, możemy skorzystać z kilku specjalnych metod, zwanych magicznymi, które mogą zostać użyte wewnątrz klas. Dzięki nim uzyskamy wiele dodatkowych możliwości podczas korzystania z obiektów. W niniejszej, pierwszej części z serii artykułów opisującej te zagadnienia, przedstawię konstruktor, destruktor oraz metody __set(), __get()  i __call(). Konstruktor i destruktor Są to dwie podstawowe metody, których wywołanie następuje odpowiednio podczas tworzenia nowego obiektu oraz przy jego usuwaniu. Konstruktor służy do zainicjowania obiektu, przypisania właściwości oraz [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Programując obiektowo w PHP, możemy skorzystać z kilku specjalnych metod, zwanych magicznymi, które mogą zostać użyte wewnątrz klas. Dzięki nim uzyskamy wiele dodatkowych możliwości podczas korzystania z obiektów. W niniejszej, pierwszej części z serii artykułów opisującej te zagadnienia, przedstawię konstruktor, destruktor oraz metody <code>__set()</code>, <code>__get()</code>  i <code>__call()</code>.<span id="more-430"></span></p>
<h3>Konstruktor i destruktor</h3>
<p>Są to dwie podstawowe metody, których wywołanie następuje odpowiednio podczas tworzenia nowego obiektu oraz przy jego usuwaniu. Konstruktor służy do zainicjowania obiektu, przypisania właściwości oraz wykonania podstawowych operacji podczas jego tworzenia.</p>
<p>Destruktor jest wywoływany automatycznie w momencie usuwania obiektu. Bardzo ważne jest to, że samodzielne wywołanie tej metody nie usuwa obiektu. W przypadku takiego działania zostanie po prostu wykonany zdefiniowany w destruktorze kod, jednak obiekt będzie istniał dalej. Jeśli chcemy sami go usunąć , możemy skorzystać z jednej z następujących możliwości:</p>
<pre class="brush: php; light: true; title: ; notranslate">

unset($object);
$object = null;

</pre>
<p>Nie mamy obowiązku definiowania konstruktora i destruktora, domyślnie są one puste.</p>
<p>Na poniższym przykładzie przedstawiono działanie konstruktora i destruktora:</p>
<pre class="brush: php; title: ; notranslate">

class MyClass
{
   public $variable;
   public function __construct($variable)
   {
      $this-&gt;variable = $variable;
      echo &quot;Obiekt został utworzony&quot;;
   }

   public function __destruct()
   {
      echo &quot;Obiekt został zniszczony&quot;;
   }
}

$object = new MyClass(123);
$object-&gt;__destruct();
var_dump($object);

</pre>
<p>Wynik działania skryptu będzie następujący:</p>
<pre class="brush: php; light: true; title: ; notranslate">

Obiekt został utworzony
Obiekt został zniszczony
object(MyClass)#1 (1) {
   [&quot;variable&quot;]=&gt;
   int(123)
}
Obiekt został zniszczony

</pre>
<p>Jak  można zauważyć obiekt został utworzony, w wyniku czego nastąpiło wywołanie konstruktora, który przypisał odpowiednią właściwość. W kolejnym kroku wywołano destruktor, co jak widać w dalszej części nie usunęło obiektu, a jedynie wykonało jego kod (wyświetlenie komunikatu). Można to zaobserwować w wyniku funkcji <code>var_dump()</code>. Ostatecznie obiekt został usunięty w momencie zakończenia skryptu &#8211; destruktor został wywołany ponownie, tym razem automatycznie.</p>
<h3>Metody <code>__get()</code> oraz <code>__set()</code></h3>
<p>Są to metody wywoływane w momencie, gdy następuje próba dostępu do nieistniejącej właściwości obiektu. Metoda <code>__get()</code> zostanie wykonana, gdy będziemy pobierali taką właściwość. Posiada ona jeden parametr, do którego zostaje przypisana nazwa wywoływanej właściwości.</p>
<p>Analogicznie metoda <code>__set()</code> wywoła się, gdy będziemy chcieli ustawić nieistniejącą właściwość obiektu. Przyjmuje ona dwa parametry, kolejno: nazwa oraz wartość.</p>
<p>Należy pamiętać, że gdy nie zdefiniujemy powyższych metod, to w przypadku odczytu nieistniejącej właściwości otrzymamy <code>null</code>, natomiast gdy będziemy chcieli do takiej przypisać wartość, zostanie ona w tym momencie utworzona.</p>
<p>Można to zobaczyć analizując działanie następującego skryptu:</p>
<pre class="brush: php; title: ; notranslate">

class MyClass
{
   /* ... */
}

$object = new MyClass();
$object-&gt;undefinedVariable = 123;

var_dump($object);
var_dump($object-&gt;anotherUndefinedVariable);

</pre>
<p>Efekt jego działania będzie następujący:</p>
<pre class="brush: php; light: true; title: ; notranslate">
object(MyClass)#1 (1) {
   [&quot;undefinedVariable&quot;]=&gt;
   int(123)
}
NULL

</pre>
<p>Na poniższym przykładzie przedstawiono zasadę działania metod <code>__get()</code> oraz <code>__set()</code>:</p>
<pre class="brush: php; title: ; notranslate">

class MyClass
{
   public function __construct()
   {
      echo $this-&gt;undefinedVariable;
   }

   public function __get($name)
   {
      echo &quot;Obiekt nie posiada właściwości $name&quot;;
   }

   public function __set($name,  $value)
   {
      echo &quot;Obiekt nie posiada właściwości $name, nie można więc przypisać 
wartości $value&quot;;
   }
}

$object = new MyClass();
$object-&gt;anotherUndefinedVariable = 678;

</pre>
<p>Wynikiem działania skryptu będzie:</p>
<pre class="brush: php; light: true; title: ; notranslate">

Obiekt nie posiada właściwości undefinedVariable
Obiekt nie posiada właściwości anotherUndefinedVariable, nie można więc 
przypisać wartości 678

</pre>
<p>W momencie tworzenia obiektu poprzez konstruktor nastąpiła próba odczytania zmiennej  <code>undefinedVariable</code>, co spowodowało wywołanie metody <code>__get()</code>. Gdy wykonano przypisanie do nieistniejącej właściwości <code>anotherUndefinedVariable</code>, aktywowana została metoda <code>__set()</code>;</p>
<h3>Metoda <code>__call()</code></h3>
<p>Metoda ta działa analogicznie do poprzednio omówionych, dotyczy jednak metod obiektu. W przypadku, gdy nie zdefiniujemy <code>__cal()</code> i wywołujemy nieistniejącą metodę, zostanie wyświetlony odpowiedni błąd, a działanie skryptu zatrzymane:</p>
<pre class="brush: php; light: true; title: ; notranslate">

Fatal error:  Call to undefined method MyClass::undefinedMethod() 
in /sciezka/do/pliku/skrypt.php on line 13

</pre>
<p>Po zdefiniowaniu w klasie metody <code>__call()</code>, w takim przypadku błąd nie wystąpi i zostanie wykonany zawarty w niej kod. Przyjmuje ona dwa parametry: nazwę wywołanej metody oraz tablicę zawierającą przekazane zmienne. Przykładowe zastosowanie może być nastepujące:</p>
<pre class="brush: php; title: ; notranslate">

class MyClass
{
   public function __call($name, $params)
   {
      echo &quot;Metoda $name nie istnieje. Przekazane parametry:&quot;;
      print_r($params);
   }
}

$object = new MyClass();
$object-&gt;undefinedMethod(12, &quot;a&quot;, &quot;b&quot;);

</pre>
<p>Wynik działania powyższego skryptu będzie następujący:</p>
<pre class="brush: php; light: true; title: ; notranslate">

Metoda undefinedMethod nie istnieje. Przekazane parametry:

Array
(
   [0] =&gt; 12
   [1] =&gt; a
   [2] =&gt; b
}

</pre>
<h3>Ciąg dalszy nastąpi&#8230;</h3>
]]></content:encoded>
			<wfw:commentRss>https://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-pierwsza.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rozpoznawanie typów plików w PHP</title>
		<link>https://blog.visionsoftware.pl/programowanie-php/rozpoznawanie-typow-plikow-w-php.html</link>
		<comments>https://blog.visionsoftware.pl/programowanie-php/rozpoznawanie-typow-plikow-w-php.html#comments</comments>
		<pubDate>Fri, 30 Sep 2011 21:25:28 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[fileinfo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[plik]]></category>
		<category><![CDATA[rozszerzenie]]></category>
		<category><![CDATA[walidacja]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=368</guid>
		<description><![CDATA[Gdy umożliwiamy na naszej stronie internetowej lub w systemie wgrywanie plików, powinniśmy sprawdzać ich typ. Dzięki temu dopuścimy tylko wybrane przez nas rodzaje, np. pliki graficzne. Możemy sobie jednak nie zdawać sprawy, że podstawowe, najczęściej stosowane możliwości sprawdzania typu są bardzo zawodne i umożliwiają wgranie na serwer niepożądanych danych. Sprawdzanie rozszerzenia pliku Najprostszym możliwym testem dla pliku jest sprawdzenie jego rozszerzenia. Oczywiście w ten sposób jest on wykonywany niezwykle rzadko. Wystarczy, że rozdzielimy nazwę względem [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Gdy umożliwiamy na naszej stronie internetowej lub w systemie wgrywanie plików, powinniśmy sprawdzać ich typ. Dzięki temu dopuścimy tylko wybrane przez nas rodzaje, np. pliki graficzne. Możemy sobie jednak nie zdawać sprawy, że podstawowe, najczęściej stosowane możliwości sprawdzania typu są bardzo zawodne i umożliwiają wgranie na serwer niepożądanych danych.<span id="more-368"></span></p>
<h3>Sprawdzanie rozszerzenia pliku</h3>
<p>Najprostszym możliwym testem dla pliku jest sprawdzenie jego rozszerzenia. Oczywiście w ten sposób jest on wykonywany niezwykle rzadko. Wystarczy, że rozdzielimy nazwę względem kropki i sprawdzimy ostatnią z części. Jest to oczywiście sposób bardzo zawodny, gdyż ktoś może zmienić rozszerzenie przed wgraniem na serwer. Na przykład plik PHP może zostać ukryty pod nazwą image.jpg. Wykorzystując następnie luki w naszym systemie, istnieje możliwość wykonania takiego kodu.</p>
<h3>Sprawdzanie typu MIME w tablicy <code>$_FILES</code></h3>
<p>Znacznie częściej stosowanym sposobem na rozpoznawanie rodzaju pliku jest sprawdzenie typu MIME. Możemy to osiągnąć, analizując dane z formularza, konkretnie wartość <code>$_FILES['type']</code>.</p>
<p>Poniższy, bardzo uproszczony kod, wyświetla formularz HTML z jednym polem umożliwiającym wczytanie pliku. Po jego wysłaniu wyświetlone zostaną szczegółowe dane o pliku z tablicy <code>$_FILES</code>.</p>
<pre class="brush: php; title: ; notranslate">
&lt;html&gt;
    &lt;body&gt;
        &lt;form action=&quot;mime_test.php&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&gt;
        	&lt;label for=&quot;file&quot;&gt;Filename:&lt;/label&gt;
        	&lt;input type=&quot;file&quot; name=&quot;file&quot; id=&quot;file&quot; /&gt;
        	&lt;input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;Submit&quot; /&gt;
        &lt;/form&gt;
    &lt;/body&gt;
&lt;/html&gt; 

&lt;?php 
if($_POST){
    print_r($_FILES);    
}
?&gt;
</pre>
<p>Wczytanie przykładowego zdjęcia zwróci w polu type wartość image/jpeg. Co się jednak stanie, gdy przez formularz wczytamy plik PHP ze zmienioną nazwą na jpg? Wynik może być dla niektórych zaskakujący – powyższy kod wyświetli informację, że wgrany został plik graficzny. </p>
<p>Dlaczego tak się dzieje? Otóż dane na temat pliku przekazywane są przez przeglądarkę, a większość z nich (wszystkie?)  określa typ MIME po rozszerzeniu pliku. Tak więc wracamy do punktu wyjścia.</p>
<h3>Wykrywanie pliku graficznego</h3>
<p>Zawodność powyższych metod możemy naprawić jednym prostym rozwiązaniem. Wystarczy, że skorzystamy z funkcji  <code>getimagesize()</code> z biblioteki GD, która zwraca wymiary pliku graficznego. Przykładowe wywołanie wraz z efektem może wyglądać nastepująco:</p>
<pre class="brush: php; light: true; title: ; notranslate">
print_r(getimagesize('image.jpg'));

Array
(
    [0] =&gt; 979
    [1] =&gt; 734
    [2] =&gt; 2
    [3] =&gt; width=&quot;979&quot; height=&quot;734&quot;
    [bits] =&gt; 8
    [channels] =&gt; 3
    [mime] =&gt; image/jpeg
)
</pre>
<p>Otrzymujemy więc dane na temat wymiarów grafiki, palety kolorów, liczby kanałów oraz typu MIME. Jeśli spróbujemy naszego oszustwa ze zmianą rozszerzenia i użyjemy powyższej funkcji do sprawdzenia spreparowanego pliku PHP, funkcja zwróci wartość <code>false</code>. </p>
<pre class="brush: php; light: true; title: ; notranslate">
var_dump(getimagesize('phpcode.jpg'));
bool(false)
</pre>
<p>Dzięki temu możemy sprawdzić, czy wgrywany plik jest faktycznie obrazkiem. Co jednak zrobić, gdy chcemy testować inne typy?</p>
<h3>Sprawdzanie typu pliku po &#8222;magicznych bajtach&#8221;</h3>
<p>Każdy plik zaczyna się od charakterystycznych bajtów, które identyfikują jego typ. Dla kilku popularnych typów, wyglądają one następująco (w zapisie szesnastkowym):</p>
<pre class="brush: plain; light: true; title: ; notranslate">
GIF87a:  47 49 46 38 37 61 
GIF89a:  47 49 46 38 39 61 
JFIF, JPE, JPEG, JPG: FF D8 FF E0 xx xx 4A 46 49 46 00 
AVI: 52 49 46 46 xx xx xx xx 41 56 49 20 4C 49 53 54 
</pre>
<p>Wystarczy więc je wczytać i sprawdzić, aby określić rodzaj. Na poniższym przykładzie przedstawiono sprawdzenie, czy dany plik to gif.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
$file = fopen('image.gif', 'r');
$bytes = bin2hex(fread($file, 6));

if($bytes == '474946383761' || $bytes == '474946383961'){
    print 'To plik gif';
}
else{
    print 'To NIE JEST gif';
}

fclose($file);
?&gt;
</pre>
<p>Działanie kodu jest niezwykle proste. Wczytujemy pierwsze 6 bajtów z pliku, po czym konwertujemy je na wartości hexadecymalne. Następnie porównujemy z odpowiednim schematem, który dla GIF może być  <code>47 49 46 38 37 61</code> lub <code>47 49 46 38 39 61</code>.</p>
<p>Długa lista „magicznych bajtów” dla najróżniejszych typów plików jest dostępna <a href="http://www.garykessler.net/library/file_sigs.html" title="" target="_blank">tutaj</a>.</p>
<p>Możemy na jej podstawie stworzyć własną funkcję sprawdzającą. Oczywiście to także nie zabezpieczy nas w stu procentach. Możliwe jest bowiem stworzenie pliku z oszukanym nagłówkiem. Ten sposób, mimo że dość karkołomny, jest jednak znacznie lepszy od poprzednich.</p>
<h3>Sprawdzanie typu przez Fileinfo</h3>
<p>Niedogodności poprzednio opisanego sposobu można zlikwidować, stosując wbudowane w PHP funkcje <code>Fileinfo</code>. Są one obecne od wersji 5.3.0 języka, dla wcześniejszych możemy skorzystać z PECL. Oczywiście podczas kompilacji PHP należy się upewnić, że dołączamy powyższą bibliotekę.</p>
<p>Poniższe wywołanie pokazuje efekt sprawdzenia typu pliku jpg oraz PHP ze zmienionym rozszerzeniem.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php 
$file1 = 'image.jpg';
$file2 = 'phpcode.jpg';

$file_info = new finfo(FILEINFO_MIME);

print $file_info-&gt;file($file1, FILEINFO_MIME_TYPE); 
print $file_info-&gt;file($file2, FILEINFO_MIME_TYPE);
?&gt;
</pre>
<p>Wynik wywołania skryptu:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
image/jpeg
text/x-php
</pre>
<p>Wywołanie metody <code>file</code> posiada kilka innych wariantów, w zależności od drugiego parametru. Możemy między innymi sprawdzić kodowanie pliku oraz klika innych rzeczy.</p>
<p><em>Artykuł został oparty o tekst z bloga http://cakephp-php.blogspot.com.</em></p>
]]></content:encoded>
			<wfw:commentRss>https://blog.visionsoftware.pl/programowanie-php/rozpoznawanie-typow-plikow-w-php.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
