PHP 8 forventes at blive frigivet i december 2020 og vil bringe os en hel masse kraftfulde funktioner og store forbedringer til sprog.

Mange RFC’er er allerede godkendt og implementeret, så det er tid for os at dykke ned i nogle af de mest spændende tilføjelser, der skal gøre PHP hurtigere og mere pålidelige.

Da PHP 8 stadig er under udvikling, kunne vi se flere ændringer før den endelige udgivelse. Vi vil holde styr på disse ændringer og opdatere dette indlæg regelmæssigt, så sørg for, at du ikke går glip af noget om PHP 8 og tjek dette indlæg igen fra tid til anden.

Så hvilke funktioner og forbedringer skal vi forvente med PHP 8? Hvad er den største ting, der følger med PHP 8, den næste større udgivelse af sproget?

Lad os dykke ned!

PHP JIT (Just in Time Compiler)

Den mest anerkendte funktion, der følger med PHP 8, er Just-in-time (JIT)  Compiler. Hvad handler JIT om?

RFC forslaget beskriver JIT som følgende:

”PHP JIT implementeres som en næsten uafhængig del af OPcache. Det kan være aktiveret / deaktiveret på PHP compile tid og ved kørselstidspunkt. Når det er aktiveret, gemmes oprindelig kode for PHP-filer i en yderligere region i den OPCache delte hukommelse og op_array → opcodes[]. Handler(e) holder pegepunkter til indgangspunkterne for JIT-ed-kode. ”

Så hvordan kom vi til JIT, og hvad er forskellen mellem JIT vs OPcache?

For bedre at forstå, hvad JIT er til PHP, så lad os se hurtigt på, hvordan PHP kører fra kildekoden til det endelige resultat.

PHP-udførelsen er en 4-trins proces:

Det følgende billede viser en visuel repræsentation af den grundlæggende PHP-eksekveringsproces.

Grundlæggende PHP-eksekveringsproces

Grundlæggende PHP-eksekveringsproces

Så hvordan gør OPcache PHP hurtigere? Og hvilke ændringer i udførelsesprocessen med JIT?

OPcache extension

PHP er et tolket sprog. Dette betyder, at når et PHP-script kører, tolker, kompilerer og udfører tolken koden igen og igen på hver anmodning. Dette kan resultere i spild af CPU-ressourcer og ekstra tid.

Det er her en OPcache extension kommer i spil:

“OPcache forbedrer PHP-ydeevne ved at gemme forudkompileret script-bytecode i delt hukommelse og dermed fjerne behovet for PHP at indlæse og analysere scripts på hver anmodning.”

Når OPcache er aktiveret, gennemgår PHP-tolken den 4-trins proces, der er nævnt ovenfor kun første gang scriptet kører. Da PHP-bytekoder gemmes i delt hukommelse, er de straks tilgængelige som mellemliggende repræsentation på lavt niveau og kan udføres med det samme på Zend VM.

PHP eksekveringsproces med OPcache aktiveret

PHP eksekveringsproces med OPcache aktiveret

Fra PHP 5.5 er en Zend OPcache extension tilgængelig som standard, og du kan kontrollere, om du har den korrekt konfigureret ved blot at kalde phpinfo() fra et script på din server eller tjekke din php.ini-fil (se OPcache-konfigurationsindstillinger).

Zend OPcache-sektion på en phpinfo-side

Zend OPcache-sektion på en phpinfo-side

Preloading

OPcache er for nylig blevet forbedret med implementeringen af preloading, en ny OPcache-funktion tilføjet med PHP 7.4. Forudindlæsning giver en måde at gemme et specificeret sæt scripts i OPcache-hukommelse “før en applikationskode køres”, men det medfører ikke konkrete ydelse-forbedringer for typiske webbaserede applikationer.

Du kan læse mere om preloading i vores introduktion til PHP 7.4.

Med JIT bevæger PHP sig et skridt fremad.

JIT — The Just in Time Compiler

