message

PHP 8.2 Is Now Stable and Available on SiteGround Servers

PHP 8.2 Is Now Stable and Available on SiteGround Servers

Table of Contents

UPDATE

We’re happy to announce that PHP 8.2 is now considered stable and has been deployed on all SiteGround servers. Once again, we’re among the first companies to already have it available on our hosting platform. Read the blog post below to find out more about the new features of the latest PHP version.

It’s that time again! Time for the Santa ElePHPant to visit all the good little PHP developers around the world and shower them with new goodies that make it easier for them to build the web.

As of this writing, PHP 8.2 is in Release Candidate 1 (RC1) status. We are in the late stages of development and bug fixing for this version and you can tell because forward looking web hosts like SiteGround are now making the RC builds available for their clients to test with. (Did you see the word TEST there? For those who don’t know what that means, it means NOT IN PRODUCTION!)

So let’s take a look at some of the new presents that Santa ElePHPant is bringing us.

New Goodies

First up, let’s take a look at a few of the new features that will be of interest to PHP developers. This is not an exhaustive list of the new goodies in Santa ElePHPant’s bag. It’s more a short list of the things I think the majority of PHP developers will be interested in.

readonly classes

In PHP 8.1 we got readonly properties for classes. This was a great leap forward for a lot of projects. However, there is still a small hole that needed to be plugged, clases. Yes, you can make every typed property in a class as read only and you are good to go, but honestly, that’s a lot of typing and if we know anything, we know that developers are lazy. So instead, in PHP 8.2 we can mark an entire class as readonly.

readonly class MyClass {
    public int $myProp;
    public string $myOtherProp;
    public __construct(string $myOtherProp, int $myProp) 
    {
        $this->myProp = $myProp;
        $this->myOtherProp = $myOtherProp;
    }
}

Here we have a class defined as readonly. We have 2 properties of the class and both of them are inherently readonly. The readonly rules from PHP 8.1 still apply. You can initialize the property only once, after that it is set. 

$myObj = new MyClass(‘Cal was here’,42);

However, once they are initialized, they are now immutable.

$myObj->myProp = ‘Cal is no longer here’;

// Fatal Error: Uncaught Error: Cannot modify readonly property MyClass::myProp

One other behavior of the readonly class is that properties cannot be dynamically added to the class, ever. Below we talk about deprecating Dynamic properties and how that’s a good thing. There is even an annotation that allows you to override this. However, if you mark a class as readonly, then it cannot be overridden.

Constants in Traits

Traits have been with us in PHP since PHP 5.4. They have long been the language’s answer to “composition over inheritance”. Now traits are getting an interesting new feature, the ability to define constants in a trait.

trait MyTrait {

    private const MY_CONSTANT = 42;

}

Now, if your trait uses a constant, you can define it in the trait and not have to remember to define it in each class that uses the trait.

trait MyTrait {

    private const MY_CONSTANT = 42;

    public function meaningOfLife() : int

    {

        return self::MY_CONSTANT;

    }

}

class MyClass {

    use MyTrait;

}

$myObj = new MyClass();

echo $myObj->meaningOfLife(); // prints 42

Like everything in life, there are a few rules.

Traits can define class constants. If a class uses that trait it can also define the same class constant as long as both the visibility and value are exactly the same. So the example above works but the one below will trigger a fatal error

trait MyTrait {

    private const MY_CONSTANT = 42;

    public function meaningOfLife() : int

    {

        return self::MY_CONSTANT;

    }

}

class MyClass {

    use MyTrait;

    public const MY_CONSTANT = 42;

}

Still, even with the rules that you have to follow, this is a real step forward. Traits are a great way to share code between classes and now they are even more self-contained.

Random Extension 5.x + Random Extension Improvement

The original PHP random number generator is still in the base code. It’s never been great and it’s absolutely useless for cryptographic uses. In PHP 7, we got a couple new functions, random_int() and random_bytes(). They went a long way to fix the problems but under the hood, they are just interfaces to the native OS’s random number generator. At the time this was a good solution but the problem is it’s a slow one. 

Now with PHP 8.2 we get not only an entirely new Random number generator, it is built into PHP,  and we get an extensible object oriented interface to it.

This is actually two different RFCs that I’m lumping together. After the first one “Random Extension 5.x” was voted on and passed, it was discovered that there was a few issues with it. A second RFC, “Random Extension Improvement”,  was prepared and voted on to fix the issues found with the first one.

The end result is a new set of classes that give us better pseudo-random numbers in PHP.

While we are actually getting several new random number generators (RNG), for simplicity I’ll discuss the new RandomEngineSecure class.

$engine = new RandomEngineSecure();

$randomString = $engine->generate(); // a random binary string

echo bin2hex($randomString); 

Now if we want to do something like sort an array, we need one of the new Randomizer objects. 

$randomizer = new RandomRandomizer($engine);

$items = range(1, 10);

$randomizedItems = $randomizer->shuffleArray($items);

print_r($randomizedItems);

Now in the above example, we used the Secure engine. The secure engine does not accept a seed and will always generate a non-reproducible string. The engines that allow you to specify a seed will produce the same results each time if you use the same seed. 

