Készülj fel a PHP 7-re

Készülj fel a PHP 7-re

Készülj fel a PHP 7-re

2015 egy nagyszerű év volt a PHP számára. Tizenegy évvel az 5.0-ás kiadása után hamarosan egy új fő verzió érkezik. A PHP 7 kiadását az év végére datálták, mely számos új lehetőséget hordoz majd és jelentős teljesítménynövekedést hoz.

Tekintsük át, hogyan befolyásolja az új kiadás a jelenlegi PHP kódbázisodat! Milyen változások történtek? Mennyire biztonságos a frissítés? Ebben a cikkben megtalálod a válaszokat a kérdésekre és betekintést nyújtunk a PHP 7 újdonságaiba.

Kiváló teljesítmény

A teljesítmény javulása kétségtelenül az egyik legfontosabb fejlesztés, amiért érdemes lesz frissíteni a szervereket, amint az új stabil verzió megérkezik. A mag (core) refaktorálásának köszönhetően a PHP 7 olyan gyors – vagy még gyorsabb – lesz, mint a HHVM. A hivatalos teljesítmény tesztek (benchmark) lenyűgözőek: a legtöbb éles környezetben futó alkalmazás -, melyet PHP 5.6-ban írtak – legalább kétszer gyorsabb futási időt produkált.

A részletes teljesítménytesztek beszámolóját Rasmus Lerdorf előadásában itt is megtekintheted. (Használd a nyilakat a diák közötti navigáláshoz.)

Itt van néhány teszteredmény az említett tanulmányból:

Készülj fel a PHP 7-re

A PHP 7 több, mint kétszer több kérést képes másodpercenként kiszolgálni, mint elődjei. Ez gyakorlatilag 100% teljesítménynövekedést hoz Wordpress alapú weboldalak esetén.

Kompatibilitási buktatók

Vizsgáljunk meg néhány tényezőt, melyek az elkészült kódbázisod futását befolyásolhatják.

Elavult eszközök eltávolítása

Számos, korábban elavultnak jelölt eszközt véglegesen eltávolítottak. Azonban ezeket már jó ideje elavult technikáként ismerjük, így remélem, már nem használod őket! Ha mégis, akkor a következőek befolyásolják majd a programjaid futását.

Kidobásra kerültek az ASP-stílusú tag-ek (<%, <%=, %>) és a script tag is (<script language=”php”>). Bizonyosodj meg róla, hogy ezek helyett a javasolt <?php inicializáló jelet alkalmazod mindenhol.

Emellett számos funkció, mint például a split() is eltávolításra kerül a PHP 7-től kezdve.

Az ereg kiterjesztések (és minden ereg_* funkció) is a felejtés homályába vész. Ezeket cseréld PCRE funkciókra, melyek több tudással is rendelkeznek elődjénél.

A mysql (és minden mysql_* funkció) is megkapta az „elavult” megjelölést már a PHP 5.5 verziója óra. Helyette a mysqli osztályok kerülnek előtérbe.

Egységesített változókezelés

Az egységesített változókezelés célja, hogy megszűntessen számos inkonzisztenciát, melyek változó-változó kifejezések kiértékelésekor felléphettek. Tekintsük meg az alábbi kódrészletet:

PHP


<?php
class Person
	{
	public $name = 'Erika';
	public $job = 'Developer Advocate';
	}

$person = new Person();
$property = [ 'first' => 'name', 'second' => 'info' ];
echo "\nMy name is " . $person->$property['first'] . "\n\n";
?>

PHP 5 alatt a $person->$property['first'] kifejezés kirétkelése a következőt jelenti:

$person->{ $property->[’first’]}. Tulajdonképpen a $person->name tulajdonság meghívása történik, melynek eredménye „My name is Erika”. Azonban ez egy igen ritkán előforduló technika, amely azonban a megszokott kiértékelési sorrendtől eltérő, ami balról jobbra haladna.

PHP 7 verzió esetén balról jobbra történik a kiértékelés, azaz {$person->$property}[’name’] lesz a kiértékelése. Emiatt az előző kódrészlet nem fog megfelelően futni, hiszen a $property egy tömb, így nem lehet szöveges típussá alakítani.

Köszönhetően az új balról-jobbra kiértékelésnek, számos – korábban érvénytelenként kiértékelt – kifejezés mostantól kezdve futtathatóvá válik. Szemléltessük ezt egy példán keresztül. Adott a következő osztály:

PHP


<?php
class Person
	{
	public static $company = 'DigitalOcean';
	public function getFriends()
		{
		return [
			'erika' => function () {
				return 'Elephpants and Cats';
			},
			'sammy' => function () {
				return 'Sharks and Penguins';
			}
		];
		}

	public function getFriendsOf($someone)
		{
		return $this->getFriends()[$someone];
		}

	public static function getNewPerson()
		{
		return new Person();
		}
	}
?>

A PHP 7 segítségével írhatunk beágyazott asszociációkat és különböző kombinációkat alkothatunk az operátorokkal:

