PHP 8.3 has just been released.

This is a point release that introduces a few new features, and deprecates some others ahead of removal in a future version.

  • There's a json_validate function, that allows checking if a string really is JSON without the overhead of actually trying to decode it.
  • Methods added to 8.2's Randomizer extension to cover a couple of use cases that are surprisingly hard to get right when doing them yourself (then again, a lot of things about random numbers are surprisingly hard to get right).
  • New methods for DOM and Date handling
  • str_increment and str_decrement functions that work the way ++ and -- are supposed to (which in turn have been reworked to have somewhat more sensible behaviour when people are being silly with them).
  • Some more flexibility introduced when cloning objects: in 8.2 it would balk at trying to clone readonly properties; now it will allow cloning and give you a chance to actually modify it. (Think of a property that should have a different value for each object, but remains fixed for the life of that object. How can you clone such an object?)
  • If you're storing the name of a class constant in a variable, it's easier to get at the constant value: Foo::{$bar}, instead of the more fragile approach of building strings and passing them to constant.
  • Meanwhile, you can add type declarations to constants, ensuring that if they're overridden by different values in inherited classes you can have a say about what type the new values should have
  • Static variable initializers can now contain arbitrary expressions.

On the deprecation side

  • Windows 7 support has been dropped.
  • as noted above, ++ and -- have changed in that they now complain when you try to use them on something you probably shouldn't (there are functions for if you've been using them on strings instead of numbers, and if you've been using them on something else you've been doing something VERY wrong)
  • The range function has had quite a bit of work done on it to close off weird behaviour in some edge cases, and it is a bit more strict in what it will allow
  • get_class expects to be passed an object now (if you're using it to get the name of the current class, self::class works for that).
  • There are changes to setting options for assertion handling as bits of the old evaled-string mechanism continue to be dismantled
  • More error messages have been migrated to exceptions, and some extensions (notably Date) throw more specific Exception types (so that you can focus, for example, on DateException errors).

That's only a taste of the full range of changes, which as ever can be perused at:
https://www.php.net/manual/en/migration83.php

4 days later

It's not mentioned at all in the release announcement, and is but a single line in the migration guide, but...

  • Static variable initializers can now contain arbitrary expressions.

In prior versions, you could not set a static variable to anything other than a manifestly constant expression. You could write static $size = 4+3; but you couldn't refer to other variables (even previous static ones) or break the calculation out into another function for reuse. Instead, you had to initialise the static variable with some bogus value (probably null), and then every time you enter the function, explicitly check to see if it has been initialised yet or not:

8.2:

static $statvar = null;
$statvar ??= initialise_statvar();

And in earlier versions that lacked ??= it got even uglier.

static $statvar = null;
$statvar = ($statvar === null) ? initialise_statvar() : $statvar;

It got even uglier still if you wanted to allow $statvar to be null in your function and had to use something else to indicate that it hadn't been initialised yet. And of course the check would be made every single time the function was called.

8.3:

static $statvar = initialise_statvar();

As for "arbitrary", it can refer to volatile functions and use function arguments. Once the static variable is initialised, the initialiser isn't run again.

function foo()
{
	return 42;
}

function bar($x)
{
	static $thing = foo() . " now at " . microtime() . " $x";
	return $thing;
}

echo bar(17), "\n";
sleep(3);
echo bar(19), "\n";

Note that both return values are the same even though $x is different and it's three seconds later.

    Write a Reply...