The Randomizer class also provides several other methods that are really what PHP developers are looking for.

  • getInt() : int
    This replaces the old mt_rand() function
  • getInt(int $min, int $max) : int
    This replaces both the old mt_rand() function as well as the newer random_int() function.
  • getBytes(int length): string
    This replaces the random_bytes() function 
  • shuffleArray(array $array): array
    This replaces the old shuffle_array() function
  • shuffleString(string $string): string
    This replaces the old str_shuffle() function

Among other things, since this brings all of the randomizing functionality into a single area of the engine, it streamlines the core code and will make further improvements easier.

“So long and thanks for all the fish”

All good things must come to an end and that includes some features and commands of PHP. Let’s look at a couple of the important deprecations that if you aren’t careful will end up causing you problems.

Deprecate dynamic properties

At first blush, this one seems like it’s going to be a huge problem. Since PHP got the current object model, it’s been possible to add properties to an object any time you want. Now somebody thinks this behavior is a bad thing. (HINT: It was always a bad thing but one a lot of developers took advantage of.)

class MyClass {

    public string $name;

}

$myObj = new MyClass():

$myObj->nmae = ‘Cal Evans’;

Notice that I misspelled the property name. I know I’m probably the only developer who has misspelled a property name but in PHP when it happens, I get a new property on the object and the original property remains unchanged. That was not my intent.

Starting with PHP 8.2, this will emit a DEPRECATED WARNING.

There are 3 exceptions to this new rule.

  1. Any instance of StdClass will still be able to accept dynamic properties.
  2. Any class with magic __get() and __set() methods will still accept any property.
  3. Any class that has the compiler annotation #[AllowDynamicProperties] and any child class will allow dynamic properties to be set.

So while all is not lost for those that depend on this “feature” of PHP, if you are still going to use it, you are going to have to make some changes to your code. 

The good news is that all that will happen right now is the warning emitted to the log files. So while it might fill up your log files reminding you that you need to fix this, PHP 8.2 won’t break your code. That happens in PHP 9.0 when the warning – and the ability to automatically add dynamic properties – gets removed from PHP.

(Partial) Deprecate ${} string interpolation

This is another depreciation that on the surface I thought was going to be a huge deal. Turns out, it is probably not going to affect many developers.

There are 4 ways to implement the “{$variableName}” syntax, 2 that make sense, and two that don’t. The two that don’t are going away.

echo “$meaningOfLife”;

By far, this is the most common version of string interpolation. Just put the variable in a string with double quotes. If you are doing this, you are fine, this is one of the two ways that are staying.

echo “{$meaningOfLife}”;

echo “{$dogulasAdams->meaningOfLife()}”;

I always considered this way “old-skool”. Yeah, we used to do it way back in the day but I’ve not done it this way in a long time. Still this works, it’s clean, and it’s easy to understand. This is the other one that is staying.

This is also the only method that allows you to use object properties and methods. So if you want to use string interpolation with an object, you will need this method.

echo “${meaningOfLife}”;

This one is going away. Yes, it does the same thing as the first two, but it is a little more confusing because the $ is outside of the braces. 

$fourtyTwo = 42;

$meaningOfLife = ‘fourtyTwo’;

echo “${meaningOfLife}”;

Finally, we have the way that you can use “variable variables” from within string interpolation. This is just too many levels of indirection. In the code above, we eventually get to the point where we echo out 42, but we take the long way around. 

Starting in PHP 8.2, the last two structures will emit a DEPRECATION WARNING in your log files. In PHP 9.0, they will stop working altogether and cause your program to crash. (or throw an Error that you can catch, but probably can’t recover from.

Wrap Up

This is the first PHP 8.2 Release Candidate. Don’t play with it on any production site. If you want to test it with an existing site, set up a new site for testing, clone your production site into it, and play with that. When you are done, you can just delete it. 

As you poke around in your new testing environment, check your log files after every test. Make sure nothing fails and see if any new WARNINGS pop up. 

If PHP 8.2 is anything like PHP 8.0 and PHP 8.1, I don’t expect modern PHP code to have issues with it. Thankfully, Santa ElePHPant’s Elves that work for SiteGround make it incredibly easy for you to test things out to make sure your site can run as fast as possible with PHP 8.2

Speaking of performance, PHP 8.2 hasn’t been properly benchmarked yet, but we have come to expect every version of PHP to be a little faster than previous versions. With changes to the CSPRNG system and other things like removing the old libmysql, it’s a safe bet that this version will be faster than PHP 8.1.

While you are testing, cloning, and observing results, make sure you take time to tweet out a huge THANK YOU to Santa ELePHPant and all of the little ElePHPant Elves that made this release possible. Rumor has it that they keep an eye on twitter.com/@php_net

To celebrate the latest release candidate PHP 8.2, we are giving away 5 exclusive SiteGround PHP elephant plush toys (a.k.a Groundy) in a raffle, running from September 8, 2022 until September 11, 2022. Read more on Twitter.

Related Articles

Back to top button