PHP


<?php
$person = new Person();
echo "\n" . $person->getFriends()['erika']() . "\n\n";
echo "\n" . $person->getFriendsOf('sammy')() . "\n\n";
?>

PHP 5 alatt ez fordítási hibát (parse error) eredményezne, PHP 7 alatt azonban futtathatóvá válik.

Hasonlóképp, a statikus hívások láncolása is elérhetővé válik:

PHP


<?php
echo "\n" . $person::getNewPerson()::$company . "\n\n";
?>

PHP 5 alatt ez a klasszikus T_PAAMAYIM_NEKUDOTAYIM szintaxis hibát idézné elő.

Kritikus hiba a többszörös „default” ágakon

Ez ismét egy igen ritka eset és többnyire inkább logikai hibára utal a kódbázisban. Nincs értelme egy switch vezérlési szerkezetben több default ág használatának, azonban mivel ez eddig nem dobott hibát vagy figyelmeztető üzenetet, ezért nehéz lehet egy ilyen hiba felderítése.

PHP 5 alatt csak az utolsó default ágra kerülne a vezérlés, azonban a PHP 7 mostantól kritikus hibát fog jelezni: Fatal Error: Switch statements may only contain one default clause.

Engine Exceptions

Az Engine Exceptions célja, hogy megkönnyítse az alkalmazások hibakezelését. A kritikus és helyreállítható kritikus hibákat kivételekre cserélték, lehetővé téve a megnevezett kivételek elkapását. Így lehetőségünk nyílik az ilyen hibák kezelésére, naplózására, megjelenítésére vagy helyreállítási lépések megtételére.

Az implementáció során törekedtek arra, hogy visszafelé kompatibilis megoldás születhessen, azonban van egy szélsőséges eset, mely a korábbi alkalmazásodat működésképtelenné teheti. Tekintsd meg az alábbi kódot:

PHP


<?php
set_error_handler(function ($code, $message) {
	echo "ERROR $code: " . $message . "\n\n";
});

function a(ArrayObject $b){
	return $b;
}

a("test");
echo "Hello World";
?>

A kód egy helyreállítható hibát generál, hiszen típushibát vétünk, amikor az a() funkciót szöveges paraméterrel hívjuk meg. PHP 5 esetén egy E_RECOVERABLE hibát dob, melyet elkaphattunk egy saját hibakezelővel és a következő kimenetet kaptuk:

PHP


ERROR 4096: Argument 1 passed to a() must be an instance of ArrayObject, string given, called in /data/Projects/php7dev/tests/test04.php on line 12 and defined(...)

Hello World

Vegyük észre, hogy a futtatás nem akadt meg, mert a hiba kezelve lett. PHP 7 esetén nem hibát, hanem kivételt fogunk kapni (TypeError Exception), így az általunk definiált hibakezelő nem kerül meghívásra és a kimenet is megváltozik:

PHP


Fatal error: Uncaught TypeError: Argument 1 passed to a() must be an instance of ArrayObject, string given, called in /vagrant/tests/test04.php on line 12 and defined in /vagrant/tests/test04.php:7
Stack trace:
#0 /vagrant/tests/test04.php(12): a('test')
#1 {main}
	thrown in /vagrant/tests/test04.php on line 7

A futtatás ezáltal megszakad, hiszen a hibát nem kezeltük le. A probléma megoldásaként használj try/catch blokkokat, hogy elkapd a nevezetes hibákat. Fontos, hogy a kivételek hierarchiájának változását figyelembe vedd. A hierarchiába be kellett épülni ez Engine Exception osztályoknak, így a hierarchia a következőképpen épül fel:

  • Throwable interfész
    • Exception, mely megvalósítja a Throwble interfészt
      • ErrorException, mely az Exception leszármazottja
      • RuntimeException, mely az Exception leszármazottja
    • Error, mely megvalósítja a Throwble interfészt
      • TypeError, mely az Error leszármazottja
      • ParseError, mely az Error leszármazottja
      • AssertionError, mely az Error leszármazottja

Alapvetően ez azt jelenti, hogy minden kivétel őse a Throwable interfész lett a korább Exception osztály helyett. Ez nem befolyásolja jelentősen a korábbi osztályaidat, csupán érdemes észben tartani az új PHP 7 alkalmazások kivételkezelésekor.

Új nyelvi funkciók

Most pedig következzen az izgalmas rész! Tekintsük át a legfontosabb új lehetőségeket, melyek elérhetővé válnak, amint frissíted szervered PHP 7-re.

Új operátorok

A PHP 7 új, nagyszerű operátorokkal érkezik. A kombinált összehasonlítás (spaceship) és nullával összehasonlító operátor (null coalescele).

A kombinált összehasonlítás operátor ( <=> ) célja, hogy egyszerűsítse az összehasonlító kódrészleteket. Tekintsük meg az alábbi példát:

PHP


$a <=> $b

