CakeFest 2024: The Official CakePHP Conference

Neue Features

PHP-Kern

Typisierte Eigenschaften

Klasseneigenschaften unterstützen nun Typ-Deklarationen.

<?php
class User {
public
int $id;
public
string $name;
}
?>
Das obige Beispiel erzwingt, dass $user->id nur int-Werte zugewiesen werden können und $user->name nur string-Werte.

Pfeilfunktionen

Die Pfeilfunktionen bieten eine Kurzform der Syntax für die Definition von Funktionen mit impliziter Bindung an den Wertebereich.

<?php
$factor
= 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>

Eingeschränkte Kovarianz des Rückgabetyps und Kontravarianz des Parametertyps

Der folgende Code funktioniert nun:

<?php
class A {}
class
B extends A {}

class
Producer {
public function
method(): A {}
}
class
ChildProducer extends Producer {
public function
method(): B {}
}
?>
Die vollständige Unterstützung der Varianz ist nur verfügbar, wenn automatisches Laden verwendet wird. Innerhalb einer einzelnen Datei sind nur nichtzyklische Typreferenzen möglich, da alle Klassen verfügbar sein müssen, bevor sie referenziert werden.

Zuweisungsoperator für die Kombination mit null (null-Koaleszenz)

<?php
$array
['key'] ??= computeDefault();
// entspricht in etwa
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>

Entpacken innerhalb von Arrays

<?php
$parts
= ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
?>

Trennzeichen für numerische Literale

Bei numerischen Literalen können nun Unterstriche zwischen den Ziffern eingefügt werden.

<?php
6.674_083e-11
; // Gleitkommazahl
299_792_458; // Dezimalzahl
0xCAFE_F00D; // Hexadezimalzahl
0b0101_1111; // Binärzahl
?>

Schwache Referenzen

Eine schwache Referenz ermöglicht es dem Programmierer, eine Referenz auf ein Objekt zu behalten, die nicht verhindert, dass das Objekt zerstört wird.

Zulassen von Exceptions aus __toString()

Bei der Methode __toString() ist es nun möglich, Exceptions auszulösen. Zuvor führte dies zu einem schwerwiegenden Fehler. Alle behebbaren schwerwiegenden Fehler bei Zeichenketten-Konvertierungen wurden in Error-Exceptions umgewandelt.

CURL

Wenn die Erweiterung mit libcurl >= 7.56.0 kompiliert wurde, unterstützt die Klasse CURLFile nun zusätzlich zu einfachen Dateinamen auch Stream-Wrapper.

Filter

Der Filter FILTER_VALIDATE_FLOAT unterstützt nun die Optionen min_range und max_range mit der gleichen Semantik wie FILTER_VALIDATE_INT.

FFI

FFI ist eine neue Erweiterung, die eine einfache Möglichkeit bietet, native Funktionen aufzurufen, auf native Variablen zuzugreifen und Datenstrukturen zu erzeugen/aufzurufen, die in C-Bibliotheken definiert sind.

GD

Der Bildfilter IMG_FILTER_SCATTER wurde hinzugefügt, um einen Streufilter auf Bilder anzuwenden.

Hash

Der crc32c-Hash, der das Castagnoli-Polynom verwendet, wurde hinzugefügt. Diese CRC32-Variante wird in Speichersystemen wie iSCSI, SCTP, Btrfs und ext4 verwendet.

Multibyte-Zeichenketten

Die Funktion mb_str_split() wurde hinzugefügt. Sie bietet die gleiche Funktionalität wie str_split(), arbeitet aber mit Codepunkten anstelle von Bytes.

OPcache

Die Unterstützung für das Vorladen von Code wurde hinzugefügt.

Reguläre Ausdrücke (Perl-kompatibel)

Die Funktionen preg_replace_callback() und preg_replace_callback_array() akzeptieren nun zusätzlich den Parameter flags, der die Flags PREG_OFFSET_CAPTURE und PREG_UNMATCHED_AS_NULL unterstützt. Dies beeinflusst das Format des Arrays für die Übereinstimmungen, das an die Callback-Funktion übergeben wird.

PDO

Bei den Treibern für mysql, mssql, dblib, firebird und oci können Benutzername und Passwort nun als Teil des PDO DSN angegeben werden. Zuvor wurde dies nur vom pgsql-Treiber unterstützt. Wenn ein Benutzername/Passwort sowohl im Konstruktor als auch im DSN angegeben wird, hat der Konstruktor Vorrang.

