Neue Features
Deklaration skalarer Typen
Für die
Deklaration des Typs von
Skalaren gibt es zwei Möglichkeiten: erzwungen (Standard) und strikt. Die
folgenden Typen können nun für Parameter erzwungen werden: Zeichenketten
(string), Ganzzahlen (int
), Gleitkommazahlen
(float), und Booleans (bool
). Sie ergänzen
die anderen in PHP 5 eingeführten Typen: Klassennamen, Schnittstellen,
array und callable.
<?php
// Erzwingender Modus
function sumOfInts(int ...$ints)
{
return array_sum($ints);
}
var_dump(sumOfInts(2, '3', 4.1));
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
int(9)
Um den strikten Modus zu aktivieren, muss am Anfang der Datei eine einzelne
declare
-Direktive stehen. Das bedeutet, dass die Strenge der Typisierung
für Skalare für jede Datei einzeln festgelegt wird. Diese Anweisung wirkt
sich nicht nur auf die Typ-Deklarationen von Parametern aus, sondern auch
auf den Rückgabetyp von Funktionen (siehe
Deklaration des Rückgabetyps),
auf eingebaute PHP-Funktionen und auf Funktionen von geladenen Erweiterungen.
Eine vollständige Dokumentation und Beispiele für die Deklaration von Skalartypen ist im Abschnitt über die Deklaration des Typs zu finden.
Deklaration des Rückgabetyps
PHP 7 unterstützt die Deklaration des Rückgabetyps. Ähnlich wie bei der Deklaration des Parameter-Typs gibt die Deklaration des Rückgabetyps den Typ des Wertes an, der von einer Funktion zurückgegeben wird. Für die Deklaration des Rückgabetyps stehen dieselben Typen zur Verfügung wie für die Deklaration des Parameter-Typs.
<?php
function arraysSum(array ...$arrays): array
{
return array_map(function(array $array): int {
return array_sum($array);
}, $arrays);
}
print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Array ( [0] => 6 [1] => 15 [2] => 24 )
Eine vollständige Dokumentation und Beispiele für die Deklaration des Rückgabetyps ist im Abschnitt über die Deklaration des Rückgabetyps zu finden.
Null-Koaleszenz-Operator
Der null-Koaleszenz-Operator (etwa: Operator für die Kombination mit null)
??
wurde als syntaktische Vereinfachung hinzugefügt für
den häufigen Fall, dass ein ternärer Operator in Verbindung mit
isset() verwendet wird. Er gibt seinen ersten Operanden
zurück, wenn er existiert und nicht null
ist; andernfalls gibt er seinen
zweiten Operanden zurück.
<?php
// Gibt den Wert von $_GET['user'] zurück, falls er existiert,
// und andernfalls 'nobody'.
$username = $_GET['user'] ?? 'nobody';
// Dies ist gleichbedeutend mit:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
// Dieser Operator kann verkettet werden. Das Beispiel gibt den
// ersten definierten Wert aus $_GET['user'], $_POST['user'] und
// 'nobody' zurück.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>
Raumschiff-Operator (Spaceship)
Der Raumschiff-Operator wird für den Vergleich zweier Ausdrücke verwendet. Er gibt -1, 0 oder 1 zurück, wenn $a kleiner, gleich oder größer ist als $b. Vergleiche werden gemäß den üblichen Regeln für Typenvergleiche in PHP durchgeführt.
<?php
// Ganzzahlen
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
// Gleitkommazahlen
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
// Zeichenketten
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
?>
Definieren von Array-Konstanten mit define()
Es ist nun möglich, Array-Konstanten mit
define() zu definieren. Bis zu PHP 5.6 konnten
Array-Konstanten nur mit const
definiert werden.
<?php
define('ANIMALS', [
'dog',
'cat',
'bird'
]);
echo ANIMALS[1]; // gibt "cat" aus
?>
Anonyme Klassen
Mit new class
wurde die Unterstützung für anonyme Klassen
hinzugefügt. Dies kann anstelle von vollständigen Klassendefinitionen
verwendet werden für Objekte, die nur einmal benötigt werden:
<?php
interface Logger {
public function log(string $msg);
}
class Application {
private $logger;
public function getLogger(): Logger {
return $this->logger;
}
public function setLogger(Logger $logger) {
$this->logger = $logger;
}
}
$app = new Application;
$app->setLogger(new class implements Logger {
public function log(string $msg) {
echo $msg;
}
});
var_dump($app->getLogger());
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
object(class@anonymous)#2 (0) { }
Die vollständige Dokumentation befindet sich im Abschnitt Anonyme Klassen.
Syntax für die Maskierung von Unicode-Codepunkten
Diese Syntax nimmt einen Unicode-Codepunkt in hexadezimaler Form und gibt diesen Codepunkt in UTF-8 in eine Zeichenkette mit doppelten Anführungszeichen oder einen Heredoc aus. Jeder gültige Codepunkt wird akzeptiert, wobei führende Nullen optional sind.
echo "\u";
echo "\u";
echo "\u";
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
ª ª (wie zuvor, jedoch mit führenden Nullen) 香
Closure::call()
Die Methode Closure::call() ist ein leistungsfähigerer und kürzerer Weg, um den Gültigkeitsbereich eines Objekts vorübergehend an eine Closure zu binden und diese aufzurufen.
<?php
class A {private $x = 1;}
// Code vor PHP 7
$getX = function() {return $this->x;};
$getXCB = $getX->bindTo(new A, 'A'); // zwischengeschaltete Closure
echo $getXCB();
// Code in PHP 7+
$getX = function() {return $this->x;};
echo $getX->call(new A);
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
1 1
Gefiltertes unserialize()
Dieser Mechanismus soll zusätzliche Sicherheit beim Deserialisieren von Objekten aus nicht vertrauenswürdigen Daten bieten. Durch die Definition einer Whitelist für Klassen, die deserialisiert werden dürfen, können Angriffe durch Code-Injection verhindert werden.
<?php
// wandelt alle Objekte in __PHP_Incomplete_Class-Objekte um
$data = unserialize($foo, ["allowed_classes" => false]);
// wandelt mit Ausnahme von MyClass und MyClass2 alle Objekte in __PHP_Incomplete_Class-Objekte um
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]]);
// In der Voreinstellung (entspricht dem Weglassen des zweiten Parameters) werden alle Klassen akzeptiert
$data = unserialize($foo, ["allowed_classes" => true]);
IntlChar
Die neue Klasse IntlChar wurde hinzugefügt, um zusätzliche Funktionalitäten von ICU zu nutzen. Die Klasse selbst definiert eine Reihe von statischen Methoden und Konstanten, die zur Bearbeitung von Unicode-Zeichen verwendet werden können.
<?php
printf('%x', IntlChar::CODEPOINT_MAX);
echo IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
10ffff COMMERCIAL AT bool(true)
Um diese Klasse verwenden zu können, muss die Erweiterung Intl installiert sein.
Expectations (Annahmen)
Die Expectations sind eine abwärtskompatible Weiterentwicklung der alten Funktion assert(). Sie ermöglichen Assertions ohne Leistungsverluste im Produktionscode und bieten die Möglichkeit, benutzerdefinierte Exceptions auszulösen, wenn eine Assertion fehlschlägt.
Während die alte API aus Kompatibilitätsgründen beibehalten wird, ist assert() nun ein Sprachkonstrukt, das es ermöglicht, dass der erste Parameter ein Ausdruck sein kann und nicht nur ein auszuwertender string-Wert oder ein zu testender bool)-Wert.
<?php
ini_set('assert.exception', 1);
class CustomError extends AssertionError {}
assert(false, new CustomError('Irgendeine Fehlermeldung'));
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Fatal error: Uncaught CustomError: Irgendeine Fehlermeldung
Alle Details zu diesem Feature, einschließlich der Konfiguration sowohl in Entwicklungs- und Produktionsumgebungen, befinden sich im Abschnitt Expectations der assert()-Referenz.
Zusammengefasste use
-Deklarationen
Klassen, Funktionen und Konstanten, die aus demselben namespace
importiert werden, können nun in einer einzigen use
-Anweisung
zusammengefasst werden.
<?php
// Code vor PHP 7
use some\namespace\ClassA;
use some\namespace\ClassB;
use some\namespace\ClassC as C;
use function some\namespace\fn_a;
use function some\namespace\fn_b;
use function some\namespace\fn_c;
use const some\namespace\ConstA;
use const some\namespace\ConstB;
use const some\namespace\ConstC;
// Code in PHP 7+
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};
?>
Generatoren können Werte zurückgeben
Dieses Feature baut auf der Generator-Funktionalität auf, die in PHP 5.5
eingeführt wurde. Sie ermöglicht es, eine return
-Anweisung
innerhalb eines Generators zu verwenden, damit der Wert eines Ausdrucks
zurückgegeben werden kann (eine Rückgabe per Referenz ist nicht erlaubt).
Dieser Wert kann mit der neuen Methode
Generator::getReturn()
abgerufen werden, die erst
verwendet werden darf, nachdem der Generator die Ausgabe von Werten
abgeschlossen hat.
<?php
$gen = (function() {
yield 1;
yield 2;
return 3;
})();
foreach ($gen as $val) {
echo $val, PHP_EOL;
}
echo $gen->getReturn(), PHP_EOL;
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
1 2 3
Die Möglichkeit, den Endwert eines Generators explizit zurückzugeben, ist sehr nützlich. Dadurch kann der Client-Code, der den Generator ausführt, den letzten vom Generator zurückgegebenen Wert (das Ergebnis einer Berechnung durch eine Art Co-Routine) als Sonderfall behandeln. Dies ist viel einfacher, als einen clientseitigen Code zu schreiben, der zunächst prüft, ob der zurückgegebene Wert der Letzte ist, und ihn dann gegebenenfalls als speziellen Wert behandelt.
Delegierung durch Generatoren
Generatoren können nun automatisch an einen anderen Generator, ein
Traversable-Objekt oder ein Array
delegieren, ohne dass Boilerplate (redundanter Code) in den äußersten
Generator geschrieben werden muss. Dies wird durch die Verwendung des
Konstrukts yield from
erreicht.
<?php
function gen()
{
yield 1;
yield 2;
yield from gen2();
}
function gen2()
{
yield 3;
yield 4;
}
foreach (gen() as $val)
{
echo $val, PHP_EOL;
}
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
1 2 3 4
Ganzzahl-Division mit intdiv()
Die neue Funktion intdiv() führt eine Ganzzahl-Division ihrer Operanden durch und gibt das Ergebnis zurück.
<?php
var_dump(intdiv(10, 3));
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
int(3)
Optionen für Session
Die Funktion session_start() akzeptiert nun ein Array von Optionen. Diese überschreiben die Session-Konfigurationsanweisungen, die normalerweise in der php.ini gesetzt werden.
Diese Optionen unterstützen nun auch
session.lazy_write. Diese
Option ist standardmäßig aktiviert und bewirkt, dass PHP eine Session-Datei
nur dann überschreibt, wenn sich die Session-Daten geändert haben. Außerdem
wurde die Option read_and_close
hinzugefügt. Sie kann
nur an session_start() übergeben werden und gibt an,
dass die Session-Daten gelesen werden sollen und die Session dann sofort
unverändert geschlossen werden soll.
Um zum Beispiel
session.cache_limiter auf
private
zu setzen und die Session nach dem Lesen sofort
zu schließen, kann Folgendes verwendet werden:
<?php
session_start([
'cache_limiter' => 'private',
'read_and_close' => true,
]);
?>
preg_replace_callback_array()
Wenn die Funktion preg_replace_callback() verwendet werden müsste, kann stattdessen mit der neuen Funktion preg_replace_callback_array() saubererer Code geschrieben werden. Vor PHP 7 musste für jeden regulären Ausdruck ein Callback ausgeführt werden, was dazu führte, dass die Callback-Funktion voller Verzweigungen sein musste.
Nun können Callbacks für jeden regulären Ausdruck registriert werden, indem ein assoziatives Array verwendet wird, bei dem die regulären Ausdrücke die Schlüssel sind, und die Callback-Funktionen deren Werte.
CSPRNG-Funktionen
Zwei neue Funktionen wurden hinzugefügt, um plattformübergreifend kryptographisch sichere Ganzzahlen und Zeichenketten zu erzeugen: random_bytes() und random_int().
list() kann nun immer Objekte entpacken, die ArrayAccess implementieren
Zuvor war nicht gewährleistet, dass list() bei Objekten, die ArrayAccess implementieren, korrekt funktioniert. Dies wurde nun behoben.
Andere Features
-
Es wurde die Möglichkeit hinzugefügt, beim Klonen auf Klassenelemente
zuzugreifen, z. B.
(clone $foo)->bar()
.