interface I {
// We may naively assume that the PHP constant is always a string.
const PHP = 'PHP 8.2';
}
class Foo implements I {
// But implementing classes may define it as an array.
const PHP = [];
}
interface I {
const string PHP = 'PHP 8.3';
}
class Foo implements I {
const string PHP = [];
}
// Fatal error: Cannot use array as value for class constant
// Foo::PHP of type string
class Foo {
const PHP = 'PHP 8.2';
}
$searchableConstant = 'PHP';
var_dump(constant(Foo::class . "::{$searchableConstant}"));
class Foo {
const PHP = 'PHP 8.3';
}
$searchableConstant = 'PHP';
var_dump(Foo::{$searchableConstant});
#[\Override]
-Attribut RFC
use PHPUnit\Framework\TestCase;
final class MyTest extends TestCase {
protected $logFile;
protected function setUp(): void {
$this->logFile = fopen('/tmp/logfile', 'w');
}
protected function taerDown(): void {
fclose($this->logFile);
unlink('/tmp/logfile');
}
}
// The log file will never be removed, because the
// method name was mistyped (taerDown vs tearDown).
use PHPUnit\Framework\TestCase;
final class MyTest extends TestCase {
protected $logFile;
protected function setUp(): void {
$this->logFile = fopen('/tmp/logfile', 'w');
}
#[\Override]
protected function taerDown(): void {
fclose($this->logFile);
unlink('/tmp/logfile');
}
}
// Fatal error: MyTest::taerDown() has #[\Override] attribute,
// but no matching parent method exists
#[\Override]
-Attributs bei einer Methode, wird PHP nun sicherstellen, dass diese Methode in einer Elternklasse oder einem implementierten Interface vorhanden ist. Die Angabe des Attributs macht deutlich, dass das Überschreiben der Method absichtlich erfolgt ist und erleichtert ein Refactoring, da das Entfernen der überschriebenen Methode in der Elternklasse dazu führt, dass ein Fehler geworfen wird. class PHP {
public string $version = '8.2';
}
readonly class Foo {
public function __construct(
public PHP $php
) {}
public function __clone(): void {
$this->php = clone $this->php;
}
}
$instance = new Foo(new PHP());
$cloned = clone $instance;
// Fatal error: Cannot modify readonly property Foo::$php
class PHP {
public string $version = '8.2';
}
readonly class Foo {
public function __construct(
public PHP $php
) {}
public function __clone(): void {
$this->php = clone $this->php;
}
}
$instance = new Foo(new PHP());
$cloned = clone $instance;
$cloned->php->version = '8.3';
readonly
-Properties können nun innerhalb der magischen __clone
Methode geändert werden. json_validate()
Funktion RFC
Doc
function json_validate(string $string): bool {
json_decode($string);
return json_last_error() === JSON_ERROR_NONE;
}
var_dump(json_validate('{ "test": { "foo": "bar" } }')); // true
var_dump(json_validate('{ "test": { "foo": "bar" } }')); // true
json_validate()
erlaubt es einen String auf syntaktisch korrektes JSON auf eine effizientere Art und Weise als json_decode()
zu prüfen. Randomizer::getBytesFromString()
RFC
Doc
// This function needs to be manually implemented.
function getBytesFromString(string $string, int $length) {
$stringLength = strlen($string);
$result = '';
for ($i = 0; $i < $length; $i++) {
// random_int is not seedable for testing, but secure.
$result .= $string[random_int(0, $stringLength - 1)];
}
return $result;
}
$randomDomain = sprintf(
"%s.example.com",
getBytesFromString(
'abcdefghijklmnopqrstuvwxyz0123456789',
16,
),
);
echo $randomDomain;
// A \Random\Engine may be passed for seeding,
// the default is the secure engine.
$randomizer = new \Random\Randomizer();
$randomDomain = sprintf(
"%s.example.com",
$randomizer->getBytesFromString(
'abcdefghijklmnopqrstuvwxyz0123456789',
16,
),
);
echo $randomDomain;
Randomizer::getFloat()
und Randomizer::nextFloat()
RFC
Doc
// Returns a random float between $min and $max, both including.
function getFloat(float $min, float $max) {
// This algorithm is biased for specific inputs and may
// return values outside the given range. This is impossible
// to work around in userland.
$offset = random_int(0, PHP_INT_MAX) / PHP_INT_MAX;
return $offset * ($max - $min) + $min;
}
$temperature = getFloat(-89.2, 56.7);
$chanceForTrue = 0.1;
// getFloat(0, 1) might return the upper bound, i.e. 1,
// introducing a small bias.
$myBoolean = getFloat(0, 1) < $chanceForTrue;
$randomizer = new \Random\Randomizer();
$temperature = $randomizer->getFloat(
-89.2,
56.7,
\Random\IntervalBoundary::ClosedClosed,
);
$chanceForTrue = 0.1;
// Randomizer::nextFloat() is equivalent to
// Randomizer::getFloat(0, 1, \Random\IntervalBoundary::ClosedOpen).
// The upper bound, i.e. 1, will not be returned.
$myBoolean = $randomizer->nextFloat() < $chanceForTrue;
Durch die limitierte Präzision und der impliziten Rundung von Gleitkommazahlen war das gleichverteilte Generieren von Gleitkommazahlen innerhalb eines vorgegebenen Bereichs nicht einfach. Gängige Userland-Lösungen führen zu einer ungleichmäßigen Verteilung und geben potentiell Zahlen außerhalb des gewünschten Bereichs zurück.
Der Randomizer wurde daher um zwei Methoden erweitert, um zufällige Gleitkommazahlen mit einer Gleichverteilung zu generieren. Die Randomizer::getFloat()
-Methode nutzt den γ-section-Algorithmus, welcher in Drawing Random Floating-Point Numbers from an Interval. Frédéric Goualard, ACM Trans. Model. Comput. Simul., 32:3, 2022. veröffentlicht wurde.
php -l foo.php bar.php
No syntax errors detected in foo.php
php -l foo.php bar.php
No syntax errors detected in foo.php
No syntax errors detected in bar.php
Der Kommandozeilen-Linter erlaubt nun die Prüfung mehrerer Dateien.
DOMElement::getAttributeNames()
, DOMElement::insertAdjacentElement()
, DOMElement::insertAdjacentText()
, DOMElement::toggleAttribute()
, DOMNode::contains()
, DOMNode::getRootNode()
, DOMNode::isEqualNode()
, DOMNameSpaceNode::contains()
, und DOMParentNode::replaceChildren()
Methoden.IntlCalendar::setDate()
, IntlCalendar::setDateTime()
, IntlGregorianCalendar::createFromDate()
, und IntlGregorianCalendar::createFromDateTime()
Methoden.ldap_connect_wallet()
, und ldap_exop_sync()
Funktionen.mb_str_pad()
Funktion.posix_sysconf()
, posix_pathconf()
, posix_fpathconf()
, und posix_eaccess()
Funktionen.ReflectionMethod::createFromMethodName()
Methode.socket_atmark()
Funktion.str_increment()
, str_decrement()
, und stream_context_set_options()
Funktionen.ZipArchive::getArchiveFlag()
Methode.zend.max_allowed_stack_size
zum Angeben der maximal erlaubten Stack größe.n
bei einem leeren Array sorgt nun dafür, dass der nächste Index n + 1
statt 0
ist.range()
Funktion.U_MULTIPLE_DECIMAL_SEPERATORS
Konstante wurde als Veraltet markiert und wurde durch U_MULTIPLE_DECIMAL_SEPARATORS
ersetzt.MT_RAND_PHP
Mt19937 Variante wurde als veraltet markiert.ReflectionClass::getStaticProperties()
wurde von ?array
zu array
geändert.assert.active
, assert.bail
, assert.callback
, assert.exception
, and assert.warning
wurden als veraltet markiert.get_class()
und get_parent_class()
ohne die Angabe von Parametern ist veraltet.