<?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; callable</title>
	<atom:link href="https://blog.visionsoftware.pl/tag/callable/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>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>
	</channel>
</rss>