Selv hvis opcodes er i form af mellemliggende repræsentation på lavt niveau, skal de stadig samles til maskinkode. JIT “introducerer ikke nogen yderligere IR (Mellem-repræsentation) -formular”, men bruger DynASM (Dynamic Assembler til kodegenereringsmotorer) til at generere native code direkte fra PHP-byte-kode.

Kort sagt, JIT oversætter de varme dele af den mellemliggende kode til maskinkode. Ved at omgå kompilering kunne det medføre betydelige forbedringer i performance og hukommelsesforbrug.

Zeev Surasky, medforfatter til PHP JIT-forslaget, viser, hvor meget beregninger der ville være hurtigere med JIT:

Men ville JIT effektivt forbedre WordPress performance?

JIT for Live Web Apps

I henhold til JIT RFC, skal implementeringen af ​​just in time compiler forbedre PHP performance. Men ville vi virkelig opleve sådanne forbedringer i virkelige apps som WordPress?

De tidlige test viser, at JIT ville få CPU-intensive arbejdsbelastninger til at køre betydeligt hurtigere, men RFC advarer:

”… ligesom de foregående forsøg – det ser ud til, at det i øjeblikket ikke markant forbedrer apps i det virkelige liv som WordPress (med opcache.jit=1235 326 req/sek vs 315 req/sek).

Det er planlagt at give en ekstra indsats, forbedre JIT til apps i det virkelige liv, ved hjælp af profilering og spekulative optimeringer.”

Når JIT er aktiveret, køres koden ikke af Zend VM, men af ​​selve CPU’en, og dette ville forbedre hastigheden i beregningen. Webapps som WordPress er også afhængige af andre faktorer som TTFB, databaseoptimering, HTTP-anmodninger osv.

Så når det kommer til WordPress og lignende apps, bør vi ikke forvente et stort løft i PHP-eksekveringshastighed. Ikke desto mindre kunne JIT give flere fordele for udviklere.

Ifølge Nikita Popov:

”Fordelene ved JIT-kompilatoren er nogenlunde (og som allerede beskrevet i RFC):

  • Betydelig bedre ydelse for numerisk kode.
  • Lidt bedre ydelse til “typisk” PHP-webapplikationskode.
  • Potentialet for at flytte mere kode fra C til PHP, fordi PHP nu vil være tilstrækkeligt hurtigt. ”

Så selvom JIT næppe vil bringe enorme forbedringer af WordPress-ydeevne, vil den opgradere PHP til det næste niveau, hvilket gør det til et sprog, hvor mange funktioner nu kunne skrives direkte på.

Ulempen er dog den større kompleksitet, der kan føre til stigende omkostninger til vedligeholdelse, stabilitet og debugging. Ifølge Dmitry Stogov:

”JIT er ekstremt simpelt, men alligevel øger det niveauet for hele PHP-kompleksiteten, risikoen for ny slags bugs og omkostningerne til udvikling og vedligeholdelse.”

Forslaget om at medtage JIT i PHP 8 blev vedtaget med 50 til 2 stemmer.

PHP 8 kommer senere i år. 🚀 Tjek vores dybe dyk ned i de nye funktioner!Click to Tweet

PHP 8 forbedringer og nye features

Bortset fra JIT kan vi forvente mange funktioner og forbedringer med PHP 8. Den følgende liste er vores håndplukkede valg af de kommende tilføjelser og ændringer, der skal gøre PHP mere pålidelig og effektiv.

Constructor Property Promotion

Som et resultat af en løbende diskussion om, hvordan man forbedrer object ergonomics i PHP, foreslår Constructor Property Promotion RFC en ny og mere kortfattet syntaks, der vil forenkle ejendomserklæringen, hvilket gør den kortere og mindre overflødig.

Dette forslag vedrører kun promoverede parametre, dvs. de metode-parametre, der er præfixet med offentlige, beskyttede og private synlige keywords.

I øjeblikket skal alle egenskaber gentages flere gange (mindst fire gange), før vi kan bruge dem med objekter. Overvej følgende eksempel fra RFC :