A kifejezés eredménye -1 lesz, ha $a kisebb, mint $b, 0, ha egyenlőek és 1, ha $a nagyobb $b-nél.

Tulajdonképpen ez az alábbi kódrészlet rövidítése:

PHP


($a < $b) ? -1 : (($a > $b) ? 1 : 0)

A nullával összehasonlító operátor szintén rövidítő szerepet tölt be, mely egy igen gyakori problémát old meg. Egy feltétel segítségével vizsgálnunk kell, hogy egy adott változó létezik-e, mielőtt felhasználnánk az értékét egy másik kifejezésben:

PHP


$a = isset($b) ? $b : "default";

PHP 7 esetén használhatjuk a nullával összehasonlító operátort:

PHP


$a = $b ?? "default";

Skaláris típuskényszerítés

Az egyik leginkább várt újdonság a skaláris típuskényszerítés, mely lehetővé teszi, hogy integer, float, boolean és string típusú változókat kérjünk be a funkciók és metódusok fejlécében. Alapértelmezetten a kényszerítés nem szigorú, azaz integer paraméter kérésekor beérkező float változó esetén nem dob hibát, sem figyelmeztetést – egyszerűen csak átalakítja.

Azonban lehetőségünk lesz a szigorú (strict) mód aktiválására is, mely nem megfelelő típusú argumentum esetén hibát dob. Íme egy újabb kód:

PHP


<?php
function double(int $value)
	{
	return 2 * $value;
	}

$a = double("5");
var_dump($a);
?>

Ez a kód nem fog semmilyen hibaüzenetet adni, mert nem alkalmazzuk a szigorú módot. Az egyetlen dolog, ami a háttérben történni fog, az egy típus átalakítás, mely az „5” szövegből egy egész számot alkot majd és átadja a „double” függvénynek.

Amennyiben biztosítani akarod, hogy a megfelelő argumentumú paramétereket kapd meg, engedélyezheted a szigorú módot a megfelelő direktíva meghívásával a szkripted első sorában.

PHP


<?php
declare(strict_types = 1);
function double(int $value)
	{
	return 2 * $value;
	}

$a = double("5");
var_dump($a);
?>

Ebben az esetben már „Fatal Error: Uncaught TypeError: Argument 1 passed to double() must be of the type Integer, string given” hibaüzenettel fogunk találkozni.

Visszatérési érték előrejelzés

Egy újabb fontos eszközt mutatok be, mely a PHP 7-tel érkezik. Ez nem más, mint a visszatérési típus előrejelzés, mely – a skaláris típusok kényszerítéséhez hasonlóan – működhet szigorú vagy nem-szigorú módban.

PHP


<?php
function a() : bool
	{
	return 1;
	}

var_dump(a());
?>

Ez a kód hiba és figyelmeztetés nélkül fut le, ha a szigorú mód nincs engedélyezve, az 1-et -, mint egész számot - automatikusan logikai változóvá alakítjuk át. Szigorú módban a következő hibaüzenetet kapjuk:

PHP


Fatal error: Uncaught TypeError: Return value of a() must be of the type boolean, integer returned

Ismételten, ezek a hibák valójában kivételek, melyeket el tudunk kapni és kezelhetünk try/catch blokkok használatával. Emellett fontos megemlítenem, hogy bármilyen érvényes típust kérhetünk és adhatunk vissza, nem csak skaláris típusokat.

Mi van még hátra? / Mi jöhet még?

A PHP 7 idővonala szerint október közepén érkezik az első stabil kiadás. A béta verzió azonban már elérhető a lelkes tesztelők számára. Tekintsd meg a hivatalos RFC-t a további újdonságok és információk tekintetében.

Megjegyzés: a végső kiadás megjelenéséig még további változások is történhetnek, ezért kérlek, éles környezetben még ne használd a PHP 7-et! Azonban rendelkezésedre áll egy Vagrant virtuális gép, melyet Rasmus Lerforf készített és osztott meg velünk, hogy a jelenlegi kódjaidat letesztelhesd PHP 7 környezetben is. Bíztatlak, hogy teszteld le alkalmazásaidat és jelentsd, ha bármilyen problémába ütközöl.

Leírásaink azon kezdő és haladó programozóknak nyújtanak segítséget, akik már minimális szinten foglalkoztak weboldalkészítéssel. Ha szeretnél jobban elmélyülni a témában, vagy elsajátítani alapokat, még tovább fejlődni, akkor nézz körbe tanfolyam kínálatunkban, ahol a kezdőtől a profi szintig nyújtunk képzéseket a számodra.

Oszd meg barátaiddal is!

Facebook Twitter Linkedin

Elérhetőségeink

  • Címünk: 1139 Budapest, Frangepán utca 3. (1. emelet)

  • Ügyfélfogadás, beiratkozás: Hétfőtől - péntekig: 09:00-17:00

  • Telefonszámunk: 06 70 604 2060, vagy 06 1 4500 110

  • E-mail címünk:

Közösségünk