DEV Community

spO0q
spO0q

Posted on • Edited on

Why PHP 8 will be awesome

PHP 8 will be available very soon. It's a major version with breaking changes, but also with excellent features.

Disclaimer

It's a personal selection, not an exhausting list.

Small details but great features

Again, it's not an exhaustive list, but some changes will be handy for our daily PHP routines.

::class available for objects

Instead of calling an intermediary get_class() on objects, you will be able to do that directly:

$myObject = new MyClass();
var_dump($myObject::class);
Enter fullscreen mode Exit fullscreen mode

Source

Trailing commas for parameters

In PHP 7, you can add trailing commas in arrays like that:

$myArray = [ "pull", "push", "jump",];
Enter fullscreen mode Exit fullscreen mode

But you cannot do this with function and method parameters. In PHP8, you can!

new Uri(
    $scheme,
    $user,
    $pass,
    $host,
    $port,
    $path,
    $query,
    $fragment, // <-- Huh, this is allowed!
);
Enter fullscreen mode Exit fullscreen mode

Source

str_* new magic

I read about str_contains, str_starts_with() or str_ends_with() in rfc. Simpler, better, stronger than strpos or any regular expression.

Break things for the win

PHP 8 will throw many more errors by default than PHP 7. Everything deprecated before PHP 8 has been removed!

The @ operator

This dark lord of PHP operators will no longer silence fatal errors!!!

Prepare for battle

Fatal error for static calls of non-static methods

The following code already triggers some errors, but in PHP 8, it will raise a fatal error!

class MyClass {
    public function myMethod() {}
}
MyClass::myMethod();
Enter fullscreen mode Exit fullscreen mode

New default error reporting level

E_ALL will be the default value. Again, no more silenced errors.

Don't mess with undefined!

PHP 8 will convert many warnings and notices into errors, for example:

  • undefined variables
  • division by zero

The JIT disclaimer

It's not possible to write any post about PHP 8 without celebrating the JIT birth \0/.

The Just In Time compilation should improve performances, somehow. Before PHP 8, PHP executes code by converting PHP code into instructions (~ opcodes) that the virtual machine runs.

The JIT compiler converts PHP code into x86 machine code, which runs directly on the CPU.

However, as Nikita Popov said, it will be significant for code that involves mathematical calculations, not the average code.

Do not expect the same wow effect as with migrations from PHP 5 to PHP 7.

Killer features

Some features will be decisive.

Union types

Before PHP 8, union types were possible only in phpdoc:

/**
* @var int|float $number
*/
private $number;
Enter fullscreen mode Exit fullscreen mode

With PHP 8, you will write:

private int|float $number
Enter fullscreen mode Exit fullscreen mode

The idea is to move more type information from phpdoc into function signatures. Void won't be available in union types, though, but it would not make sense anyway.

Source

static return type

It will follow the same purpose as the static keyword. Your method should return something from the current (~ child) class, not the parent class.

class MyClass { 
    public function myMethod(): static { 
        return new static(); 
    } 
}
Enter fullscreen mode Exit fullscreen mode

Awesome!

Throw as expression

Moving Throw from statement to expression will allow the following usage in PHP 8:

$condition || throw new Exception();
Enter fullscreen mode Exit fullscreen mode

Source

Love the idea of using Throw in arrow functions or ternaries.

Conclusion

PHP 8 is better, faster, stronger. Can't wait to use it. It looks like the first step toward making PHP a type-safe programming language.

Top comments (15)

Collapse
 
_garybell profile image
Gary Bell

I really need to spend more time looking into how PHP 8 and the end of maintenance for PHP 7.4 next year is going to affect me.

There's a lot to be excited about, and great improvement being made. But I worry that the pace of updates, removal of deprecated features, and smaller maintenance windows will make PHP a less viable choice for organisations going forward.

Writing something from the ground up which takes even 12 months means by the time it's live, the version it was written on only has 12 month's maintenance and then 12 month's security fixes before some features may be obsolete by the language.

If there's a reliance on external components (anything via composer), then there's a lot of dependencies which may break or be otherwise unsupported.

