Constantes de classe typées
PHP < 8.3
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | 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 = []; } |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | 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 |
Recherche dynamique de constantes de classe
PHP < 8.3
Code : | Sélectionner tout |
1 2 3 4 5 6 7 | class Foo { const PHP = 'PHP 8.2'; } $searchableConstant = 'PHP'; var_dump(constant(Foo::class . "::{$searchableConstant}")); |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 | class Foo { const PHP = 'PHP 8.3'; } $searchableConstant = 'PHP'; var_dump(Foo::{$searchableConstant}); |
Nouvel attribut #[\Override]
PHP < 8.3
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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). |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
Clonage profond des propriétés en lecture seule
PHP < 8.3
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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'; |
Nouvelle fonction json_validate()
PHP < 8.3
Code : | Sélectionner tout |
1 2 3 4 5 6 7 | function json_validate(string $string): bool { json_decode($string); return json_last_error() === JSON_ERROR_NONE; } var_dump(json_validate('{ "test": { "foo": "bar" } }')); // true |
Code : | Sélectionner tout |
var_dump(json_validate('{ "test": { "foo": "bar" } }')); // true
Nouvelle méthode Randomizer::getBytesFromString()
PHP < 8.3
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 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; |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 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; |
Nouvelles méthodes Randomizer::getFloat() et Randomizer::nextFloat()
PHP < 8.3
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // 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; |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | $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; |
Le Randomizer a également été étendu avec deux méthodes pour générer des nombres flottants aléatoires de manière non biaisée. La méthode Randomizer::getFloat() utilise l'algorithme γ-section.
Le linter en ligne de commande prend en charge plusieurs fichiers
PHP < 8.3
Code : | Sélectionner tout |
1 2 | php -l foo.php bar.php No syntax errors detected in foo.php |
Code : | Sélectionner tout |
1 2 3 | php -l foo.php bar.php No syntax errors detected in foo.php No syntax errors detected in bar.php |
Nouvelles classes, interfaces et fonctions
- Nouvelles méthodes DOMElement::getAttributeNames(), DOMElement::insertAdjacentElement(), DOMElement::insertAdjacentText(), DOMElement::toggleAttribute(), DOMNode::contains(), DOMNode::getRootNode(), DOMNode::isEqualNode(), DOMNameSpaceNode::contains(), et DOMParentNode::replaceChildren().
- Nouvelles méthodes IntlCalendar::setDate(), IntlCalendar::setDateTime(), IntlGregorianCalendar::createFromDate(), et IntlGregorianCalendar::createFromDateTime().
- Nouvelles fonctions ldap_connect_wallet(), et ldap_exop_sync().
- Nouvelle fonction mb_str_pad().
- Nouvelles fonctions posix_sysconf(), posix_pathconf(), posix_fpathconf(), et posix_eaccess().
- Nouvelle méthode ReflectionMethod::createFromMethodName().
- Nouvelle fonction socket_atmark().
- Nouvelles fonctions str_increment(), str_decrement(), et stream_context_set_options().
- Nouvelle méthode ZipArchive::getArchiveFlag().
- Support de la génération de clés EC avec des paramètres EC personnalisés dans l'extension OpenSSL.
- Nouveau paramètre INI zend.max_allowed_stack_size pour définir la taille maximale autorisée de la pile.
- php.ini supporte maintenant la syntaxe des valeurs par défaut.
- Les classes anonymes peuvent maintenant être en lecture seule.
Dépréciations et ruptures de compatibilité
- Exceptions de date et d'heure plus appropriées.
- L'assignation d'un index négatif n à un taCleau vide s'assurera maintenant que l'index suivant est n + 1 au lieu de 0.
- Modifications de la fonction range().
- Changements dans la re-déclaration des propriétés statiques dans les traits.
- La constante U_MULTIPLE_DECIMAL_SEPERATORS est dépréciée en faveur de U_MULTIPLE_DECIMAL_SEPARATORS.
- La variante MT_RAND_PHP Mt19937 est oCsolète.
- ReflectionClass::getStaticProperties() n'est plus nullable.
- Les paramètres INI assert.active, assert.bail, assert.callback, assert.exception et assert.warning sont obsolètes.
- Les appels à get_class() et get_parent_class() sans arguments sont obsolètes.
- SQLite3 : Le mode d'erreur par défaut est défini sur exceptions.
Mettre à jour vers PHP 8.3 !
Source : PHP
Et vous ?
Quel est votre avis sur cette mise à jour de PHP ?
Voir aussi :
PHP 8.2 est disponible et s'accompagne des propriétés "en lecture seule" aux classes, ainsi que la possibilité de déprécier les propriétés dynamiques
PHP 8.2 est disponible en bêta 2. Cette version propose null, true et false en tant que types autonomes, ainsi que des constantes dans les traits
PHP 8.2 apportera de nouvelles fonctionnalités et les améliorations de performances, annoncée pour la fin de 2022