class Point {
    public int $x;
    public int $y;
    public int $z;

    public function __construct(
        int $x = 0,
        int $y = 0,
        int $z = 0,
    ) {
        $this->x = $x;
        $this->y = $y;
        $this->z = $z;
    }
}

Ifølge Nikita Popov, forfatteren af ​​RFC, er vi nødt til at skrive ejendomsnavnet mindst fire gange på tre forskellige steder: ejendomserklæringen, konstruktørparametrene og egenskabsopgaven. Denne syntaks er ikke særlig anvendelig, især i klasser med et godt antal egenskaber og mere beskrivende navne.

Denne RFC foreslår at flette konstruktøren og parameterdefinitionen. Så fra PHP 8 har vi en mere anvendelig måde at erklære parametre, og koden set ovenfor kan ændres som vist nedenfor:

class Point {
    public function __construct(
        public int $x = 0,
        public int $y = 0,
        public int $z = 0,
    ) {}
}

Og det er det. Så vi har en ny måde at markedsføre egenskaber, der er kortere, mere læselige og mindre tilbøjelige til fejl. Ifølge Nikita:

Det er en simpel syntaktisk transformation, som vi laver. Men det reducerer mængden af kedelplade-kode, du er nødt til at skrive for værdiobjekter især …

Ejendomserklæringen transformeres, da vi eksplicit havde erklæret disse egenskaber, og vi kan bruge Reflection-API til at introspektere egenskabsdefinitioner før udførelsen (se Desugaring):

Reflektion (og andre introspektionsmekanismer) vil observere tilstanden efter desugaring. Dette betyder, at promoverede egenskaber vises på samme måde som eksplicit deklarerede egenskaber, og promoverede konstruktørargumenter vises som almindelige konstruktørargumenter.

// before desugaring
class Point {
    public function __construct(public int $x = 0) {}
}

// after desugaring
class Point {
    public int $x;

    public function __construct(int $x = 0) {
        $this->x = $x;
    }
}

Inheritance

Vi har ingen begrænsninger i brugen af ​​arv sammen med promoverede parametre. Under alle omstændigheder er der ikke et bestemt forhold mellem forældre og child class construction. Ifølge Nikita:

Normalt siger vi, at metoder altid skal være kompatible med den overordnede metode. […] men denne regel gælder ikke for konstruktøren. Så konstruktøren hører virkelig til en enkelt klasse, og konstruktører mellem forældre og børn klasse behøver ikke at være kompatible på nogen måde.

Her er et eksempe:

class Test {
    public function __construct(
        public int $x = 0
    ) {}
}

class Child extends Test {
    public function __construct(
        $x, 
        public int $y = 0,
        public int $z = 0,
    ) {
        parent::__construct($x);
    }
}

Hvad der ikke er tilladt med promoverede egenskaber

Fremme egenskaber er tilladt i ikke-abstrakte konstruktører og træk, men der er flere begrænsninger, der er værd at nævne her.

Abstract Constructors

Promoverede egenskaber er ikke tilladt i abstrakte klasser og grænseflader:

abstract class Test {
    // Error: Abstract constructor.
    abstract public function __construct(private $x);
}
 
interface Test {
    // Error: Abstract constructor.
    public function __construct(private $x);
}
Nullability

En af de mest bemærkelsesværdige begrænsninger er relateret til nullability. Tidligere, da vi brugte en type, der ikke var eksplicit nullable, men med en nul standardværdi, var typen implicit nullable. Men med egenskabstyper har vi ikke denne implicitte opførsel, fordi promoverede parametre kræver en ejendomserklæring, og den nullable type skal eksplicit erklæres. Se følgende eksempel fra RFC:

class Test {
    // Error: Using null default on non-nullable property
    public function __construct(public Type $prop = null) {}

    // Correct: Make the type explicitly nullable instead
    public function __construct(public ?Type $prop = null) {}
}
Callable Type

Da konverterbar ikke er en understøttet type for egenskaber, har vi ikke tilladelse til at bruge den konverterbare type i promoverede egenskaber :