We certainly don't want to go back to the days of PHP 5.6 and the glacial pace of updates. But the current pace may be too fast, and be seen as unstable. Especially seeing as there's still a lot of PHP 5 applications out there refusing to die, and still being supported by some people.

Collapse
 
spo0q profile image
spO0q

you have a point, we are dealing with a momentum in release cycle and removals. Honestly, I don't know what the future holds, but I do appreciate this huge effort on types.

Collapse
 
_garybell profile image
Gary Bell

Part of me thinks PHP 8 will be more or less 7.4 with all the deprecated stuff gone, and a few new bits. If so, then I'm all for it.

Initially I was sceptical about the E_ALL errors by default, but it should force developers to be better. Production servers will have templates configurations through Ansible or similar, so I'm not worried there.

Thread Thread
 
spo0q profile image
spO0q • Edited

Nikita Popov said that in his experience moving from 7.4 to 8 should be fine. I agree with you, silencing errors by default is not a good thing, so it's a nice evolution.

Collapse
 
ecrider profile image
Kuba Paczyński • Edited

I am not sure what to think about some of those changes, most likely I will quickly learn to love all of them except one - @ operator removal is unreasonable. I am completely serious about it.

I mean I get it, I can easily understand why using @ operator is a bad practice in predictable environments where absolutely nothing can go wrong... and by predictable environments I mean of course Apache/Nginx mods, PHP-FPM... Web in general.

I wonder if someone there forgot that PHP is a GENERAL-PURPOSE language and there are people, myself included, using it to build applications outside the realm of... Apache/Nginx mods, PHP-FPM... Yeah, web in general.

PHP 7 was huge for me, in my opinion for the first time in history it made PHP a viable option for something other than processing web templates, all of a sudden you could actually start using it for general-purpose and people didn't look at you like you were out of your mind.

So, why I make such a big deal about some silencer? Well, when you start to operate outside of (mentioned twice already) predictable environments and have to deal with completely unpredictable outcomes on daily basis you very quickly find out that some warnings and errors are unavoidable, but also that they do not always represent mistakes in your code or design, or even something that can or should be fixed. Lets be realistic - if something is bound to fail, crash and burn in one case of a thousand no matter what you do, and it doesn't actually crash and burn because you were wise enough to put that little @ in there... And you didn't actually "silenced" it because you actually bother to check if it failed or not... Am I the only one seeing it?

Silencing whatever I want, whenever I feel like it? Put a SINGLE-CHARACTER shut-op on extremely rare but unavoidable trouble maker and carry on? Sooo useful, sooo good, sooo nice and also... blazing fast. I mean I ran actual tests to see how it looks when compared to try {} catch {} "alternative". Putting aside how awful it looks in tight spots in code and how unpractical it is when trying to achieve exactly the same effect as with beloved SINGLE-CHARACTER, elegant @ shut-op - its so slow it can create a bottlenecks in certain spots. I mean it - don't ever try {} catch {} stream_select()/socket_select(), blocking or not, even when used with small number of sockets to track with almost no traffic on them. What happens when you put @ operator? It's like it wasn't even there. It works so well I actually never even bothered to check what makes it that efficient, and why would I?

Whatever genius came out with shut-op removal idea - where is he? Where are you mister master? Good sir? Could you please help me kind sir? Silly me, I got a little teensy-weensy confused here and I would be very grateful if you be so kind and generous to spare a moment of your precious time to help me discover how to properly handle scenarios without that diabolic evil @ operator - and there are many scenarios, and they vary...

Here is stupid little example - lets say I have daemonised long-running process, my process is handling couple signals, signals INTERRUPT all blocking operations, most blocking operations when interrupted will immediately litter my logs with useless warnings (interruption of blocking operations at signal arrival is EXPECTED BEHAVIOUR, why they even generate those warnings?!) but lets assume for a second that it doesn't bother me and I can live with that (in reality I don't) - some of them will not be so nice and instead of a warning will throw and error and flip entire process, how am I supposed to prevent it?

