$components = parse_url("https://php.net/releases/8.5/en.php");
var_dump($components['host']);
// string(7) "php.net"use Uri\Rfc3986\Uri;
$uri = new Uri("https://php.net/releases/8.5/en.php");
var_dump($uri->getHost());
// string(7) "php.net"As an always-available part of PHP's standard library the new URI extension provides APIs to parse and modify URIs and URLs according to the RFC 3986 and the WHATWG URL standards.
The secure and standards-compliant URI parsing is powered by the uriparser (RFC 3986) and Lexbor (WHATWG URL) libraries.
Learn more about the backstory of this feature in The PHP Foundation’s blog.
final readonly class PhpVersion
{
public function __construct(
public string $version = 'PHP 8.4',
) {}
public function withVersion(string $version): self
{
$newObject = clone $this;
$newObject->version = $version;
return $newObject;
}
}
$version = new PhpVersion();
var_dump($version->version);
// string(7) "PHP 8.4"
var_dump($version->withVersion('PHP 8.5')->version);
// Fatal error: Uncaught Error: Cannot modify readonly property PhpVersion::$versionfinal readonly class PhpVersion
{
public function __construct(
public string $version = 'PHP 8.4',
) {}
public function withVersion(string $version): self
{
return clone($this, [
'version' => $version,
]);
}
}
$version = new PhpVersion();
var_dump($version->version);
// string(7) "PHP 8.4"
var_dump($version->withVersion('PHP 8.5')->version);
// string(7) "PHP 8.5"
var_dump($version->version);
// string(7) "PHP 8.4"clone() function. This enables straight-forward support of the "with-er" pattern for readonly classes. $input = ' Some kind of string. ';
$output = strtolower(
str_replace(['.', '/', '…'], '',
str_replace(' ', '-',
trim($input)
)
)
);
var_dump($output);
// string(19) "some-kind-of-string"$input = ' Some kind of string. ';
$output = $input
|> trim(...)
|> (fn($string) => str_replace(' ', '-', $string))
|> (fn($string) => str_replace(['.', '/', '…'], '', $string))
|> strtolower(...);
var_dump($output);
// string(19) "some-kind-of-string"The pipe operator allows chaining function calls together without dealing with intermediary variables. That can be especially helpful when replacing many "nested calls" with a chain that can be read forwards, rather than inside-out.
Learn more about the backstory of this feature in The PHP Foundation’s blog.
#[\NoDiscard] Attribute RFC
function getPhpVersion(): string
{
return 'PHP 8.4';
}
getPhpVersion(); // No Errors#[\NoDiscard]
function getPhpVersion(): string
{
return 'PHP 8.5';
}
getPhpVersion();
// Warning: The return value of function getPhpVersion() should either be used or intentionally ignored by casting it as (void)By adding the #[\NoDiscard] attribute to a function, PHP will check whether the returned value is consumed and emit a warning if it is not. This allows to improve the safety of APIs where the returned value is important, but where it is easy to forget using the return value by accident.
The associated (void) cast can be used to indicate that a value is intentionally unused.
final class CalculatorTest extends \PHPUnit\Framework\TestCase
{
#[DataProvider('subtractionProvider')]
public function testSubtraction(
int $minuend,
int $subtrahend,
int $result
): void
{
$this->assertSame(
$result,
Calculator::subtract($minuend, $subtrahend)
);
}
public static function subtractionProvider(): iterable
{
for ($i = -10; $i <= 10; $i++) {
yield [$i, $i, 0];
yield [$i, 0, $i];
yield [0, $i, -$i];
}
}
}final class CalculatorTest
{
#[Test\CaseGenerator(static function (): iterable
{
for ($i = -10; $i <= 10; $i++) {
yield [$i, $i, 0];
yield [$i, 0, $i];
yield [0, $i, -$i];
}
})]
public function testSubtraction(
int $minuend,
int $subtrahend,
int $result
)
{
\assert(
Calculator::subtract($minuend, $subtrahend) === $result
);
}
}$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
$ch1 = curl_init('https://php.net/');
curl_setopt($ch1, CURLOPT_SHARE, $sh);
curl_exec($ch1);
$ch2 = curl_init('https://thephp.foundation/');
curl_setopt($ch2, CURLOPT_SHARE, $sh);
curl_exec($ch2);$sh = curl_share_init_persistent([
CURL_LOCK_DATA_DNS,
CURL_LOCK_DATA_CONNECT
]);
$ch1 = curl_init('https://php.net/');
curl_setopt($ch1, CURLOPT_SHARE, $sh);
curl_exec($ch1);
$ch2 = curl_init('https://thephp.foundation/');
curl_setopt($ch2, CURLOPT_SHARE, $sh);
curl_exec($ch2);CurlSharePersistentHandle class, curl_multi_get_handles(), curl_share_init_persistent() functions are available.
array_first() and array_last() functions RFC
$php = [
'php-82' => ['state' => 'security', 'branch' => 'PHP-8.2'],
'php-83' => ['state' => 'active', 'branch' => 'PHP-8.3'],
'php-84' => ['state' => 'active', 'branch' => 'PHP-8.4'],
'php-85' => ['state' => 'upcoming', 'branch' => 'PHP-8.5'],
];
$upcomingRelease = null;
foreach ($php as $key => $version) {
if ($version['state'] === 'upcoming') {
$upcomingRelease = $version;
break;
}
}
var_dump($upcomingRelease);$php = [
'php-82' => ['state' => 'security', 'branch' => 'PHP-8.2'],
'php-83' => ['state' => 'active', 'branch' => 'PHP-8.3'],
'php-84' => ['state' => 'active', 'branch' => 'PHP-8.4'],
'php-85' => ['state' => 'upcoming', 'branch' => 'PHP-8.5'],
];
$upcomingRelease = array_first(
array_filter(
$php,
static fn($version) => $version['state'] === 'upcoming'
)
);
var_dump($upcomingRelease);
//array(2) {
// ["state"]=>
// string(8) "upcoming"
// ["branch"]=>
// string(7) "PHP-8.5"
//}final#[\Override] now works on properties#[\Deprecated] available for traits#[\DelayedTargetValidation] attribute is availableget_error_handler(), get_exception_handler() functions are available.Closure::getCurrent method is available.Dom\Element::getElementsByClassName() and Dom\Element::insertAdjacentHTML() methods are available.enchant_dict_remove_from_session() and enchant_dict_remove() functions are available.grapheme_levenshtein() function is available.opcache_is_script_cached_in_file_cache() function is available.ReflectionConstant::getFileName(), ReflectionConstant::getExtension(), ReflectionConstant::getExtensionName(), ReflectionConstant::getAttributes(), and ReflectionProperty::getMangledName() methods are available.final#[\Override] now works on properties#[\Deprecated] available for traits#[\DelayedTargetValidation] attribute is availableget_error_handler(), get_exception_handler() functions are available.