class Test {
    // Error: Callable type not supported for properties.
    public function __construct(public callable $callback) {}
}
The var Keyword Is Not Allowed

Kun et synligt keyword kan bruges med promoverede parametre, så det er ikke tilladt at erklære konstruktøregenskaber med var keyword (se følgende eksempel fra RFC) :

class Test {
    // Error: "var" keyword is not supported.
    public function __construct(var $prop) {}
}
No Duplications Allowed

Vi kan kombinere promoverede egenskaber og eksplicitte egenskaber i samme klasse, men egenskaber kan ikke erklæres to gange :

class Test {
    public string $prop;
    public int $explicitProp;

    // Correct
    public function __construct(public int $promotedProp, int $arg) {
        $this->explicitProp = $arg;
    }

    // Error: Redeclaration of property.
    public function __construct(public string $prop) {}
}
Variadic Parameters Are Not Allowed

Årsagen her er, at den erklærede type adskiller sig fra den variadiske parameter, som faktisk er en matrix :

class Test {
    // Error: Variadic parameter.
    public function __construct(public string ...$strings) {}
}

Yderligere læsninger

For at se nærmere på Costructor Property Promotion, lyt til dette interview med Nikita Popov. For et dybt overblik over object ergonomics i PHP, se dette indlæg og følgende interview med Larry Garfield.

Validering af abstrakte egenskabsmetoder

Traits er defineret som “en mekanisme til genanvendelse af kode på enkelt arvsprog som PHP”. Typisk bruges de til at erklære metoder, der kan bruges i flere klasser.

En egenskab kan også indeholde abstrakte metoder. Disse metoder erklærer simpelthen metodens signatur, men metodens implementering skal ske inden for klassen ved hjælp af egenskaben.

I henhold til PHP-manualen

“Traits understøtter brugen af ​​abstrakte metoder til at stille krav til exhibiting class.”

Dette betyder også, at signaturer til metoderne skal matche. Med andre ord skal typen og antallet af nødvendige argumenter være den samme.

I hvert fald håndhæves signatur-validering ifølge Nikita Popov, forfatter af RFC, i øjeblikket kun spottet:

Følgende eksempel fra Nikita vedrører den første sag (ikke håndhævet underskrift):

trait T {
	abstract public function test(int $x);
}
 
class C {
	use T;

	// Allowed, but shouldn't be due to invalid type.
	public function test(string $x) {}
}

Når det er sagt, foreslår denne RFC altid at kaste en dødelig fejl, hvis implementeringsmetoden ikke er kompatibel med den abstrakte egenskabsmetode, uanset dens oprindelse:

Fatal error: Declaration of C::test(string $x) must be compatible with T::test(int $x) in /path/to/your/test.php on line 10

Denne RFC er enstemmig godkendt.

Inkompatible metodetegn

I PHP kaster arvefejl på grund af inkompatible metode-signaturer enten en dødelig fejl eller en advarsel afhængigt af, hvad der forårsager fejlen.

Hvis en klasse implementerer en grænseflade, kaster ukompatible metode-signaturer en dødelig fejl. I henhold til Object Interfaces documentation:

”Klassen, der implementerer grænsefladen, skal bruge en metode-signatur, der er kompatibel med LSP (Liskov Substitution Principle). Hvis du ikke gør det, vil det medføre en dødelig fejl. ”

Her er et eksempel på en arvefejl med en grænseflade:

interface I {
	public function method(array $a);
}
class C implements I {
	public function method(int $a) {}
}

I PHP 7.4 ville koden ovenfor kaste følgende fejl:

Fatal error: Declaration of C::method(int $a) must be compatible with I::method(array $a) in /path/to/your/test.php on line 7

En funktion i en child class med en inkompatibel signatur ville kaste en advarsel. Se følgende kode fra RFC:

class C1 {
	public function method(array $a) {}
}
class C2 extends C1 {
	public function method(int $a) {}
}

