What's new in PHP 8 : The Upcoming Version of PHP and The Inclusion of JIT
PHP 8.0 is currently being discussed and developed.
As we know that PHP7 is awesome, it has huge improvements over PHP5, either we talk in terms of speed or performance. Also, it brought us the much-awaited scalar type hints for better user experience.
However, it would not be wrong to say that no language is perfect and requires to be updated now and then. So, when it comes to PHP 8, users' expectations are very high. Well, the one place where everyone loves to see PHP8 go is into more real-time features. That's because this feature will help not to use other languages in one PHP project only for the sake of real-time.
Due to the real-time era, the internet is transitioning to real-time. And, therefore, even users want their content fast. Few languages already have something for real-time purposes like JavaScript has Node.js, Python has Tornado, but PHP still doesn't have anything. So, as per the announcement, we can suppose that PHP has evolved, and the next major legs are PHP 8.0.0 and the JIT (Just-in-Time) compilation.
When will PHP 8.0 be released?
PHP 8.0 will be released on December 2020. At least this is where the official schedule is pointing to.
Accepted features for PHP 8.0
Features listed below will be delivered within PHP 8.0's release. They were already voted, accepted AND implemented.
So if you want to have a taste of this version, check this section out:
JIT: Just in Time Compiler
- Status: Confirmed.
- Category: Performance.
This feature claims to be more than four times faster on Mandelbrot benchmark and should cause big impacts on CPU-bound operations.
You can check the full spec by visiting the RFC page.
Union Types V2
- Status: Confirmed.
- Category: Syntax.
- Votes: 61 yes. 5 no.
The Union Types V2 RFC will allow every type definition to explicitly tell what possibilities are accepted, instead of trusting the good old mixed.
New syntax will look like the following:
function myFunction(int|float $number): int
{
return round($number);
}
The WeakMap class
- Status: Confirmed.
- Category: Standard Library.
- Votes: 25 yes. 0 no.
The WeakMap class RFC creates a new class called WeakMap
which looks a bit like SplObjectStorage
.
The main idea is that you can create a object -> value
map in it, without preventing this object from being garbage collected. Thus the Weak
name, stating there's a weak reference between the key object and the map itself.
Garbage collecting an object used as key in such map will cause its removal, meaning the value will be removed. Like the following:
$map = new WeakMap();
$obj = new DateTime('today');
$map[$obj] = 100;
// Shows one key
var_dump($map);
// Remove $obj from memory
unset($obj);
// WeakMap is now empty
var_dump($map);
Edit (2020.01.20): if you want to give it a try, there's already a polyfill implementation that works with PHP 7.4; It is called BenMorel/weakmap-polyfill.
TypeError exceptions will be thrown on parameter parsing failures
- Status: Confirmed.
- Category: Standard Library.
- Votes: 50 yes. 2 no.
Whenever you cause a type error on user-defined functions, it will throw an exception. For internal functions, though, PHP shows a warning and returns null by default.
The consistent TypeError RFC makes both behaviours consistent, by throwing TypeError exceptions in both cases.
Implicit array keys will be more consistent
- Status: Confirmed.
- Category: Standard Library.
- Votes: 17 yes. 2 no.
Whenever you use negative indexes on the array_fill
function, it will generate the first negative index and then jump to 0 (???). Like this:
$a = array_fill(-2, 3, true);
var_dump($a);
// outputs
array(3) {
[-2] =>
bool(true)
[0] =>
bool(true)
[1] =>
bool(true)
}
So the Negative Array Index RFC aims to fix this behaviour by letting array_fill
properly step with negative indexes:
$a = array_fill(-2, 3, true);
var_dump($a);
// outputs
array(3) {
[-2] =>
bool(true)
[-1] =>
bool(true)
[0] =>
bool(true)
}
Fatal Error on wrongly typed inherited methods
- Status: Confirmed.
- Category: Standard Library.
- Votes: 39 yes. 3 no.
Whenever a class defines a method signature and its children attempt to overload such method (by changing its signature) a warning is thrown.
This RFC from Nikita Popov makes this behaviour to throw a Fatal Error whenever this overload is attempted.
Here's an example of buggy code on PHP 8:
class A
{
function x(int $a): int
{
// ...
}
}
class B extends A
{
// Notice the signature
// changed. Fatal Error here.
function x(float $a): float
{
// ...
}
}
DOM API upgrade to match latest standard version
- Status: Confirmed.
- Category: Standard Library.
- Votes: 37 yes. 0 no.
This RFC also requires a post by itself.
But basically it adds a couple of interfaces and classes to make ext/dom
API to match the current DOM standard which is constantly changing.
What MIGHT enter PHP 8.0 version?
There are a couple of RFCs still under discussion. They might be denied or accepted any time soon. There are many things related to the core of the language and its syntax.
Here goes the list:
Severity levels for errors messages fixed
- Status: Accepted. Pending Implementation.
- Category: Standard Library.
The severity error messages' levels RFC aims to make a revision on many core error handling features.
For example the widely known Invalid argument supplied for foreach()
might jump from Warning
to TypeError Exception
.
Allow ::class access on objects
- Status: Implemented. Under Discussion.
- Category: Syntax.
Basically Dynamic class names aren't allowed in compile time. So a code like the following raises a fatal error:
$a = new DateTime();
var_dump($a::class);
// PHP Fatal error: Dynamic
// class names are not allowed
// in compile-time
// ::class fetch in...
With this RFC it will be now possible.
Make static a valid return type, like self
- Status: Implemented. Under Discussion.
- Category: Syntax.
Just the way we can make self
a return type for functions, the static return RFC aims to make static
also an available return type.
This way functions like the following would be then correct:
class A
{
public function b(): static
{
return new static();
}
}
Consistent variables syntax
- Status: Implemented. Under Discussion.
- Category: Syntax.
This one is also about syntax and will change a couple of features.
I recommend you checking out the RFC for more details. Affected language features include:
- Interpolated and non-interpolated strings
- Constants and magic constants
- Constant dereferencability
- Class constant dereferencability
- Arbitrary expression support for new and instanceof
Optimize function/constants lookup
- Status: POC implemented. Under Discussion.
- Category: Syntax. Performance.
The RFC about function and constants lookup adds a new declare()
statement that prevents PHP from performing lookups on runtime.
Whenever you're in a namespaced code and tries to fetch a globally scoped function or constant without prefixing it with a backslash (\
), PHP will first try to find it on the current namespace and then bubble up to the global namespace.
By adding a disable_ambiguous_element_lookup=1
directive, PHP will directly go to the global namespace. Here's an example (from the RFC):
namespace MyNS;
declare(
strict_types=1,
disable_ambiguous_element_lookup=1
);
use function OtherNS\my_function;
use const OtherNS\OTHER_CONST;
if (
// function lookup!!
version_compare(
// constant lookup!!
PHP_VERSION,
'8.0.5'
) >= 0
) {
// ...
}
disable_ambiguous_element_lookup
was zero
on the above example, PHP would attempt to find MyNS\PHP_VERSION
and MyNS\version_compare
first, understand they don't exist (hopefully) and only then attempt the \PHP_VERSION
and \version_compare
.
When disable_ambiguous_element_lookup
equals one
, this extra lookup is no longer necessary and PHP will go directly to the global scope, fetching \PHP_VERSION
and \version_compare
.
Strict Operators directive
- Status: POC implemented. Under Discussion.
- Category: Syntax.
The strict operators RFC would add a new directive called strict_operators
. When switched on a couple of comparisons would then behave differently.
Here are some examples on how php would behave (from the RFC):
10 > 42; // false
3.14 < 42; // true
"foo" > "bar"; // TypeError("Unsupported type string for comparison")
"foo" > 10; // TypeError("Operator type mismatch string and int for comparison")
"foo" == "bar"; // false
"foo" == 10; // TypeError("Operator type mismatch string and int for comparison")
"foo" == null; // TypeError("Operator type mismatch string and null for comparison")
true > false; // true
true != 0; // TypeError("Operator type mismatch bool and int for comparison")
[10] > []; // TypeError("Unsupported type array for comparison")
[10] == []; // false
"120" > "99.9"; // TypeError("Unsupported type string for comparison")
(float)"120" > (float)"99.9"; // true
"100" == "1e1"; // false
(int)"100" == (int)"1e2"; // true
"120" <=> "99.9"; // TypeError("Unsupported type string for comparison")
Changes are much wider than this example and are out of the scope of this single post. Check the RFC for more, or ping me on twitter if you'd like to see a blog post about this one! ?
The RFCs below are still under discussion and most of them have something related to past versions of PHP, not being able to get released in time or something similar. I won't describe them in detail just yet, as I don't quite feel they have big changes to be integrated to the language.
I will, of course, follow up on them to make sure I'm hopefully wrong.
Here they are:
Auto Increment value on copy on write
- Status: Under Discussion.
- Category: Syntax.
This RFC was originally targeting PHP 7.4 but is still marked as Under Discussion. So I'd expect it to retarget PHP 8.0 this time.
Alternative "use" syntax on Closures
- Status: Under Discussion.
- Category: Syntax.
This RFC was originally targeting "the next minor version", which at that time would be php version 7.4.
Apply a declare() to an entire Namespace ?
- Status: Implemented. Under Discussion.
- Category: Syntax.
Permit trailing spaces on numeric strings
- Status: Implemented. Under Discussion.
- Category: Syntax.
This RFC also targeted version 7.4 and didn't make it in time.
Allow nullable type casting
- Status: Lost. Under Discussion.
- Category: Syntax.
Apparently the fork containing the Work In Progress for such change got deleted. And the Pull Request closed. Doesn't seem like it will ever be integrated unless someone take over this one.
Let’s begin with a brief introduction of PHP and its previous versions first to understand it better.
Introduction to PHP
PHP: Hypertext Preprocessor started as a small open source project that eventually evolved as more and more people found out how useful it was. Way back in 1994, Rasmus Lerdorf, a Danish-Canadian programmer, unleashed the first version of PHP. PHP, embedded in HTML, is a server-side scripting language which is very much popular now.
The language is used to manage dynamic content, session tracking, databases, and even build entire e-commerce sites. It is integrated with various popular databases, including MySQL, Oracle, PostgreSQL, Sybase, Microsoft SQL Server, and Informix.
PHP, especially when compiled as an Apache module on the Unix side, is pleasingly zippy in its execution. And, once the MySQL server starts, it executes highly complex queries with huge result sets in record-setting time.
Moreover, the language supports a huge number of major protocols such as IMAP, POP3, and LDAP. Making an n-tier development a possibility for the first time, PHP4 added support for Java and distributed object architecture (CORBA and COM). As another best feature, PHP is a forgiving language. Yes, it tries to be as 'forgiving' as possible. And, its Syntax is C-Like.
Another best thing about this language is that it is easy to use as not only the advanced developers but also the newbies can use it. And it still retains a healthy list of innovative features for highly professional programmers to develop.
Previous Versions of PHP Till Now
Till now, several versions of PHP has evolved. So, let’s check out the PHP versions already available in the market here.
1.0 8th June 1995
2.0 1st November 1997
3.0 6th June 1998 to 20th October 2000
4.0 22nd May 2000 to 23rd June 2001
4.1 10th December 2001 to 12th March 2002
4.2 22nd April 2002 to 6th September 2002
4.3 27th December 2002 to 31st March 2005
4.4 11th July 2005 7th August 2008
5.0 13th July 2004 to 5th September 2005
5.1 24th November 2005 to 24th August 2006
5.2 2nd November 2006 to 6th January 2011
5.3 30th June 2009 to 14th August 2014
5.4 1st March 2012 to 3rd September 2015
5.5 20th June 2013 to 21st July 2016
5.6 28th August 2014 to 31st December 2018
7.0 3rd December 2015 to 3rd December 2018
7.1 1st December 2016 to 1st December 2019
7.2 30th November 2017 to 30th November 2020
7.3 6th December 2018 to December 2021