It this scenario there are only 3 things to keep in mind:

  1. I don't want to put signal block mask before error-throwing troublemakers because its anti-pattern and it's beneficial for them to be immediately interrupted as signal needs to be handled ASAP.
  2. I will not use try {} catch {} because it will create bottlenecks all over (also they are ugly af).
  3. I still want everything else to throw an error when there is an actual error, because otherwise I wouldn't be able debug anything .

Let's hear it. I have like a dozen more complex scenarios at the top of my head - if that's what it takes to keep my little friend @ in this bug 8, then I can put them all inside some email and send that email whenever it needs to be sent. How about bribes?

Collapse
 
spo0q profile image
spO0q

IMHO, @ is a terrible operator. Suppressing errors to make them go away is not something I would recommend in any case.

Collapse
 
ecrider profile image
Kuba Paczyński • Edited

What's the alternative then? If you don't suppress error you were not supposed to receive and cannot fix, then your process will crash when it's not supposed to.

Sorry, but PHP cannot have it both ways and still be described as reliable general-purpose language. It either has to provide stable, consistent behaviour and compliance with standards across all its core extensions OR provide developers with reliable tool to countermeasure.

PHP 7.4 provides reliable tool to countermeasure when core extension is acting out - that makes it a reliable, you can work with it, you can build things without taking personal risks to your career.

So far the only thing certain about PHP 8 is that it removes the tool to countermeasure that was needed in previous versions. What I would expect as a solution would be some kind of reassurance like "we are removing @ shut-op, but we also fixed the reason you needed it in the first place".

Thread Thread
 
spo0q profile image
spO0q • Edited

See the big picture. This operator creates more problems than it solves.

display_errors off and logs seems a better choice.

Collapse
 
kirkhilles profile image
kirkhilles

I'm a software developer by trade, but I'm NOT an Engineer. My interest is to have code that's simple, easy to follow, easy to maintain and efficient. I -detest- the word "elegant". If my code were a car, it'd be a Honda. Simple. Bulletproof. Effective. Reliable. Too many programmers want to over-engineer. The complexity of code is their pride. Their code is like a BMW. When it works, it's very nice but after awhile you just throw it away because it's a mess to work on.

So, in terms of the "@" sign, I understand the arguments. I get how some people might be excited about it going away. But to me, it's very effective to use in the REAL WORLD. I use this code all day long:

$sVar = @$_REQUEST["sVar"];

It allows me the ideal situation of having just that one clean line and then I can check to see if sVar has a value throughout the code. Why do I need to check to see if it exists first? Why is this code considered "better"?

$sValue = "";
if (isset($_REQUEST["sVar"])) $sValue = $_REQUEST["sVar"];

The original code is cleaner, easier to read and provides the exact same results as the second without you having to specify "$_REQUEST" 2x and "$sValue" 2x.

I get it and I know that I'm "wrong", but it drives me nuts when there are "breaking" changes in a version. That's just not a philosophy I agree with. I understand why it went "mysql_query($sql, $conn)" to "mysqli_query($conn, $sql)" and how i I deally you'd have everything separated into separate functions and only have to update it once, but in the REAL WORLD sometimes that doesn't happen that way and you have to go and update thousands of references because a PHP architect decided a philosophy change was needed. Why do things have to be depreciated?

Again, I don't need to be told why "I'm wrong". I'm interested in the end solution and not with the latest and greatest coding design and from my perspective, the end justifies the means. If it were up to me, I would design all future versions of a language where the latest builds still work with coding from version 1.x.

Anyway, end of rant LOL.

Collapse
 
spo0q profile image
spO0q

maybe you can use the syntactic sugar $var = $_REQUEST["sVar"] ?? ""; instead.

Breaking changes are something to consider as a last resort, but sometimes it makes sense.

Collapse
 
joeczubiak profile image
Joe Czubiak

Thanks for summarizing some of the changes we can look forward to!

Collapse
 
madza profile image
Madza

They did step up the game by a mile with 7x, too 👍😉

Collapse
 
spo0q profile image
spO0q

that's true ;) it seems PHP 8 is a momentum, though

Collapse
 
lamka02sk profile image
lamka02sk

All these are nothing compared to attributes.

Collapse
 
spo0q profile image
spO0q

I will write about them, but in another article, it deserves en entire post IMHO