<?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="http://blog.visionsoftware.pl/kategoria/programowanie-php/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>Method chaining w PHP</title>
		<link>http://blog.visionsoftware.pl/programowanie-php/method-chaining-w-php.html</link>
		<comments>http://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>http://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>http://blog.visionsoftware.pl/programowanie-php/php-5-4-3-i-php-5-3-13-wydane-z-problemami.html</link>
		<comments>http://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>http://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>http://blog.visionsoftware.pl/programowanie-php/wydano-php-5-4-1-i-5-3-11.html</link>
		<comments>http://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>http://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>http://blog.visionsoftware.pl/programowanie-php/podpowiadanie-typow-w-php.html</link>
		<comments>http://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>http://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>http://blog.visionsoftware.pl/programowanie-php/php-5-4-w-wersji-finalnej-wydane.html</link>
		<comments>http://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>http://blog.visionsoftware.pl/programowanie-php/php-5-4-w-wersji-finalnej-wydane.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Metody magiczne w PHP &#8211; część trzecia i ostatnia</title>
		<link>http://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-trzecia-i-ostatnia.html</link>
		<comments>http://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-trzecia-i-ostatnia.html#comments</comments>
		<pubDate>Tue, 28 Feb 2012 21:52:04 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[metody magiczne]]></category>
		<category><![CDATA[__callStatic()]]></category>
		<category><![CDATA[__invoke()]]></category>
		<category><![CDATA[__isset()]]></category>
		<category><![CDATA[__set_state()]]></category>
		<category><![CDATA[__unset()]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=504</guid>
		<description><![CDATA[Nadszedł czas na ostatnią część cyklu opisującego metody magiczne w PHP. W części pierwszej oraz drugiej omówiłem wiele z nich: konstruktor i destruktor, settery, gettery, metody zwiększające możliwości serializacji obiektów oraz klonowania. W niniejszym tekście przedstawię pozostałe metody magiczne: __callStatic(), __isset(), __unset(), __invoke() oraz __set_state(). Metoda __callStatic() Metoda ta pojawiła się stosunkowo niedawno, bo dopiero w PHP 5.3. Jest bardzo podobna do omawianej w poprzedniej części zestawienia metody __call(). Tak jak ona jest używania w [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Nadszedł czas na ostatnią część cyklu opisującego metody magiczne w PHP. W części <a href="http://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-pierwsza.html" title="Metody magiczne w PHP">pierwszej</a> oraz <a href="http://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-druga.html" title="Metody magiczne w PHP">drugiej</a> omówiłem wiele z nich: konstruktor i destruktor, settery, gettery, metody zwiększające możliwości serializacji obiektów oraz klonowania. W niniejszym tekście przedstawię pozostałe metody magiczne: <code>__callStatic()</code>, <code>__isset()</code>, <code>__unset()</code>, <code>__invoke()</code> oraz <code>__set_state()</code>.<span id="more-504"></span></p>
<h3>Metoda <code>__callStatic()</code></h3>
<p>Metoda ta pojawiła się stosunkowo niedawno, bo dopiero w PHP 5.3. Jest bardzo podobna do omawianej w poprzedniej części zestawienia metody <code>__call()</code>. Tak jak ona jest używania w momencie wywołania nieistniejącej metody, jednak tylko w przypadku, gdy nastąpiło to w sposób statyczny (tak też musi być sama zdefiniowana). Jako parametry <code>__callStatic()</code> przyjmuje kolejno nazwę wywołanej metody oraz tablicę zawierającą przekazane do niej parametry. Na poniższym przykładzie widać porównanie obu metod:</p>
<pre class="brush: php; title: ; notranslate">
class TestCall
{
	public function __call($nazwa, $argumenty)
	{
		echo &quot;Wywołano metodę $nazwa z parametrami: &quot; . implode(',', $argumenty) . PHP_EOL;
	}

	public static function __callStatic($nazwa, $argumenty)
	{
		echo &quot;Wywołano statycznie metodę $nazwa z parametrami: &quot; . implode(',', $argumenty) . PHP_EOL;
	}
}
$obj = new TestCall();
$obj-&gt;nieistniejacaMetoda('normalne wywołanie');
TestCall::nieistniejacaMetoda('statyczne wywołanie');
</pre>
<p>Wynik działania powyższego skryptu będzie następujący:</p>
<pre class="brush: xml; light: true; title: ; notranslate">
Wywołano metodę nieistniejacaMetoda z parametrami: normalne wywołanie 
Wywołano statycznie metodę nieistniejacaMetoda z parametrami: statyczne wywołanie 
</pre>
<h3>Metody <code>__isset()</code> oraz <code>__unset()</code></h3>
<p>Pierwsza jest wywoływana w momencie, gdy pojawia się próba dostępu do nieistniejącej właściwości obiektu poprzez funkcję <code>isset()</code> lub <code>empty()</code>. Metoda <code>__unset()</code> jest natomiast wywoływana podczas  wykonywania funkcji <code>unset()</code> na nieistniejącej właściwości. Obie przyjmują jako parametr nazwę wywołanej właściwości. Poniższy przykład obrazuje sposób działania opisanych metod:</p>
<pre class="brush: php; title: ; notranslate">
class TestowaKlasa
{
   public function __unset($nazwa)
   {
      echo &quot;Nie można usunąć '$nazwa', zmienna nie isnieje!&quot; . PHP_EOL;
   }

   public function __isset($nazwa){
      echo &quot;Właściwość '$nazwa' nie istnieje!&quot; . PHP_EOL;
   }
}

$obj = new TestowaKlasa();

unset($obj-&gt;nieistniejacaWlasciwosc);
isset($obj-&gt;nieistniejacaWlasciwosc);
</pre>
<p>Efekt działania będzie następujący:</p>
<pre class="brush: xml; light: true; title: ; notranslate">
Nie można usunąć 'nieistniejacaWlasciwosc', zmienna nie isnieje!
Właściwość 'nieistniejacaWlasciwosc' nie istnieje!
</pre>
<h3>Metoda <code>__invoke()</code></h3>
<p>Została wprowadzona w PHP 5.3 i jest wywołana w momencie, gdy następuje próba użycia obiektu w sposób przeznaczony dla funkcji. Poszczególne parametry odpowiadają tym użytym w wywołaniu obiektu. Warto pamiętać, że gdy klasa posiada zdefiniowaną metodę <code>__invoke()</code>, zastosowanie na jej obiekcie funkcji <code>is_callable()</code> zwróci w rezultacie <code>true</code>.</p>
<pre class="brush: php; title: ; notranslate">
class MojaKlasa 
{
   public function __invoke($parametr1, $parametr2)
   {
      var_dump($parametr1, $parametr2);		
   }	
}

$obj = new MojaKlasa();
$obj('abc', 123);
var_dump(is_callable($obj));
</pre>
<p>Wynik działania powyższego skryptu będzie następujący:</p>
<pre class="brush: xml; light: true; title: ; notranslate">
string(3) &quot;abc&quot;
int(123)
bool(true)
</pre>
<h3>Metoda <code>__set_state()</code></h3>
<p>Jest to metoda statyczna, która jest wywoływana w momencie użycia na klasie funkcji <code>var_export()</code>. Przyjmuje jeden parametr, zawierający eksportowane właściwości w formacie: <code>array('wlasciwosc1' => wartosc, 'wlasciwosc2' => wartosc, …)</code>. Obrazuje to przykład zaczerpnięty z dokumentacji:</p>
<pre class="brush: php; title: ; notranslate">
class MojaKlasa
{
    public $w1;
    public $w2;

    public static function __set_state($tab)
    {
        $obj = new MojaKlasa();
        $obj-&gt;w1 = $tab['w1'];
        $obj-&gt;w2 = $tab['w2'];
        return $obj;
    }
}

$obj = new MojaKlasa();
$obj-&gt;w1 = 123;
$obj-&gt;w2 = 'abc';

eval('$b = ' . var_export($obj, true) . ';'); 
var_dump($b);
</pre>
<pre class="brush: xml; light: true; title: ; notranslate">
object(MojaKlasa)#2 (2) {
  [&quot;w1&quot;]=&gt;
  int(123)
  [&quot;w2&quot;]=&gt;
  string(3) &quot;abc&quot;
}
</pre>
<h3>Podsumowanie</h3>
<p>To była ostatnia część z cyklu &#8222;Metody magiczne w PHP&#8221;. W poszczególnych artykułach omówiłem wszystkie, jakie występują w PHP 5.3. Mam nadzieję, że wyjaśniły one mechanizmy, które mogą być bardzo przydatne w programowaniu obiektowym.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visionsoftware.pl/programowanie-php/metody-magiczne-w-php-czesc-trzecia-i-ostatnia.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Jak sprawdzić i porównać wersje PHP?</title>
		<link>http://blog.visionsoftware.pl/programowanie-php/jak-sprawdzic-i-porownac-wersje-php.html</link>
		<comments>http://blog.visionsoftware.pl/programowanie-php/jak-sprawdzic-i-porownac-wersje-php.html#comments</comments>
		<pubDate>Tue, 10 Jan 2012 22:00:21 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpversion()]]></category>
		<category><![CDATA[PHP_VERSION]]></category>
		<category><![CDATA[version_compare()]]></category>
		<category><![CDATA[wersje PHP]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=474</guid>
		<description><![CDATA[Podczas pisania kodu PHP możemy zastosować elementy języka, które zostały wprowadzone w konkretnej wersji. Przez to, nasza aplikacja może nie działać w pełni poprawnie lub nawet w ogóle na serwerze ze starszą wersją PHP. W jaki sposób sprawdzić, czy środowisko jest odpowiednie dla naszego skryptu? Opisane poniżej metody są często stosowane podczas instalacji popularnych systemów CMS, forum itd. Podczas tego procesu sprawdzana jest wersja PHP i w przypadku wykrycia zbyt starej, proces  jest przerywany. Warto [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Podczas pisania kodu PHP możemy zastosować elementy języka, które zostały wprowadzone w konkretnej wersji. Przez to, nasza aplikacja może nie działać w pełni poprawnie lub nawet w ogóle na serwerze ze starszą wersją PHP. W jaki sposób sprawdzić, czy środowisko jest odpowiednie dla naszego skryptu?<span id="more-474"></span></p>
<p>Opisane poniżej metody są często stosowane podczas instalacji popularnych systemów CMS, forum itd. Podczas tego procesu sprawdzana jest wersja PHP i w przypadku wykrycia zbyt starej, proces  jest przerywany. Warto w ten sposób zabezpieczyć własne skrypty zwłaszcza, gdy nie oferują one pełnej zgodności wstecz i są rozpowszechniane publicznie.</p>
<h3>Metody standardowe</h3>
<p>Najprostszym sposobem na sprawdzenie wersji PHP jest wywołanie funkcji <code>phpinfo()</code>. Jej wynikiem jest jednak ogromna liczba danych dotyczących konfiguracji całego serwera. Jeśli natomiast mamy dostęp do wywołania poleceń shell, to możemy skorzystać z jednej z dwóch poniższych możliwości:</p>
<pre class="brush: php; light: true; title: ; notranslate">
php -v
php -–version
</pre>
<p>Oczywiście nie jest to dobre rozwianie, gdyż nie zawsze jest taka możliwość. Po pierwsze musimy mieć dostęp do funkcji <code>shell_exec()</code> lub <code>exec()</code> a z tym może być kłopot. Po drugie do sprawdzania wersji PHP przyda się bardziej wyrafinowana metoda. Możemy to zrealizować na dwa sposoby: za pośrednictwem odpowiedniej funkcji oraz predefiniowanych stałych.</p>
<h3>Funkcja <code>phpversion()</code></h3>
<p>Zwraca ona po prostu dostępną na serwerze wersję PHP. W przypadku podania jako parametr wywołania nazwy konkretnego rozszerzenia, efektem wywołania będzie jego &#8222;aktualny numerek&#8221;. Może to wyglądać następująco:</p>
<pre class="brush: php; title: ; notranslate">
echo &quot;Wersja PHP: &quot;.phpversion();
echo &quot;Wersja PDO MySQL: &quot;.phpversion('pdo_mysql');
</pre>
<p>Efektem działania skryptu może być:</p>
<pre class="brush: php; light: true; title: ; notranslate">
Wersja PHP: 5.3.4
Wersja PDO MySQL: 1.0.2
</pre>
<h3>Stałe PHP_VERSION_*</h3>
<p>Innym sposobem na określenie wersji PHP jest skorzystanie ze zmiennych predefiniowanych. Jest ich kilka, wszystkie poza pierwszą dostępne są od PHP 5.2.7 wzwyż:</p>
<ul>
<li><code>PHP_VERSION</code> &#8211; (string) bieżąca wersja PHP przedstawiona w formacie GłównaWersja.MniejszaWersja.Wydanie[extra], np. 5.2.0[RC2]</li>
<li><code>PHP_MAJOR_VERSION</code> &#8211; (integer) określa &#8222;główną wersję&#8221; (pierwsza liczba)</li>
<li><code>PHP_MINOR_VERSION</code> &#8211; (integer) określa &#8222;mniejszą wersję&#8221; (druga liczba)</li>
<li><code>PHP_RELEASE_VERSION</code> &#8211; (integer) określa wydanie (trzecia liczba)</li>
<li><code>PHP_VERSION_ID</code> &#8211; (integer) pełna wersja przedstawiana jako liczba, przydatna do porównywania, np. 50304 (czyli 5.3.4)</li>
<li><code>PHP_EXTRA_VERSION</code> &#8211; (string) dodatkowe określenie wydania np. dev lub RC1</li>
</ul>
<p>Wywołanie poszczególnych zmiennych może wyglądać następująco:</p>
<pre class="brush: php; title: ; notranslate">
echo &quot;Wersja PHP: &quot; . PHP_VERSION . &quot;&lt;br /&gt;&quot;;
echo &quot;- głowna wersja: &quot; . PHP_MAJOR_VERSION . &quot;&lt;br /&gt;&quot;;
echo &quot;- mniejsza wersja: &quot; . PHP_MINOR_VERSION . &quot;&lt;br /&gt;&quot;;
echo &quot;- wydanie: &quot; . PHP_RELEASE_VERSION . &quot;&lt;br /&gt;&quot;;
echo &quot;Wersja PHP jako liczba: &quot; . PHP_VERSION_ID . &quot;&lt;br /&gt;&quot;;
echo &quot;Określenie wersji: &quot; . PHP_EXTRA_VERSION . &quot;&lt;br /&gt;&quot;;
</pre>
<pre class="brush: php; light: true; title: ; notranslate">
Wersja PHP: 5.3.4
- główna wersja: 5
- mniejsza wersja: 3
- wydanie: 4
Wersja PHP jako liczba: 50304
Określenie wersji:
</pre>
<p>Jeśli korzystamy z wersji PHP starszej niż 5.2.7, a chcemy mieć dostępne wszystkie powyższe zmienne, możemy je sami zdefiniować (cytując dokumentację):</p>
<pre class="brush: php; title: ; notranslate">
if (!defined('PHP_VERSION_ID')) {
    $version = explode('.', PHP_VERSION);

    define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}

if (PHP_VERSION_ID &lt; 50207) {
    define('PHP_MAJOR_VERSION',   $version[0]);
    define('PHP_MINOR_VERSION',   $version[1]);
    define('PHP_RELEASE_VERSION', $version[2]);

    // itd.
}

</pre>
<h3>Porównywanie wersji PHP przy pomocy <code>version_compare()</code></h3>
<p>Oczywiście stosując przedstawione metody, możemy porównać wersję PHP tak, jak to zostało już pokazane w powyższym przykładzie przy pomocy instrukcji <code>if</code> oraz zmiennej  <code>PHP_VERSION_ID</code>. Możemy to także zrobić, korzystając ze specjalnie stworzonej w tym celu funkcji <code>version_compare()</code>.</p>
<p>Może ona działać na dwa sposoby. W obu przyjmuje jako dwa pierwsze parametry wersje PHP do porównania w formacie <code>X.X.X</code>. Gdy podamy tylko tyle, zwróci ona -1 w przypadku, gdy pierwsza podana wersja jest niższa od drugiej, 0 jeśli są takie same lub 1 gdy druga jest mniejsza.</p>
<p>Funkcja może także przyjąć trzeci, opcjonalny parametr, określający rodzaj porównania: <code><=</code></code>, <code>le</code>, <code>></code>, <code>gt</code>, <code>>=</code>, <code>ge</code>, <code>==</code>, <code>=</code>, <code>eq</code>, <code>!=</code>, <code><></code>, <code>ne</code>. W takim przypadku zwróci ona <code>true</code> gdy warunek jest spełniony lub, w przeciwnym wypadku, <code>false</code>.<br />
Sposób użycia został przedstawiony na poniższym przykładzie:</p>
<pre class="brush: php; title: ; notranslate">
if (version_compare(PHP_VERSION, '5.0.0') &gt;= 0) {
    echo 'Używasz PHP5. Twoja wersja to' . PHP_VERSION;
}

if (version_compare(PHP_VERSION, '5.3.8', '&lt;=')) {
    echo 'Twoja wersja PHP nie jest najnowsza! Używasz :' . PHP_VERSION;
}
</pre>
<p><em>Jeśli ostatni przykład jest nieaktualny, proszę zwrócić uwagę na datę powstania artykułu</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visionsoftware.pl/programowanie-php/jak-sprawdzic-i-porownac-wersje-php.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Odczyt danych GPS ze zdjęcia w PHP</title>
		<link>http://blog.visionsoftware.pl/programowanie-php/odczyt-danych-gps-ze-zdjecia-w-php.html</link>
		<comments>http://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>http://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>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>
		<item>
		<title>Wydano PHP 5.4 RC2</title>
		<link>http://blog.visionsoftware.pl/programowanie-php/wydano-php-5-4-rc2.html</link>
		<comments>http://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>http://blog.visionsoftware.pl/programowanie-php/wydano-php-5-4-rc2.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
