PHP 8.0 has been released on 26th November and come with a ton of new features and breaking changes. CyberPanel has added PHP 8.0 and all the currently available extensions. You can update your CyberPanel now and start testing your application to make it future proof.

PHP 8.0 is a major version which means it has been anticipated for years and it was under development for more than 2 years. This brings loads of changes to the type system, syntax, error handling, strings, object-oriented programming, and much more.

PHP 8.0 also introduces JIT ( Just in Time) compilation which makes it much easier and faster to run code that can be predicted.

So let's start discussing significant changes and new features.

New Features

Constructor property promotion

The new version allows you to define and assign variables right in the constructor instead of having to define first, ask or set them in the constructor's argument list and then assign the values.
So a typical PHP 7 or below class initialization code looks like this

class Point {
    public int $x;
    public int $y;
    public int $z;

    public function __construct(
        int $x = 0,
        int $y = 0,
        int $z = 0,
    ) {
        $this->x = $x;
        $this->y = $y;
        $this->z = $z;


With PHP 8 it can be shortened to this

class Point {
  public function __construct(
    public float $x = 0.0,
    public float $y = 0.0,
    public float $z = 0.0,
  ) {}


Named Arguments

Before PHP 8.0 we could pass parameter as arguments but they had to be in order that they were defined in the function ( positional arguments ) and there was no way that you could pass them along with the name of the argument, so you always had to make sure that they were in order and it made writing code a bit difficult and more time-consuming. It was an additional nuisance to check for declaration whenever you had to debug.
For example in PHP 7 and below a typical function and its call would look like this

function str_contains(string $haystack, string needle): bool {
//code to find the needle in the haystack
str_contains('FooBar', 'Foo');

But if you mistakenly send the "needle" first or if you function has many arguments and you missed one of them you would be in trouble however from PHP 8.0 you can send the name along the argument too.

function str_contains(string $haystack, string $needle): bool {
//code to find the needle in the haystack
str_contains(haystack: 'FooBar', needle: 'Foo');

You could also send the named arguments in different order and it would still work

function str_contains(string $haystack, string $needle): bool {
//code to find the needle in the haystack
str_contains(needle: 'Foo', haystack: 'FooBar');

As you can understand this could help make the code easier to write, understand and debug.

Null-safe Operator

We have all been there when we have to add a extra check to make sure something is present in the any object before calling a pointer or a nested pointer if we don't want a missing info resulting in a fatal error

PHP 8.0 adds a null safe operator to -> to provides safety in method/property chaining when the return value or property can be "null"

In PHP 7 and below we had to do something like this

$country =  null;

if ($session !== null) {
  $user = $session->user;

  if ($user !== null) {
    $address = $user->getAddress();
    if ($address !== null) {
      $country = $address->country;

With PHP 8 it can be done in a single line like this

return $user->getAddress()?->getCountry()?->isoCode;

The ?-> null-safe operator short-circuits the rest of the expression if it encounters a null value, and immediately returns null without causing any errors.


Atrributes or meta-data annotations are one of the biggest changes in PHP 8.0. Till this version PHPdoc was used to add comments, now we can attributes which can be fetched programmatically when declared using "use" keyword and reflection API

This can be done using << >> operators instead of using *@ method

Here is a complete example

use App\Annotations\FooAttribute;
use App\Annotations\ClassAttrib as FooClassAttrib;
use App\Annotations\FooParamAttrib;
use External\Attr\BarClassAttrib;

function foo_func(<<FooParamAttrib('Foo1')>> $foo) {}

class Foo {
    private const FOO_CONST = 28;
    private const BAR_CONST = 28;

    <<PropAttr(Foo::BAR_CONST, 'string')>>
    private string $foo;

    public function getFoo(<<FooClassAttrib(28)>>): string{}

JIT ( Just in time ) Compilation

JIT is arguably the biggest change that has been added to PHP 8. In a compiled language, the source code is converted to computer-readable code ahead of time. Interpreted languages, on the other hand, convert the source code as it's executed, which is much slower. PHP is an interpreted language, and there have been several tactics used to improve PHP performance in the past with the latest step is the addition of the JIT compiler in PHP 8.

The JIT compiler is a middle ground between compilation and interpretation. It will compile and cache some sections of code at runtime so that the compiled version can be used instead of the interpreted version. This could lead to huge performance gains for PHP, but with some caveats. Generally, JIT compilers mostly benefit CPU-intensive applications, such as 3D rendering or large mathematical computations. If you're using PHP for web applications, you may not see a substantial performance boost by enabling the JIT compiler.

PHP team has shared some results which show improvement in processing speed for synthetic benchmarks

However one of the developer says the following

 it currently doesn’t seem to significantly improve real-life apps like WordPress (with opcache.jit=1235 326 req/sec vs 315 req/sec).

It’s planned to provide additional effort, improving JIT for real-life apps, using profiling and speculative optimizations.”

So we might have to wait a few more version to see the results on web apps like WordPress or Laravel based apps.

throw as an expression

Prior to PHP 8.0, throw was a statement and it was not allowed to throw an exceptions in when a single expression is expected. It is now possible to throw an exception in arrow functions, ternary expressions, or anywhere else the PHP parser expects a single expression.

Arrow Functions:

$fn = fn() => throw new \Exception('oops');

Ternary expressions:

$value = isset($_GET['value'])
? $_GET['value']
: throw new \InvalidArgumentException('value not set');

$value ??= throw new \InvalidArgumentException('value not set');

$foo = $bar ?: throw new \InvalidArgumentException('$bar is falsy');

$foo = $bar ?? throw new \InvalidArgumentException('$bar is not set');

Match expression

Switch statement gets and elder more powerful sister called match. Its an expression so the results can be stored. Although it does strict comparison only.

So a switch statement like this in PHP 7

switch (8.0) {
  case '8.0':
    $result = "Oh no!";
  case 8.0:
    $result = "This is what I expected";
echo $result;
//> Oh no!

Can now be written as

echo match (8.0) {
  '8.0' => "Oh no!",
  8.0 => "This is what I expected",
//> This is what I expected

String functions

PHP 8.0 comes with better string search but its only string sensitive and save you from add !== to strops() function

Without this function, the usual way to find if a given string contains another string is to use to the strpos() function:

if (strpos('Foo Bar Baz', 'Bar') !== false) {
echo 'Found';

strpos() function returns the position of the needle string, or false if the needle is not found. This is error-prone, because if the needle is found at the position 0 of the haystack, it evaluates to false unless strict comparison (===) used.

To explain further, the following snippet is not correct:

if (strpos('Foo Bar Baz', 'Foo')) {
echo 'Found';

Because Foo is found at the beginning of the haystack, the return value of strpos() call will be 0, which evaluates to false, and the if block will not run.

With the new str_contains function, it is easy to do this:

if (strpos('Foo Bar Baz', 'Foo')) {
echo 'Found';

Similarly, two more string functions are added to check if the string begins or ends with another string

str_starts_with to determine if a string starts with another string and str_ends_with to determine if the string ends with another string

str_starts_with (string $haystack, string $needle): bool;
str_ends_with (string $haystack, string $needle): bool;

Deprecations and removals

Adding PHP 8 to Cyberpanel

Installing PHP 8 to Cyberpanel is simple and easy. Just run the upgrade command and it will be installed for you. In case you don't know how to update, please follow this guide

Still not using CyberPanel? Well, you are missing out a lot. CyberPanel provide 1-Click installers for all major server providers and a single command to install if you are using something else. So what are you waiting for?

Get Started Now 


In version 2.0.0, CyberPanel has added the option to add Redis Mass hosting with LiteSpeed Enterprise Edition (This feature works with Web Host Professional license or above.

What is Redis Mass Hosting?

Redis Mass hosting is a feature that caches and dynamically generates all the configurations on Redis backend. No web server restart is required when you create a new website or change the PHP version.

Why use Redis Mass Hosting

Without this feature, CyberPanel has to be restart whenever a new domain or a vHost is added, additionally change in PHP version for any vHost triggers a reboot too.

Redis Mass Hosting makes it very easy for large web hosts to manage their hosting companies or hosting servers. Addition or removal of vHost or change in PHP version won't affect any other site on the server.

How to Install

From version v2.0.0 onward, will be presented with an option to install Redis Mass hosting during installation if you are installing LiteSpeed Ent

During installation process, select 1 to install CyberPanel

Choose "Install CyberPanel with LiteSpeed Enterprise" by entering 2

Enter your LiteSpeed Ent key and you will be presented with an option to choose to install Redis Mass hosting or not. Answer with Y

That's all you have to do, after installation CyberPanel with automatically configure and attach Redis Dynamic vHosts to LiteSpeed.

CloudLinux and CageFS integration are available from CyberPanel v1.8.6. However, before using CageFS you need to be on CloudLinux OS. So before moving forward convert your CyberPanel server to CloudLinux and install CageFS.

What is CageFS?

From the official documentation:

CageFS is a virtualized, per-user file system that uniquely encapsulates each customer, preventing users from seeing each other and viewing sensitive information. CageFS prevents a large number of attacks, including most privilege escalation and information disclosure attacks. It is completely transparent to your customers, without any need for them to change their scripts.

So now when you create any website, you can enable CageFS on the website user, that user will then see a virtualized file system.

How to enable/disable CageFS for users?

In order to manage CageFS for individual users, log in to LVE manager by going to <IP_ADDRESS>:9000

Use your root credentials to log in, you CyberPanel administration credentials won't work.

When you are logged in you will see this


At the menu on the top, Click on Users where you will see all the list of users on the server


From this screen, you can enable or disable CageFS for any user by clicking the pencil icon in the end, the user's resource limits can be increased or decreased easily from same interface.



Click save after you have changed it to the values you like.

That's how you can easily manage CageFS for all your users.


Various configurations files are located at different places, there structure is defined below.




Virtual Hosts