What's new in PHP land? 2025.1

@brisphp1

https://brisphp.com

#BrisPHP

@brisphp1

https://brisphp.com

#BrisPHP

PHP 8.5: Closures in constant expressions

function my_array_filter(
    array $array,
    Closure $callback = static function ($item) { return !empty($item); },
) {
    $result = [];
 
    foreach ($array as $item) {
        if ($callback($item)) {
            $result[] = $item;
        }
    }
 
    return $result;
}

@brisphp1

https://brisphp.com

#BrisPHP

PHP 8.5: Closures in constant expressions

final class Locale
{
    #[Validator\Custom(static function (string $languageCode): bool {
        return \preg_match('/^[a-z][a-z]$/', $languageCode);
    })]
    public string $languageCode;
    
    // Also works with first class callables
    #[Validator\Custom(Locale::validateLanguageCode(...))]
    public string $languageCodeTwo;
    
    public static function validateLanguageCode(string $languageCode): bool 
    {
        return \preg_match('/^[a-z][a-z]$/', $languageCode);
    }
}

@brisphp1

https://brisphp.com

#BrisPHP

PHP 8.5: array_first() & array_last()

$array = [1 => 'a', 0 => 'b', 3 => 'c', 2 => 'd']

array_first($array); // 'a'
array_last($array); // 'd'

// functionally the same as
$array[array_key_first($array)]; // 'a'
$array[array_key_last($array)]; // 'd'

@brisphp1

https://brisphp.com

#BrisPHP

PHP 8.5: Fatal error backtraces

set_time_limit(1);
 
function recurse() {
    usleep(100000);
    recurse();
}
 
recurse();
Fatal error: Maximum execution time of 1 second exceeded in example.php on line 7

@brisphp1

https://brisphp.com

#BrisPHP

PHP 8.5: Fatal error backtraces

Fatal error: Maximum execution time of 1 second exceeded in example.php on line 6
Stack trace:
#0 example.php(6): usleep(100000)
#1 example.php(7): recurse()
#2 example.php(7): recurse()
#3 example.php(7): recurse()
#4 example.php(7): recurse()
#5 example.php(7): recurse()
#6 example.php(7): recurse()
#7 example.php(7): recurse()
#8 example.php(7): recurse()
#9 example.php(7): recurse()
#10 example.php(10): recurse()
#11 {main}

@brisphp1

https://brisphp.com

#BrisPHP

PHP 8.5: Mark return values as important

#[\NoDiscard("as processing might fail for individual items")]
function bulk_process(array $items): array {
	$results = [];
 
	foreach ($items as $key => $item) {
		// Do some processing, maybe it succeeds, maybe it fails
        // $result contains the the success/failure
 
		$results[$key] = $result;
	}
 
	return $results;
}
 
$items = [ 'foo', 'bar', 'baz' ];
 
// E_USER_WARNING: as processing might fail for individual items in test.php
bulk_process($items);
 
// No warning, because the return value is consumed by the assignment.
$results = bulk_process($items);

@brisphp1

https://brisphp.com

#BrisPHP

PHP 8.5: Attributes on constants

// This is okay
#[\MyAttribute]
const Example1 = 1;
 
// This is an error
#[\MyAttribute]
const Example2 = 2,
    Example3 = 3;

@brisphp1

https://brisphp.com

#BrisPHP

PHP 8.5: Asymmetric visibility for static prop

class Example
{
    public private(set) static string $classTitle = 'Example class';
 
    // Implicitly public-read, just like object properties.
    protected(set) static int $counter = 0;
 
    public static function changeName(string $name): void
    {
        // From private scope, so this is allowed.
        self::$classTitle = $name;
    }
}
 
print Example::$classTitle; // Allowed.
 
Example::$classTitle = 'Nope'; // Disallowed.

Questions?

@brisphp1

https://brisphp.com

#BrisPHP

What's new in PHP land

By Nathan Dench

What's new in PHP land

  • 146