I PHP 7.4 ville koden ovenfor blot kaste en advarsel:

Warning: Declaration of C2::method(int $a) should be compatible with C1::method(array $a) in /path/to/your/test.php on line 7

Nu foreslår denne RFC altid at kaste en dødelig fejl ved underskrifter med inkompatibel metode. Med PHP 8 ville den kode, vi så tidligere ovenfor, bede om følgende:

Fatal error: Declaration of C2::method(int $a) must be compatible with C1::method(array $a) in /path/to/your/test.php on line 7

Arrays der starter med et negativt indeks

I PHP, hvis en matrix starter med et negativt indeks (start_index <0), starter de følgende indekser fra 0 (mere om dette i array_fill dokumentation). Se på følgende eksempel:

$a = array_fill(-5, 4, true);
var_dump($a);

I PHP 7.4 ville resultatet være følgende:

array(4) {
	[-5]=>
	bool(true)
	[0]=>
	bool(true)
	[1]=>
	bool(true)
	[2]=>
	bool(true)
}

Nu foreslår denne RFC at ændre ting, så det andet indeks ville være start_index + 1, uanset værdien af start_index.

I PHP 8 ville koden ovenfor resultere i følgende array:

array(4) {
	[-5]=>
	bool(true)
	[-4]=>
	bool(true)
	[-3]=>
	bool(true)
	[-2]=>
	bool(true)
}

Med PHP 8 ændrer arrays der begynder med et negativt indeks deres opførsel. Læs mere om bagudkompatibiliteter i RFC.

Union Types 2.0

Union types accepterer værdier, der kan være af forskellige typer. I øjeblikket yder PHP ikke support til fagtyper med undtagelse af syntaks ?Type og den specielle iterable type.

Før PHP 8 kunne union types kun specificeres i phpdoc-kommentarer, som vist i følgende eksempel fra RFC:

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;
	}
}

Nu foreslår the Union types 2.0 RFC at tilføje support til union types i funktionssignaturer, så vi ikke vil stole på inline-dokumentation mere, men vil definere union types med en T1 | T2 | ... syntaks i stedet:

class Number {
	private int|float $number;

	public function setNumber(int|float $number): void {
		$this->number = $number;
	}

	public function getNumber(): int|float {
		return $this->number;
	}
}

Som forklaret af Nikita Popov i RFC,

”At støtte fagforeningstyper på sproget giver os mulighed for at flytte flere typeoplysninger fra phpdoc til funktionsunderskrifter med de sædvanlige fordele, dette medfører:

  • Types håndhæves faktisk, så fejl kan fanges tidligt.
  • Fordi de håndhæves, er type-oplysninger mindre tilbøjelige til at blive forældede eller gå glip af kanter.
  • Types kontrolleres under arv, hvilket håndhæver Liskov-substitutionsprincippet.
  • Types er tilgængelige via Reflektion.
  • Syntaxen er meget mindre kedelplade-y end phpdoc. ”

Union types understøtter alle tilgængelige typer med nogle begrænsninger:

Du kan læse mere om union types V2 i RFC.

Konsistente typefejl til interne funktioner

Når du sender en parameter af ulovlig type, opfører de interne og brugerdefinerede funktioner sig forskelligt.

Brugerdefinerede funktioner kaster en TypeError, men interne funktioner opfører sig på forskellige måder, afhængigt af flere forhold. Alligevel er den typiske opførsel at smide en advarsel og returnere null. Se følgende eksempel i PHP 7.4:

var_dump(strlen(new stdClass));

Dette ville resultere i følgende advarsel:

Warning: strlen() expects parameter 1 to be string, object given in /path/to/your/test.php on line 4
NULL

Hvis strict_types er aktiveret, eller hvis argument oplysninger specificerer typer, vil adfærden være anderledes. I sådanne scenarier registreres typefejlen og resulterer i en TypeError.

Denne situation ville føre til en række problemer, der er godt forklaret i RFC’s problemafdeling.

