Tartalom
Bevezető
A PHP 2020. november 26-án adta ki legújabb főverzióját a PHP 8-at (8.0.0), valamint azóta 2021. január 7-én pedig a PHP 8.0.1-et is, ezért már itt az ideje, hogy itt az oldalon is foglalkozzunk vele. Ebben a rövidebb cikkben átnézzük a PHP 8 fontosabb újításait és változtatásait.
A PHP 8 újdonságai
A PHP 8 sok újdonsággal bővült, illetve sok mindent változtattak benne.
RFC-k
Az RFC (az angol Request For Comments rövidítése, magyarul: kéretik megkritizálni) egy olyan dokumentum, mely egy új Internet-szabvány beiktatásakor adnak közre. Az új szabvány első tervezete saját számmal kerül a nyilvánosság elé, egy adott időtartamon belül bárki hozzászólhat. Ezeket a hozzászólásokat rendszerezik, majd többszöri módosítás után a szabványtervezetet elfogadják, vagy eldobják. Forrás
A PHP esetében az RFC-k segítségével gyűjtik össze azokat a terveket, amik idővel a PHP nyelv szabványává válnak. Ezen az oldalon láthatjuk a jelenlegi RFC-ket, amik még szavazati fázisban, vagy megvitatás alatt, vagy piszkozatban, vagy elfogadott állapotban, vagy pedig megvalósított állapotban vannak.
Itt pedig érdekességképpen élőben követhetjük, hogy melyik RFC hány szavazattal rendelkezik, stb: php-rfc-watch.beberlei.de
A következő részben a teljesség igénye nélkül átnézünk néhány fontosabbat ezek közül.
Union types (RFC)
A union types (unió típusok) segítségével változóknak megadhatunk két, vagy többféle típust is, mint elfogadható típusok. Példák:
// Példa #1
class Number {
private int|float $number;
public function setNumber(int|float $number): void {
$this->number = $number;
}
public function getNumber(): int|float {
return $this->number;
}
}
// Példa #2
// phpdoc jelöléssel:
class Number {
/**
* @var int|float $number
*/
private $number;
/**
* @param int|float $number
*/
public function setNumber($number) {
$this->number = $number;
}
/**
* @return int|float
*/
public function getNumber() {
return $this->number;
}
}
Named arguments (RFC)
A named arguments (magyarosan: nevezett paraméterek) lehetővé teszik, hogy egy függvénynek a paramétereket a neveik alapján adhassuk meg, ne a pozícióik alapján. Ez a paramétereket sorrendfüggetlenné teszi, valamint lehetővé teszi az alapértelmezett/opcionális értékek kihagyhatóságát is. Példák:
// Példa #1:
// Hagyományos paraméterek használata:
array_fill(0, 100, 50);
// Named arguments használata:
array_fill(start_index: 0, num: 100, value: 50);
// A nevezett argumentumok átadásának sorrendje nem számít.
// A fenti példa ugyanabban a sorrendben adja át őket, mint amelyet a függvény aláírásában deklaráltunk,
// de bármilyen más sorrend is lehetséges:
array_fill(value: 50, num: 100, start_index: 0);
// Példa #2:
function foo(string $a, string $b, ?string $c = null, ?string $d = null)
{ /* … */ }
foo(
b: 'value b',
a: 'value a',
d: 'value d',
);
JIT (RFC)
A JIT (Just In Time compilation) egy futásidejű fordítási módszer, amely a bájtkód-fordított rendszerek teljesítményének növelésére szolgáló technika. A bájtkódot futási időben fordítja natív kódra. A PHP 8 esetében akár háromszoros teljesítménynövekedést is eredményezhet a tisztán matematikai számításokat végző részek futtatásakor, azonban más webes alkalmazásoknál hasonló teljesítményt produkál, mint elődje, a PHP 7.4.
Attributes (RFC)
Az attributes (attribútumok), más nyelvekben közismertebb nevén kommentárok, lehetőséget kínálnak a metaadatok osztályokhoz adására anélkül, hogy fel kellene dolgozni a docblock-okat. Az attribútumok lehetővé teszik a kód deklarációjába közvetlenül beágyazott konfigurációs irányelvek meghatározását.
Hasonló megoldások léteznek más programozási nyelvekben is: Annotation-ok a Java-ban, Attribute-ok a C #-ban, C ++-ban, Rust-ban, Hack-ban és Decorator-ok a Python-ban és Javascript-ben. PHP példa:
// PHP 7-ben:
class PostsController
{
/**
* @Route("/api/posts/{id}", methods={"GET"})
*/
public function get($id) { /* ... */ }
}
// PHP 8-ban:
class PostsController
{
#[Route("/api/posts/{id}", methods: ["GET"])]
public function get($id) { /* ... */ }
}
A PHPDoc kommentárok helyett mostantól strukturált metaadatokat használhatunk a PHP natív szintaxisával. Forrás
Constructor Property Promotion (RFC)
A Constructor Property Promotion, másnéven egyszerűsített konstruktor, leegyszerűsíti az objektumok létrehozásának menetét. Ahelyett, hogy külön meg kellene adni az osztálytulajdonságokat és a konstruktort, a PHP 8 már egybe kombinálja ezeket. Példák:
// Példa #1:
// Korábbi PHP-k esetén:
class Point {
public float $x;
public float $y;
public float $z;
public function __construct(
float $x = 0.0,
float $y = 0.0,
float $z = 0.0
) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
}
// PHP 8-ban ugyanez:
class Point {
public function __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
// Példa #2:
// Korábbi PHP-k esetén:
class Money
{
public Currency $currency;
public int $amount;
public function __construct(
Currency $currency,
int $amount,
) {
$this->currency = $currency;
$this->amount = $amount;
}
}
// PHP 8-ban:
class Money
{
public function __construct(
public Currency $currency,
public int $amount,
) {}
}
Match (RFC)
A match kifejezés tulajdonképpen a switch kifejezés okosabb változata: A match szerkezetnek lehet visszatérési értéke, nem igényel break kifejezéseket, egyesítheti a feltételeket, szigorú típus-összehasonlításokat alkalmaz, és nem végez semmilyen típus kényszerítést. Példák:
// Példa #1:
// PHP 7-ben:
switch (1) {
case 0:
$result = 'Foo';
break;
case 1:
$result = 'Bar';
break;
case 2:
$result = 'Baz';
break;
}
echo $result;
//> Bar
// PHP 8-ban
echo match (1) {
0 => 'Foo',
1 => 'Bar',
2 => 'Baz',
};
//> Bar
// Példa #2:
// PHP 7-ben:
switch ('foo') {
case 0:
$result = "Oh no!\n";
break;
case 'foo':
$result = "This is what I expected\n";
break;
}
echo $result;
//> Oh no!
// PHP 8-ban:
echo match ('foo') {
0 => "Oh no!\n",
'foo' => "This is what I expected\n",
};
//> This is what I expected
Ésszerűbb karakterlánc-szám összehasonlítás (RFC)
Az ésszerűbb karakterlánc-szám összehasonlítás (Saner string to number comparisons) kijavít egy régi PHP furcsaságot: a PHP korábbi verzióiban amikor a parancsfeldolgozó karakterláncokat és számokat hasonlított össze a "==" és más nem szigorú összehasonlító operátorok használatával, az úgy történt, hogy a karakterláncot először számmá alakította, és ezután egész számokként, vagy lebegőpontos számokként hasonlította össze. Ez sok esetben nem várt eredményt idézett elő, mint például ebben az esetben is: 0 == "foobar" , aminek az értéke igaz volt. Ez az RFC azt írja elő, hogy a nem szigorú összehasonlításokat hasznosabbá és kevésbé hibára hajlamossá tegye, azáltal, hogy számként történő összehasonlítást csak akkor végezzen, ha az összehasonlítandó karakterlánc valójában numerikus szám. Ellenkező esetben a számok kerüljenek karakterlánccá alakítva, majd egy karakterlánc összehasonlítást hajtson végre rajtuk. Példa:
// PHP korábbi változataiban:
0 == 'foobar' // true
// PHP 8-ban:
0 == 'foobar' // false
Összehasonlítás | Korábban | PHP 8-ban
----------------------------------------
0 == "0" | true | true
0 == "0.0" | true | true
0 == "foo" | true | false
0 == "" | true | false
42 == " 42" | true | true
42 == "42foo" | true | false
A nullsafe operátor (RFC)
A nullsafe operátor segítségével a null ellenőrzési feltételek helyett most már használható a híváslánc az új nullsafe operátorral. Ha a lánc egyik elemének értékelése sikertelen, akkor a teljes lánc végrehajtása megszakad, és a teljes lánc nullára értékelődik. Példa:
// PHP korábbi verzióiban:
$country = null;
if ($session !== null) {
$user = $session->user;
if ($user !== null) {
$address = $user->getAddress();
if ($address !== null) {
$country = $address->country;
}
}
}
// PHP 8-ban:
$country = $session?->user?->getAddress()?->country;
Throw kifejezés (RFC)
Ez az RFC megváltoztatja a korábbi throw utasítást (statement), amelyet kifejezéssé (expression) alakít, ami lehetővé teszi a kivételek új helyeken történő dobását, ami rugalmasabbá teszi a használatát. Példa:
// Korábbi PHP változatokban használható throw minta:
// függvény létrehozáűsa egy kivétellel
function checkNum($number) {
if($number>1) {
throw new Exception("Az értéknek 1-nek vagy akatta kell lennie");
}
return true;
}
// PHP 8-ban használható minták, amik ezelőtt nem voltak lehetségesek:
// Ez korábban nem volt lehetséges, mivel a (PHP 7.4-ben bevezetett) nyíl függvények csak egyetlen kifejezést fogadtak el, míg a throw korábban egy utasítás volt.
$callable = fn() => throw new Exception();
// $value is non-nullable.
$value = $nullableValue ?? throw new InvalidArgumentException();
// $value is truthy.
$value = $falsableValue ?: throw new InvalidArgumentException();
// $value is only set if the array is not empty.
$value = !empty($array)
? reset($array)
: throw new InvalidArgumentException();
$triggerError = fn () => throw new MyError();
Új str_starts_with() és str_ends_with() karakterlánc kereső függvények (RFC)
A karakterláncok kezdetének és végének ellenőrzése nagyon gyakori feladat, amelynek egyszerűnek kell lennie. Ennek a feladatnak a teljesítése nem könnyű, ezért sok keretrendszer választotta ennek beépítését. Több magas szintű programozási nyelvben is megvalósították ezt a funkciót, mint például a JavaScript, a Java, a Haskell és a Matlab. A karakterlánc kezdetének és végének ellenőrzése nem lehet olyan feladat, amely megköveteli egy PHP keretrendszer behúzását vagy egy potenciálisan nem optimális (vagy rosszabb esetben hibás) funkció kifejlesztését a programozási nyelvben.
Az str_starts_with() ellenőrzi, hogy egy karakterlánc egy másik karaktersorozattal kezdődik-e, és visszaadja a megfelelő logikai értéket (igaz/hamis)
Az str_ends_with() ellenőrzi, hogy egy karakterlánc egy másik karaktersorozattal végződik-e, és visszaadja a megfelelő logikai értéket (igaz/hamis)
str_starts_with('abcdefgh', 'abc'); // igaz
str_ends_with('abcdefgh', 'fgh'); // igaz
Elavult dolgok (Deprecated)
Itt kerülnek felsorolásra azok a dolgok, amik a PHP korábbi verzióiban még mindenféle hiba nélkül működtek, de a PHP 8-ban elavulttá lettek nyilvánítva. Az elavult (deprecated) dolgok általában még nem kerülnek kivezetésre az adott verzióból, tehát még nem dobnak végzetes hibákat (Fatal error) de már "Deprecated" típusú PHP notice-eket dobálnak, és majd egy jövőbeni PHP verzióban kerülnek végleges kivezetésre.
Reflection API ReflectionMethod osztály egyes metódusai
A PHP Reflection API ReflectionMethod osztályának néhány metódusa elavulttá vált (deprecated), ezért amik az alábbi metódusokat használják, notice-okat kapnak:
ReflectionParameter::getClass()
ReflectionParameter::isArray()
ReflectionParameter::isCallable()
Forrás: https://php.watch/versions/8.0/deprecated-reflectionparameter-methods
Ezt azért emeltem itt ki, mert például a phpMyAdmin 4.9.x verziója is ilyen notice-okat dobál PHP 8-on futtatva, tehát ez az ág még nem 100%-osan kompatibilis a PHP 8-al.
A phpMyAdmin által megjelenített hibaüzenet:
Deprecation Notice in ./libraries/classes/Di/ReflectorItem.php#82 Method ReflectionParameter::getClass() is deprecated
Egyéb változások
Itt kerülnek felsorolásra a fenti csoportokba nem sorolt változások, újdonságok.
Új alapértelmezett Error reporting szint
A PHP 8-ban megváltozott az alapértelmezett Error reporting szint. A korábban érvényben lévő alapértelmezett beállítás (error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED) helyett a PHP 8-ban az error_reporting = E_ALL beállítás lépett érvénybe. Forrás
// PHP 8 előtti verzióban az alapértelmezett error_reporting érték:
// php.ini beállítás:
// error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
// PHP script beállítás:
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
// A PHP 8-ban pedig:
// php.ini beállítás:
// error_reporting = E_ALL
// PHP script beállítás:
error_reporting(E_ALL);
Mindez azt eredményezi, hogy a PHP 8 alapértelmezetten minden olyan hibát megjelenít, amiket a PHP korábbi verziói figyelmen kívül hagytak. Ezért éles használat esetén célszerű kézzel beállítani a megfelelő értéket, amennyiben nem szeretnénk, ha a weboldalainkon minden apró hiba megjelenjen.
Végzetes hibák felfedése
A forráskódban az utasítások elé helyezett '@' operátorok a PHP 8-ban már nem nyomják el a végzetes hibákat, így azok felfedésre kerülnek, amik korábban nem voltak láthatók. Éles szerverkörnyezetek esetén gondoskodjunk róla, hogy a "display_errors=Off" beállítás legyen érvényben, hogy az elrejteni kívánt végzetes hibák továbbra is rejtve maradjanak.
PHP 8 telepítése és beállítása
A PHP 8 telepítéséről és beállításáról egy másik leírásban tájékozódhatunk:
Konklúzió
Ezek lennének a PHP 8 fontosabb változásai. Természetesen ezeknél még sokkal több újdonságot tartalmaz, ezeknek részletesebb megismeréséhez látogassunk el a lenti linkekre. Apránként bővítem még ezt a cikket, ahogy belebotlok újabb PHP 8-as érdekességekbe.
- A hozzászóláshoz regisztráció és bejelentkezés szükséges
- 456 megtekintés