Tim Bond

MergePHP - November 14, 2024

Date Milestone
Jul 04 2024 Alpha 1
Jul 18 2024 Alpha 2
Aug 01 2024 Alpha 3 (skipped)
Aug 01 2024 Alpha 4
Aug 13 2024 Feature freeze
Aug 15 2024 Beta 1 (skipped)
Aug 15 2024 Beta 2 (skipped)
Aug 15 2024 Beta 3
Aug 29 2024 Beta 4
Sep 12 2024 Beta 5
Sep 26 2024 RC 1
Oct 10 2024 RC 2
Oct 24 2024 RC 3
Nov 07 2024 RC 4 👈
Nov 21 2024 GA

new MyClass()->method() without parentheses

// < 8.4
echo (new DateTimeImmutable())->getTimestamp();

// 8.4
echo new DateTimeImmutable()->getTimestamp();

https://wiki.php.net/rfc/new_without_parentheses

New array_*() functions

$animal = array_find(
    ['dog', 'cat', 'cow', 'duck', 'goose'],
    static function (string $value) {
        return str_starts_with($value, 'c');
    }
);

var_dump($animal); // string(3) "array_find"

https://wiki.php.net/rfc/array_find

  • array_find
    • Returns the first element satisfying a callback function
  • array_find_key
    • Returns the key of the first element satisfying a callback function
  • array_any
    • Checks if at least one array element satisfies a callback function
  • array_all
    • Checks if all array elements satisfy a callback function

New array_*() functions

Asymmetric Visibility

class PhpVersion
{
    public private(set) string $version = '8.4';
}

$phpVersion = new PhpVersion();
var_dump($phpVersion->version); // string(3) "8.4"
$phpVersion->version = 'PHP 8.3'; // Visibility error

https://wiki.php.net/rfc/asymmetric-visibility-v2

class PhpVersion
{
    public string $version = '8.3';
}

$phpVersion = new PhpVersion();
var_dump($phpVersion->version); // string(3) "8.3"
$phpVersion->version = 'PHP 8.4'; // No error

Deprecated Attribute

/**
* @deprecated 8.3 use get_bar() instead
*/
function get_foo() {
	return 'foo';
}

$value = get_foo();
// No indication that the method is deprecated

https://wiki.php.net/rfc/deprecated_attribute

#[\Deprecated(
	message: "use get_bar() instead",
	since: "8.4"
)]
function get_foo() {
	return 'foo';
}

$value = get_foo();
// Deprecated: Method get_foo() is deprecated
// since 8.4, use get_bar() instead

Property Hooks

class Locale
{
    public string $languageCode;

    public string $countryCode {
        set (string $countryCode) {
            $this->countryCode = strtoupper($countryCode);
        }
    }

    public string $combinedCode {
        get => \sprintf("%s_%s", $this->languageCode, $this->countryCode);
        set (string $value) {
            [$this->countryCode, $this->languageCode] = explode('_', $value, 2);
        }
    }

    public function __construct(string $languageCode, string $countryCode) {
        $this->languageCode = $languageCode;
        $this->countryCode = $countryCode;
    }
}

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->countryCode); // BR
var_dump($brazilianPortuguese->combinedCode); // pt_BR

https://wiki.php.net/rfc/property-hooks

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->countryCode); // BR
var_dump($brazilianPortuguese->combinedCode); // pt_BR

Deprecated Implicit nullable types

function save(Book $book = null) {}

// Deprecated: Implicitly marking parameter $book as
// nullable is deprecated, the explicit nullable type
// must be used instead

function save(?Book $book = null) {}

https://wiki.php.net/rfc/deprecate-implicitly-nullable-types

PDO Driver specific SQL parsers

<?php
$connection = new PDO(
    'mysql:host=localhost;dbname=test',
    $username,
    $password,
);
// in 8.4: object(Pdo\Mysql)
// previously: object(PDO)

$connection->sqliteCreateFunction(
    'append_php',
    static fn($string) => 'PHP ' . $string
); // Fatal

https://wiki.php.net/rfc/pdo_driver_specific_parsers

Lazy Objects

<?php
$initializer = static function (MyClass $proxy): MyClass {
    return new MyClass(123);
};
 
$reflector = new ReflectionClass(MyClass::class);
$object = $reflector->newLazyProxy($initializer);

https://wiki.php.net/rfc/lazy-objects

Deprecated: _ as a class name

class _ {
}

exit() behavioral change

https://wiki.php.net/rfc/exit-as-function

  • The exit() (and die()) language constructs now behave more like a function
  • Can now be passed like callables
  • Are affected by the strict_types declare statement
  • Perform the type coercions (instead of casting any non-integer value to a string)
  • Passing invalid types (not int or string) to now result in a TypeError

New bcmath functions

https://wiki.php.net/rfc/adding_bcround_bcfloor_bcceil_to_bcmath

  • bcceil()
  • bcdivmod()
  • bcfloor()
  • bcround()

New mb_ functions

https://wiki.php.net/rfc/mb_trim

  • mb_trim()
  • mb_ltrim()
  • mb_rtrim()
  • mb_ucfirst()
  • mb_lcfirst()

New XML functions

  •  XMLReader::fromStream()
  • XMLReader::fromUri()
  • XMLReader::fromString()
  • XMLWriter::toStream()
  • XMLWriter::toUri()
  • XMLWriter::toMemory()

New header functions

  • http_get_last_response_headers()
  • http_clear_last_response_headers()

New request_parse_body() function

// On a a PUT request
var_dump($_POST);  // []
var_dump($_FILES); // []

https://wiki.php.net/rfc/rfc1867-non-post

function request_parse_body(?array $options = null): array {}

// usage:
[$_POST, $_FILES] = request_parse_body();

// options:
// max_file_uploads
// max_input_vars
// max_multipart_body_parts
// post_max_size
// upload_max_filesize

PHP 8.4 security support until 31 Dec 2028

Release Cycle Update

https://wiki.php.net/rfc/release_cycle_update

  • Allow features that do not require an RFC in the beta period
  • Disallow new features in release candidates and bug fix releases
  • Reduce number of RCs to four (was six)
  • Extend security support by one year
  • Allowing recent regression fixes during security support

How can I play with it now?

  • Easy: docker container run --rm php:8.4.0RC3-cli php -i
  • Medium:
    • POSIX
      docker container run --rm -v $(pwd):/app/ php:8.4.0RC3-cli php /app/script.php
    • Windows - cmd

      docker container run --rm -v %cd%:/app/ php:8.4.0RC3-cli php /app/script.php
    • Windows - PowerShell

      docker container run --rm -v ${PWD}:/app/ php:8.4.0RC3-cli php /app/script.php
  • Hard: FROM php:8.4.0RC3-...