For at fjerne disse uoverensstemmelser foreslår denne RFC at oprette de interne parameter-parsing-API’er til altid at generere en ThrowError i tilfælde af en parametertilpasning.

I PHP 8 kaster koden ovenfor følgende fejl:

Fatal error: Uncaught TypeError: strlen(): Argument #1 ($str) must be of type string, object given in /path/to/your/test.php:4
Stack trace:
#0 {main}
  thrown in /path/to/your/test.php on line 4

Throw Expression

I PHP er throw en statement, så det er ikke muligt at bruge det på steder, hvor kun en expression er tilladt.

Denne RFC foreslår at konvertere throw statement  til et udtryk, så det kan bruges i enhver sammenhæng, hvor udtryk er tilladt. For eksempel arrow functions, null coalesce operator, ternary og elvis operators osv.

Se følgende eksempler fra RFC:

$callable = fn() => throw new Exception();

// $value is non-nullable.
$value = $nullableValue ?? throw new InvalidArgumentException();
 
// $value is truthy.
$value = $falsableValue ?: throw new InvalidArgumentException();

Weak Maps

Et weak map er en samling af data (objekter), hvor nøgler refereres svagt, hvilket betyder, at de ikke forhindres i at blive opsamlet skrald.

Brug for en lynhurtig, sikker og udviklervenlig hosting til dine websteder? Kinsta er bygget med WordPress-udviklere i tankerne og giver masser af værktøjer og et stærkt dashboard. Check vores planer

PHP 7.4 tilføjede støtte til weak references som en måde at bevare en henvisning til et objekt, der ikke forhindrer selve objektet i at blive ødelagt. Som påpeget af Nikita Popov,

”Rå svage referencer er kun af begrænset brugbarhed i sig selv, og weak maps er meget mere almindeligt anvendt i praksis. Det er ikke muligt at implementere et effektivt weak map oven på PHP-svage referencer, fordi der ikke er mulighed for at registrere et destruction callback. ”

Derfor introducerer denne RFC en WeakMap-klasse for at oprette objekter, der kan bruges som svage weak map keys, der kan ødelægges og fjernes fra weak map, hvis der ikke er yderligere henvisninger til nøgleobjektet.

I langvarige processer ville dette forhindre hukommelse lækager og forbedre ydelsen. Se følgende eksempel fra RFC:

$map = new WeakMap;
$obj = new stdClass;
$map[$obj] = 42;
var_dump($map);

Med PHP 8 ville koden ovenfor give følgende resultat (se koden i action her):

object(WeakMap)#1 (1) {
	[0]=>
	array(2) {
		["key"]=>
		object(stdClass)#2 (0) {
		}
		["value"]=>
		int(42)
	}
}

Hvis du fjerner objektet, fjernes nøglen automatisk fra weak map:

unset($obj);
var_dump($map);

Nu ville resultatet være følgende:

object(WeakMap)#1 (0) {
}

Se RFC for et nærmere kig på weak mapst. Forslaget blev enstemmigt godkendt.

Trailing commas i parameterliste

Trailing commas er kommaer knyttet til lister over elementer i forskellige sammenhænge. PHP 7.2 introducerede trailing commas i listesyntaks, PHP 7.3 introducerede trailing commas i function calls.

PHP 8 introducerer nu trailing commas i parameter lists med funktioner, metoder og lukninger, som vist i følgende eksempel:

class Foo {
	public function __construct(
		string $x,
		int $y,
		float $z, // trailing comma
	) {
		// do something
	}
}

Dette forslag blev vedtaget med 58 til 1 stemmer.

Allow ::class syntax på objekter

For at hente navnet på en klasse kan vi bruge Foo\Bar::class syntax. Denne RFC foreslår at udvide den samme syntaks til objekter, så det nu er muligt at hente navnet på klassen på et givet objekt som vist i eksemplet herunder:

$object = new stdClass;
var_dump($object::class); // "stdClass"
 
$object = null;
var_dump($object::class); // TypeError

Med PHP 8 giver $object:: class det samme resultat som get_class ($object). Hvis $object ikke er et objekt, kaster det en TypeError-undtagelse.