Es ist nun möglich, Fragezeichen in SQL-Abfragen zu maskieren, damit sie nicht als als Platzhalter für Parameter interpretiert werden. Mit ?? ist es möglich, ein einzelnes Fragezeichen an die Datenbank zu senden. Dieses kann z. B. bei PostgreSQL als ?-Operator verwendet werden, um zu prüfen, ob ein JSON-Schlüssel existiert.

PDO_OCI

Die Methode PDOStatement::getColumnMeta() ist nun verfügbar.

PDO_SQLite

PDOStatement::getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT) ermöglicht es, zu prüfen, ob eine Anweisung nur lesend ist, d. h., ob sie die Datenbank nicht verändert.

PDO::setAttribute(PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES, true) ermöglicht in PDO::errorInfo() und PDOStatement::errorInfo() die Verwendung der erweiterten SQLite3-Ergebniscodes.

SQLite3

Die Methode SQLite3::lastExtendedErrorCode() wurde hinzugefügt, um den letzten erweiterten Ergebniscode abzurufen.

SQLite3::enableExtendedResultCodes($enable = true) wurde hinzugefügt, was dazu führt, dass SQLite3::lastErrorCode() erweiterte Ergebniscodes zurückgibt.

Standard

strip_tags() mit einem Array von Tag-Namen

Die Funktion strip_tags() akzeptiert nun auch ein Array mit erlaubten Tags: Anstelle von strip_tags($str, '<a><p>') kann nun strip_tags($str, ['a', 'p']) geschrieben werden.

Benutzerdefinierte Serialisierung von Objekten

Es wurde ein neues Verfahren für die benutzerdefinierte Serialisierung von Objekten hinzugefügt, das zwei neue magische Methoden verwendet: __serialize und __unserialize.

<?php
// Gibt ein Array zurück, das alle notwendigen Zustände des Objekts enthält.
public function __serialize(): array;

// Stellt den Objektzustand aus dem angegebenen Datenarray wieder her.
public function __unserialize(array $data): void;
?>
Das neue Serialisierungsverfahren ersetzt die Schnittstelle Serializable, die in Zukunft für veraltet erklärt werden wird.

Verwendung der array_merge-Funktionen ohne Parameter

Die Funktionen array_merge() und array_merge_recursive() können nun auch ohne Parameter aufgerufen werden und geben in diesem Fall ein leeres Array zurück. Dies ist nützlich in Verbindung mit dem Spread-Operator (Zerlegungsoperator), z. B. array_merge(...$arrays).

Die Funktion proc_open()

proc_open() akzeptiert für den Befehl nun ein Array anstelle einer Zeichenkette. In diesem Fall wird der Prozess direkt geöffnet (ohne den Umweg über eine Shell) und PHP kümmert sich bei Bedarf darum, die Parameter zu maskieren.

<?php
proc_open
(['php', '-r', 'echo "Hello World\n";'], $descriptors, $pipes);
?>

proc_open() unterstützt nun die Deskriptoren redirect und null.

<?php
// Wie 2>&1 in der Shell
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['redirect', 1]], $pipes);
// Wie 2>/dev/null oder 2>nul in der Shell
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['null']], $pipes);
?>

argon2i(d) ohne libargon

Wenn PHP ohne libargon gebaut wird, hat password_hash() nun die argon2i- und argon2id-Implementierungen aus der Erweiterung Sodium.

add a note

User Contributed Notes 2 notes

up
97
Rain
4 years ago
It should be noted that typed properties internally are never initialized to a default null. Unless of course you initialize them to null yourself. That's why you will always going to encounter this error if you try to access them before initialization.

**Typed property foo::$bar must not be accessed before initialization**

<?php
class User
{
public
$id;
public
string $name; // Typed property (Uninitialized)
public ?string $age = null; // Typed property (Initialized)
}

$user = new User;
var_dump(is_null($user->id)); // bool(true)
var_dump(is_null($user->name)); // PHP Fatal error: Typed property User::$name must not be accessed before initialization
var_dump(is_null($user->age));// bool(true)
?>

Another thing worth noting is that it's not possible to initialize a property of type object to anything other than null. Since the evaluation of properties happens at compile-time and object instantiation happens at runtime. One last thing, callable type is not supported due to its context-dependent behavior.
up
7
wow-apps.pro
4 years ago
<?php

// How to get property type? For example for testing:

class Foo
{
private
int $num;
private
bool $isPositive;
private
$notes;
}

$reflection = new \ReflectionClass(Foo::class);
$classProperties = $reflection->getProperties(\ReflectionProperty::IS_PRIVATE);
foreach (
$classProperties as $classProperty) {
var_dump((string) $classProperty->getType());
}

/**
* Result:
* "int"
* "bool"
* ""
*/
To Top