Dette forslag blev enstemmigt godkendt.

Attributes v2

Attributes, også kendt som annotationer, er en form for strukturerede metadata, der kan bruges til at specificere egenskaber for objekter, elementer eller filer.

Indtil PHP 7.4 var doc-kommentarer den eneste måde at tilføje metadata til erklæringer om klasser, funktioner osv. Nu introducerer Attributes v2 RFC attributes til PHP, der definerer dem som en form for strukturerede, syntaktiske metadata, der kan føjes til erklæringerne om klasser, egenskaber, funktioner, metoder, parametre og konstanter.

Attributes tilføjes før de erklæringer, de henviser til. Se følgende eksempler fra RFC:

<>
class Foo
{
	<>
	public const FOO = 'foo';

	<>
	public $x;

	<>
	public function foo(<> $bar) { }
}

$object = new <> class () { };

<>
function f1() { }

$f2 = <> function () { };

$f3 = <> fn () => 1;

Attributes kan tilføjes før eller efter en doc-block kommentar:

<>
/** docblock */
<>
function foo() {}

Hver erklæring kan have en eller flere attributter, og hver attribut kan have en eller flere tilknyttede værdier:

<>
<<SingleArgument(0)>>
<<FewArguments('Hello', 'World')>>
function foo() {}

Se RFC for en dybere oversigt over PHP-attributter, brugssager og alternativ syntaks.

Nye PHP-funktioner

PHP 8 bringer flere nye funktioner til sproget:

str_contains

Før PHP 8 var strstr og strpos de typiske muligheder for udviklere at søge efter en nål inde i en given streng. Problemet er, begge funktioner betragtes ikke som meget intuitive, og deres brug kan være forvirrende for nye PHP-udviklere. Se følgende eksempel:

$mystring = 'Managed WordPress Hosting';
$findme = 'WordPress';
$pos = strpos($mystring, $findme);

if ($pos !== false) {
	echo "The string has been found";
} else {
	echo "String not found";
}

I eksemplet ovenfor brugte vi! == sammenligning operatøren, som også kontrollerer, om to værdier er af samme type. Dette forhindrer os i at få en fejl, hvis nålens placering er 0:

”Denne funktion returnerer muligvis Boolean FALSE, men kan også returnere en ikke-boolean værdi, der evalueres til FALSE. […] Brug === operatoren til at teste returnerings-værdien for denne funktion”

Derudover giver flere rammer hjælperfunktioner til at søge efter en værdi inde i en given streng (se Laravel Helpers dokumentation som et eksempel).

Nu foreslår denne RFC introduktion af en ny funktion, der gør det muligt at søge i en streng: str_concepts.

str_contains ( string $haystack , string $needle ) : bool

Dens brug er temmelig ligetil. str_concepts kontrollerer om $needle findes i $haystack og returnerer true eller false i overensstemmelse hermed.

Så takket være str_contains kan vi skrive følgende kode:

$mystring = 'Managed WordPress Hosting';
$findme   = 'WordPress';

if (str_contains($mystring, $findme)) {
	echo "The string has been found";
} else {
	echo "String not found";
}

Hvilket er mere læseligt og mindre tilbøjeligt til fejl (se denne kode i action her).
På dette tidspunkt er str_containes store og små bogstaver, men dette kan ændre sig i fremtiden.

str_concepts-forslaget vedtaget med 43 til 9 stemmer.

str_starts_with() og str_ends_with()

Foruden str_concepts-funktionen tillader to nye funktioner at søge efter en needle inden i en given streng: str_starts_with og str_ends_with.

Disse nye funktioner kontrollerer, om en given streng starter eller slutter med en anden streng:

str_starts_with (string $haystack , string $needle) : bool
str_ends_with (string $haystack , string $needle) : bool

Begge funktioner returnerer false, hvis $needle er længere end $haystack.

Ifølge Will Hudgins, forfatteren af denne RFC,

str_starts_with– og str_ends_with-funktionaliteten er så almindeligt nødvendigt, at mange store PHP-rammer understøtter det, herunder Symfony, Laravel, Yii, FuelPHP og Phalcon.”

Takket være dem kunne vi nu undgå at bruge suboptimale og mindre intuitive funktioner som substr, strpos. Begge funktioner er store og små bogstaver:

$str = "WordPress";
if (str_starts_with($str, "Word")) echo "Found!";

if (str_starts_with($str, "word")) echo "Not found!";

Du kan se denne kode i handling her.

Denne RFC er godkendt med 51 til 4 stemmer.

get_debug_type

get_debug_type er en ny PHP-funktion, der returnerer typen af en variabel. Den nye funktion fungerer på en ganske lignende måde som gettype funktion, men get_debug_type returnerer oprindelige type navne og løser klassens navn.

Det er en god forbedring for sproget, da gettype() ikke er nyttigt til typekontrol.

RFC giver to nyttige eksempler for bedre at forstå forskellen mellem den nye get_debug_type() -function og gettype(). Det første eksempel viser gettype på arbejdet:

$bar = [1,2,3];

if (!($bar instanceof Foo)) { 
	throw new TypeError('Expected ' . Foo::class . ', got ' . (is_object($bar) ? get_class($bar) : gettype($bar)));
}

Med PHP 8 kunne vi i stedet bruge get_debug_type:

if (!($bar instanceof Foo)) { 
	throw new TypeError('Expected ' . Foo::class . ' got ' . get_debug_type($bar));
}

Med PHP 8 kunne vi bruge get_de Følgende tabel viser returnerende værdier af get_debug_type og gettype:

Value gettype() get_debug_type()
1 integer int
0.1 double float
true boolean bool
false boolean bool
null NULL null
“WordPress” string string
[1,2,3] array array
A class with name “Foo\Bar” object Foo\Bar
An anonymous class object class@anonymous

Yderligere RFC’er

På dette tidspunkt er flere RFC’er, der er målrettet mod PHP 8, stadig i udkast og/eller afventer implementering. Vi tilføjer dem, så snart deres status ændres til “Implementeret”.

Her er en hurtig liste over yderligere godkendte forbedringer, der vil være en del af PHP 8:

  1. Stringable interface: denne RFC¨ introducerer en stringable grænseflade, der automatisk føjes til klasser, der implementerer __to String() -metoden. Det vigtigste mål her er at bruge string|Stringable union type.
  2. Nye DOM Living Standard API’er i ext/dom: denne RFC foreslår at implementere den nuværende DOM Living Standard til PHP DOM extension ved at introducere nye grænseflader og offentlige egenskaber.
  3. Static return type: PHP 8 introducerer brugen af ​​static som returtype ud for self– og parent typer.
  4. Variable Syntax Tweaks: denne RFC løser nogle resterende uoverensstemmelser i PHPs variable syntax
PHP 8 kommer senere i år, og det vil medføre mange ændringer og forbedringer. 🚀 Tjek vores dybe dyk ned i de nye funktioner!Click to Tweet

Resumé

Sikke en tur! I dette indlæg dækkede vi alle de vigtigste ændringer og forbedringer, der forventes med frigivelsen af ​​PHP 8. Den mest afventede er helt sikkert Just in Time Compiler, men der kommer så meget mere med PHP 8.

Sørg for at bogmærke dette blogindlæg, da vi tilføjer vores favoritter til listen, så snart de er godkendt. 🤓

Nu er det din tur: er du klar til at teste de kommende PHP-funktioner? Hvilken er din favorit? Slip en linje i kommentarfeltet nedenfor.


Hvis du godt kunne lide denne artikel, så vil du elske Kinstas WordPress hostingplatform. Boost dit website og få 24/7 support fra vores WordPress-ekspertteam. Vores Google Cloud-drevne infrastruktur fokuserer på automatisk skalering, ydeevne og sikkerhed. Lad os vise dig Kinsta-forskellen! Tjek vores planer