{"id":1468,"date":"2020-07-23T07:47:38","date_gmt":"2020-07-23T07:47:38","guid":{"rendered":"https:\/\/www.ipraxa.com\/blog\/?p=1468"},"modified":"2023-07-06T09:04:06","modified_gmt":"2023-07-06T09:04:06","slug":"php-8-features-improvements","status":"publish","type":"post","link":"https:\/\/www.ipraxa.com\/blog\/php-8-features-improvements\/","title":{"rendered":"PHP 8 \u2013 Key Features &#038; Improvements with Screenshots"},"content":{"rendered":"<p>Since its inception in the early 90s, PHP has evolved from a fun way to track visits to a website to a powerful, autonomous tool used to develop large-scale, business-critical web systems. With an estimated 80% market share, it&#8217;s now the server-side programming language of choice for most <a href=\"https:\/\/www.ipraxa.com\/hire-dedicated-developers.html\">web development professionals<\/a> to create dynamic and interactive websites and applications.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1471\" src=\"https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-1.png\" alt=\"PHP 8\" width=\"481\" height=\"306\" srcset=\"https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-1.png 481w, https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-1-300x191.png 300w\" sizes=\"(max-width: 481px) 100vw, 481px\" \/><\/p>\n<p>Although PHP 7.x brought significant improvements over PHP 5.x in terms of speed, performance, and lower memory usage, the team has been continuously working to make the language even better, faster, and more feature-rich as the performance improvements in versions 7.1 and 7.2 were modest. As a result of this active development, PHP 8 is all set to release <a href=\"https:\/\/wiki.php.net\/todo\/php80\" target=\"_blank\" rel=\"dofollow noopener noreferrer\">by the end of 2020<\/a>, with its <a href=\"https:\/\/www.php.net\/archive\/2020.php#2020-07-09-1\" target=\"_blank\" rel=\"dofollow noopener noreferrer\">second alpha released<\/a> a few weeks ago.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-1472\" src=\"https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-2.png\" alt=\"PHP 8\" width=\"700\" height=\"411\" srcset=\"https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-2.png 830w, https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-2-300x176.png 300w, https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-2-768x451.png 768w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>PHP 8 is on the way, and what could be a better way to celebrate its <a href=\"https:\/\/www.jetbrains.com\/lp\/php-25\/\" target=\"_blank\" rel=\"dofollow noopener noreferrer\">25th anniversary<\/a> than getting familiar with all the new goodies coming to the next major release of the language? Let&#8217;s dive into some of the most exciting new features and improvements that will make PHP more efficient and reliable.<\/p>\n<h2>Highlights:<\/h2>\n<ul>\n<li><a href=\"#link1\">PHP JIT (Just in Time Compiler)<\/a><\/li>\n<li><a href=\"#link2\">PHP 8 New Features &amp; Improvements<\/a><\/li>\n<li><a href=\"#link3\">New Functions in PHP 8<\/a><\/li>\n<li><a href=\"#link4\">Backward Compatibility<\/a><\/li>\n<\/ul>\n<h2 id=\"link1\" align=\"center\">PHP JIT (Just in Time Compiler)<\/h2>\n<p>One of the most promising features coming to PHP 8 is Just-in-time (JIT) compilation. PHP JIT is almost independent of OPcache and is introduced to bring significant improvements to language performance.<\/p>\n<p>To better understand JIT, you first need to be familiar with how PHP executes from the source code to render the final output. The PHP runs the source code in 4 steps:<\/p>\n<ul>\n<li><strong>Lexing\/Tokenizing:<\/strong> The PHP code will be read and converted into a set of tokens by the interpreter.<\/li>\n<li><strong>Parsing:<\/strong> The interpreter matches the syntax rules with the script and utilizes tokes to create an abstract syntax tree (AST) &#8211; a hierarchical representation of the source code structure.<\/li>\n<li><strong>Compilation:<\/strong> The interpreter travel across the AST and translates nodes into Opcode &#8211; the language that Zend virtual machine understands.<\/li>\n<li><strong>Interpretation:<\/strong> The Zend VM finally interprets and runs the Opcode to produce the final results.<\/li>\n<\/ul>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-1473\" src=\"https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-3.png\" alt=\"PHP 8\" width=\"379\" height=\"675\" srcset=\"https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-3.png 740w, https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-3-168x300.png 168w, https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-3-574x1024.png 574w\" sizes=\"(max-width: 379px) 100vw, 379px\" \/><\/p>\n<p>And to save time in the above process, we have OPCache (Opcode Cache) that improves PHP performance by storing the results of the compilation step in shared memory, thereby eliminating the need for the interpreter to parse, compile, and execute scripts over and over again on each request.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-1474\" src=\"https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-4.png\" alt=\"PHP 8\" width=\"399\" height=\"581\" srcset=\"https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-4.png 1004w, https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-4-206x300.png 206w, https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-4-702x1024.png 702w, https:\/\/www.ipraxa.com\/blog\/wp-content\/uploads\/2020\/07\/Image-4-768x1120.png 768w\" sizes=\"(max-width: 399px) 100vw, 399px\" \/><\/p>\n<p>With the implementation of <a href=\"https:\/\/wiki.php.net\/rfc\/preload\" target=\"_blank\" rel=\"dofollow noopener noreferrer\">preloading<\/a> in PHP 7.4, OPcache received significant improvements. However, its performance is still not optimized for typical web-based applications, and PHP JIT attempts to do the same.<\/p>\n<p>The PHP JIT compiler takes advantage of <a href=\"https:\/\/luajit.org\/dynasm.html\" target=\"_blank\" rel=\"dofollow noopener noreferrer\">DynASM<\/a> (Dynamic Assembler) to translate Opcode into machine code and run that code instead of transferring it to the Zend VM. Thus, bypassing compilation or say removing the need for the Zend VM, the PHP JIT optimizes the memory usage and offers remarkable performance improvements for numerical and &#8220;typical&#8221; PHP web application codes.<\/p>\n<h2 id=\"link2\" align=\"center\">PHP 8 New Features &amp; Improvements<\/h2>\n<p>Apart from JIT, PHP 8 brings us a whole bunch of powerful features and improvements. Following is our handpicked selection of enhancements made to the world&#8217;s most popular server-side scripting language:<\/p>\n<ul>\n<li><a href=\"#a\">Union Types 2.0<\/a><\/li>\n<li><a href=\"#b\">Attributes v2<\/a><\/li>\n<li><a href=\"#c\">Match Expression v2<\/a><\/li>\n<li><a href=\"#d\">Mixed Type v2<\/a><\/li>\n<li><a href=\"#e\">Validation for Abstract Trait Methods<\/a><\/li>\n<li><a href=\"#f\">Consistent Type Errors for Internal Functions<\/a><\/li>\n<li><a href=\"#g\">Constructor Property Promotion<\/a><\/li>\n<li><a href=\"#h\">Arrays Starting with a Negative Index<\/a><\/li>\n<li><a href=\"#i\">Fatal Error for Incompatible Method Signatures<\/a><\/li>\n<li><a href=\"#j\">throw Expression<\/a><\/li>\n<li><a href=\"#k\">Trailing Comma in Parameter List<\/a><\/li>\n<li><a href=\"#l\">Weak Maps<\/a><\/li>\n<li><a href=\"#m\">Allowing ::class on objects<\/a><\/li>\n<li><a href=\"#n\">New static Return Type<\/a><\/li>\n<li><a href=\"#o\">Non-capturing Catches<\/a><\/li>\n<li><a href=\"#p\">New Stringable interface<\/a><\/li>\n<li><a href=\"#q\">Always Available JSON Extension<\/a><\/li>\n<li><a href=\"#r\">Stable Sorting<\/a><\/li>\n<li><a href=\"#s\">Remove Inappropriate Inheritance Signature Checks<\/a><\/li>\n<li><a href=\"#t\">Object-based token_get_all() Alternative<\/a><\/li>\n<\/ul>\n<h3 id=\"a\" align=\"left\">#Union Types 2.0<\/h3>\n<p>Union types accept values of several different types. Currently, PHP doesn\u2019t support arbitrary union types, but it supports only two special union types:<\/p>\n<ul>\n<li><em>Type or null<\/em> through the special ?Type syntax<\/li>\n<li><em>array<\/em> or Traversable via special <em>iterable<\/em> type.<\/li>\n<\/ul>\n<p>You can only specify arbitrary union types in phpdoc annotations as shown in the following example:<\/p>\n<pre class=\"theme:raygun font:courier-new nums:false lang:default decode:true\">class Number {\n    \/**\n     * @var int|float $number\n     *\/\n    private $number;\n \n    \/**\n     * @param int|float $number\n     *\/\n    public function setNumber($number) {\n        $this-&gt;number = $number;\n    }\n \n    \/**\n     * @return int|float\n     *\/\n    public function getNumber() {\n        return $this-&gt;number;\n    }\n}\n<\/pre>\n<p>But starting PHP 8, you&#8217;ll be able to specify arbitrary union types with a T1|T2|&#8230; syntax and use them in all positions where they are accepted.<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">class Number {\n    private int|float $number;\n \n    public function setNumber(int|float $number): void {\n        $this-&gt;number = $number;\n    }\n \n    public function getNumber(): int|float {\n        return $this-&gt;number;\n    }\n}\n<\/pre>\n<p>Learn more about <a href=\"https:\/\/wiki.php.net\/rfc\/union_types_v2\" target=\"_blank\" rel=\"noopener noreferrer\">Union Types V2<\/a> in the RFC.<\/p>\n<h3 id=\"b\" align=\"left\">#Attributes v2<\/h3>\n<p>Also known as Annotations, Attributes are a form of structured metadata that you can use to define properties for files, elements, or objects.<\/p>\n<p>So far, PHP has been allowing you to add an unstructured form of such metadata via doc-comments. PHP 8 introduces Attributes as a new way to add structured, syntactic metadata to declarations of functions, properties, classes, etc.<\/p>\n<p>Similar to doc-block comments, Attributes can be added before the declaration they belong to:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">&lt;&lt;ExampleAttribute&gt;&gt;\nclass Foo\n{\n    &lt;&lt;ExampleAttribute&gt;&gt;\n    public const FOO = 'foo';\n \n    &lt;&lt;ExampleAttribute&gt;&gt;\n    public $x;\n \n    &lt;&lt;ExampleAttribute&gt;&gt;\n    public function foo(&lt;&lt;ExampleAttribute&gt;&gt; $bar) { }\n}\n \n$object = new &lt;&lt;ExampleAttribute&gt;&gt; class () { };\n \n&lt;&lt;ExampleAttribute&gt;&gt;\nfunction f1() { }\n \n$f2 = &lt;&lt;ExampleAttribute&gt;&gt; function () { };\n \n$f3 = &lt;&lt;ExampleAttribute&gt;&gt; fn () =&gt; 1;<\/pre>\n<p>You can declare Attributes before or after a doc-block comment:<\/p>\n<pre class=\"theme:raygun font-size:14 nums:false lang:default decode:true\">&lt;&lt;ExampleAttribute&gt;&gt;\n\/** docblock *\/\n&lt;&lt;AnotherExampleAttribute&gt;&gt;\nfunction foo() {}<\/pre>\n<p>Each declaration may have one or more attributes and each attribute may have one or more values associated with it:<\/p>\n<pre class=\"theme:raygun font-size:14 nums:false lang:default decode:true\">&lt;&lt;WithoutArgument&gt;&gt;\n&lt;&lt;SingleArgument(0)&gt;&gt;\n&lt;&lt;FewArguments('Hello', 'World')&gt;&gt;\nfunction foo() {}<\/pre>\n<p>You can even use the same attribute name more than once in a declaration. Learn more about <a href=\"https:\/\/wiki.php.net\/rfc\/attributes_v2\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Attributes v2<\/a> in the RFC.<\/p>\n<h3 id=\"c\" align=\"left\">#Match Expression v2<\/h3>\n<p>The <strong><em>match<\/em><\/strong> expression is the enhanced version of the <strong><em>switch<\/em><\/strong> expression. It has been introduced to address long-standing shortcomings of the <strong><em>switch<\/em><\/strong>, namely:<\/p>\n<ul>\n<li>Type coercion<\/li>\n<li>No return value<\/li>\n<li>Fallthrough<\/li>\n<li>Inexhaustiveness<\/li>\n<\/ul>\n<p>The new <strong><em>match<\/em><\/strong> expression uses strict type comparisons, returns values, doesn&#8217;t require <strong><em>break<\/em><\/strong> statements, and throws an error if a condition isn&#8217;t met. It looks like this:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true \">match ($condition) {\n    1 =&gt; {\n        foo();\n        bar();\n    },\n    2 =&gt; baz(),\n}\n \n$expressionResult = match ($condition) {\n    1, 2 =&gt; foo(),\n    3, 4 =&gt; bar(),\n    default =&gt; baz(),\n};<\/pre>\n<p>Read up on the <strong><em>match<\/em><\/strong> in detail over <a href=\"https:\/\/wiki.php.net\/rfc\/match_expression\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>.<\/p>\n<h3 id=\"d\" align=\"left\">#Mixed Type v2<\/h3>\n<p>With the addition of union types in 8.0, <a href=\"https:\/\/www.ipraxa.com\/hire-dedicated-php-developers.html\">PHP development experts<\/a> may explicitly declare type information for most class properties and function returns or parameters. Keeping this in mind, PHP 8 adds the <strong><em>mixed<\/em><\/strong> pseudo-type to PHP&#8217;s type system. You can use it when the parameter\/return\/property are of any type.<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true \">public function foo(mixed $value){}<\/pre>\n<p>To be more precise, a type of <strong><em>mixed<\/em><\/strong> would be equivalent to a Union Type of:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true \">array|bool|callable|int|float|null|object|resource|string<\/pre>\n<p>Learn more about <a href=\"https:\/\/wiki.php.net\/rfc\/mixed_type_v2\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Mixed Type v2<\/a> in the RFC.<\/p>\n<h3 id=\"e\" align=\"left\">#Validation for Abstract Trait Methods<\/h3>\n<p>Traits are a mechanism for code reuse in PHP. They are typically used to declare methods used in more than one class.<\/p>\n<p>Traits can contain abstract methods to impose requirements on the classes using them. However, the signatures of these method implementations are currently only spottily enforced.<\/p>\n<p>The following example relates to not-enforced Abstract trait method signatures:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">trait T {\n    abstract public function test(int $x);\n}\n \nclass C {\n    use T;\n \n    \/\/ Allowed, but shouldn't be due to invalid type.\n    public function test(string $x) {}\n}<\/pre>\n<p>PHP 8 performs proper method signature validation and always generates a fatal error if the implementing method is incompatible with the abstract trait method.<\/p>\n<p><span style=\"color: #99cc00;\"><em>Fatal error: Declaration of C::test(string $x) must be compatible with T::test(int $x) in \/path\/to\/your\/test.php on line 10<\/em><\/span><\/p>\n<h3 id=\"f\" align=\"left\">#Consistent Type Errors for Internal Functions<\/h3>\n<p>For passing a parameter of illegal type in PHP 7.4, user-defined functions throw a <strong><em>TypeError<\/em><\/strong> while internal functions typically emit a warning and return null. See the following example:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true \">var_dump(strlen(new stdClass));<\/pre>\n<p>The above line of code throws the following warning:<\/p>\n<p><span style=\"color: #99cc00;\"><em>\/\/ Warning: strlen () expects parameter 1 to be string, object given<br \/>\n\/\/ NULL<\/em><\/span><\/p>\n<p>To eliminate inconsistencies, PHP 8 consistently throws <strong><em>TypeError<\/em><\/strong> for all invalid parameter types, including internal functions. As a result, the code above generates the following error in PHP 8:<\/p>\n<p><span style=\"color: #99cc00;\"><em>Fatal error: Uncaught TypeError: strlen(): Argument #1 ($str) must be of type string, object given in \/path\/to\/your\/test.php:4<br \/>\nStack trace:<br \/>\n#0 { main }<br \/>\nthrown in \/path\/to\/your\/test.php on line 4<\/em><\/span><\/p>\n<h3 id=\"g\" align=\"left\">#Constructor Property Promotion<\/h3>\n<p>Currently, when you define a simple value object, you have to repeat all properties multiple times:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true \">class Point {\n    public float $x;\n    public float $y;\n    public float $z;\n \n    public function __construct(\n        float $x = 0.0,\n        float $y = 0.0,\n        float $z = 0.0,\n    ) {\n        $this-&gt;x = $x;\n        $this-&gt;y = $y;\n        $this-&gt;z = $z;\n    }\n}<\/pre>\n<p>PHP 8 introduces a short hand syntax to simplify the property declaration. The new and more concise syntax combines class properties and the constructor into a single class.<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true \">class Point {\n    public function __construct(\n        public float $x = 0.0,\n        public float $y = 0.0,\n        public float $z = 0.0,\n    ) {}\n}<\/pre>\n<p>This short-hand code is equivalent to the previous syntax but more concise.<\/p>\n<h3 id=\"h\" align=\"left\">#Arrays Starting with a Negative Index<\/h3>\n<p>In PHP 7.4, if the value of <strong><em>start_index<\/em><\/strong> is less than zero, the first index is <strong><em>start_index<\/em><\/strong> and the following indices start from zero. Look at the following example:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">$a = array_fill(-5, 4, true);\nvar_dump($a);<\/pre>\n<p>This results the following:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">array(4) {\n  [-5]=&gt;\n  bool(true)\n  [0]=&gt;\n  bool(true)\n  [1]=&gt;\n  bool(true)\n  [2]=&gt;\n  bool(true)\n}<\/pre>\n<p>PHP 8 makes implicit array keys consistent by always using <strong><em>start_index + 1<\/em><\/strong> for the second index, regardless the value of <strong><em>start_index<\/em><\/strong>. Consequently, the syntax above would result in the following array:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">array(4) {\n  [-5]=&gt;\n  bool(true)\n  [-4]=&gt;\n  bool(true)\n  [-3]=&gt;\n  bool(true)\n  [-2]=&gt;\n  bool(true)\n}<\/pre>\n<h3 id=\"i\" align=\"left\">#Fatal Error for Incompatible Method Signatures<\/h3>\n<p>Inheritance errors caused by incompatible abstract and non-abstract method signatures either throw a fatal error or a warning, depending on the cause or origin of the error.<\/p>\n<p>For example, in PHP 7.4, the following code generates a fatal error:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">interface I {\n    public function method(array $a);\n}\nclass C implements I {\n    public function method(int $a) {}\n}\n\/\/ Fatal error: Declaration of C::method(int $a) must be compatible with I::method(array $a)\n<\/pre>\n<p>On the other hand, the following code only generates a warning:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">class C1 {\n    public function method(array $a) {}\n}\nclass C2 extends C1 {\n    public function method(int $a) {}\n}\n\/\/ Warning: Declaration of C2::method(int $a) should be compatible with C1::method(array $a)\n<\/pre>\n<p><span style=\"font-family: 'courier new', courier, monospace; font-size: 12pt;\">PHP 8 always generates a fatal error for incompatible method signatures, no matter the origin of the error.<\/span><\/p>\n<h3 id=\"j\" align=\"left\">#<em>throw<\/em> Expression<\/h3>\n<p>In the previous version of PHP, <strong><em>throw<\/em><\/strong> is a statement, making it impossible to throw exceptions in places where only expressions are accepted.<\/p>\n<p>PHP 8 converts the <strong><em>throw<\/em><\/strong> statement into an expression so you can use it in places where expressions are allowed. Look at the following examples:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">$callable = fn() =&gt; throw new Exception();\n \n$value = $nullableValue ?? throw new InvalidArgumentException();\n$value = $falsableValue ?: throw new InvalidArgumentException();<\/pre>\n<h3 id=\"k\" align=\"left\">#Trailing Comma in Parameter List<\/h3>\n<p>Trailing commas are commas added to a list of items in different contexts. PHP currently supports trailing commas in function calls and list syntax.<\/p>\n<p>PHP 8 lets you use a single optional trailing comma in parameter lists for functions, methods, and closures. Here is an example:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">class Uri {\n    private function __construct(\n        ?string $a,\n        ?int $b,\n        ?float $c, \/\/ trailing comma\n    ) {\n        ...\n    }\n}\n<\/pre>\n<h3 id=\"l\" align=\"left\">#Weak Maps<\/h3>\n<p>PHP 7.4 introduced <a href=\"https:\/\/wiki.php.net\/rfc\/weakrefs\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">weak references<\/a> to allow developers to retain a reference to an object that doesn\u2019t prevent itself from getting destroyed. However, their usefulness is limited.<\/p>\n<p>A weak map holds data (objects) without preventing it from being garbage collected. PHP 8 introduces a <strong><em>WeakMap<\/em><\/strong> class with the following prototype:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">final class WeakMap implements ArrayAccess, Countable, Traversable {\n    public function offsetGet($object);\n    public function offsetSet($object, $value): void;\n    public function offsetExists($object): bool;\n    public function offsetUnset($object): void;\n    public function count(): int;\n}\n<\/pre>\n<p>As a result, if an object used as a weak map key is garbage collected, the key is destroyed and removed from the weak map. See the following example:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">$map = new WeakMap;\n$obj = new stdClass;\n$map[$obj] = 42;\nvar_dump($map);\n<\/pre>\n<p>In PHP 8, this code will produce the result below:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true \">\/\/ object(WeakMap)#1 (1) {\n\/\/   [0]=&gt;\n\/\/   array(2) {\n\/\/     [\"key\"]=&gt;\n\/\/     object(stdClass)#2 (0) {\n\/\/     }\n\/\/     [\"value\"]=&gt;\n\/\/     int(42)\n\/\/   }\n\/\/ }\n<\/pre>\n<p>Unsetting the object leads to automatically removing the key from the weak map:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true \">unset($obj);\nvar_dump($map);<\/pre>\n<p><span style=\"font-family: 'courier new', courier, monospace; font-size: 12pt;\">Now the result would be:<\/span><\/p>\n<p><span style=\"font-family: 'courier new', courier, monospace; font-size: 12pt; color: #99cc00;\"><em>\/\/ object(WeakMap)#1 (0) {<\/em> <\/span><\/p>\n<p><span style=\"font-family: 'courier new', courier, monospace; font-size: 12pt; color: #99cc00;\"><em>\/\/ }<\/em><\/span><\/p>\n<h3 id=\"m\" align=\"left\">#Allowing <em>::class<\/em> on objects<\/h3>\n<p>A small, yet useful, new feature! PHP 8 allows you to use to use <strong><em>::class<\/em><\/strong> on objects and get the same result as <strong><em>get_class($object) <\/em><\/strong>.<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">$object = new stdClass;\nvar_dump($object::class); \/\/ \"stdClass\"\n \n$object = null;\nvar_dump($object::class); \/\/ TypeError\n<\/pre>\n<p><span style=\"font-family: 'courier new', courier, monospace; font-size: 12pt;\">If <strong><em>$object<\/em><\/strong> is not an object, <strong><em>$object::class<\/em><\/strong> throws a <strong><em>TypeError<\/em><\/strong> exception.<\/span><\/p>\n<h3 id=\"n\" align=\"left\">#New <em>static<\/em> Return Type<\/h3>\n<p>While it was already possible to return <strong><em>self<\/em><\/strong> and <strong><em>parent<\/em><\/strong> types, PHP 8 allows you to use static as a return type.<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">class Foo\n{\n    public function test(): static\n    {\n        return new static();\n    }\n}<\/pre>\n<h3 id=\"o\" align=\"left\">#Non-capturing Catches<\/h3>\n<p>If you want to catch an exception in PHP 7.4, you have to store it in a variable, regardless of whether or not you use it.<\/p>\n<p>On the contrary, PHP 8 allows you to catch exceptions without storing them to variables, so instead of this:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">try {\n    changeImportantData();\n} catch (PermissionException $ex) {\n    echo \"You don't have permission to do this\";\n}<\/pre>\n<p><span style=\"font-family: 'courier new', courier, monospace; font-size: 12pt;\">You can now do this:<\/span><\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">try {\n    changeImportantData();\n} catch (PermissionException) {\n    echo \"You don't have permission to do this\";\n}<\/pre>\n<h3 id=\"p\" align=\"left\">#New <em>Stringable<\/em> interface<\/h3>\n<p>PHP 8 introduces a new <strong><em>Stringable<\/em><\/strong> interface that is automatically added to anything that is a string or implements the <strong><em>__to String ( )<\/em><\/strong> method. You don&#8217;t have to implement it manually. Here is an example:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">interface Stringable\n{\n   public function __toString(): string;\n}<\/pre>\n<h3 id=\"q\" align=\"left\">#Always Available JSON Extension<\/h3>\n<p>A subtle yet healthy change in PHP 8 is the continuous availability of the JSON extension. Currently, you can compile PHP with <strong><em>.\/configure &#8211;disable-json<\/em><\/strong>. However, this is not possible anymore with PHP 8.<\/p>\n<p>Given that JSON is widely used for many use cases, PHP 8 makes it impossible to disable it through configuration or build options. Now developers have the guarantee that JSON is always enabled.<\/p>\n<h3 id=\"r\" align=\"left\">#Stable Sorting<\/h3>\n<p>Sorting functions are currently unstable in PHP, resulting in no guarantee of the order of equal elements. PHP 8 makes all sorting functions stable by default.<\/p>\n<h3 id=\"s\" align=\"left\">#Remove Inappropriate Inheritance Signature Checks<\/h3>\n<p>In the current PHP version, a method with a similar name to a parent&#8217;s method is still checked against some inheritance rules regardless of the parent&#8217;s method is public or private.<\/p>\n<p>Given that private methods cannot be called outside of their scope, PHP 8 removes inappropriate inheritance checks for the cases when the parent method is private.<\/p>\n<h3 id=\"t\" align=\"left\">#Object-based <em>token_get_all()<\/em> Alternative<\/h3>\n<p>Currently, the <strong><em>token_get_all()<\/em><\/strong> returns tokens either as a single-character string, or an array of values.<\/p>\n<p>PHP 8 introduces a new <strong><em>PhpToken<\/em><\/strong> class with a <strong><em>PhpToken::getAll()<\/em><\/strong> method, which acts as an alternative to <strong><em>token_get_all()<\/em><\/strong> method. Instead of a mix of strings and arrays, <strong><em>PhpToken::getAll()<\/em><\/strong> returns an array of <strong><em>PhpToken<\/em><\/strong> objects.<\/p>\n<h2 id=\"link3\" align=\"center\">New Functions in PHP 8<\/h2>\n<p>In addition to the features and improvements mentioned above, PHP 8 also adds several new functions to the language:<\/p>\n<p><strong>#<em>str_contains:<\/em><\/strong> This new function checks if a string is contained within another string and returns a Boolean value, <strong><em>true<\/em><\/strong> or <strong><em>false<\/em><\/strong>, depending on the situation.<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">str_contains ( string $haystack , string $needle ) : bool<\/pre>\n<p><strong><em>#get_debug_type:<\/em><\/strong> This new PHP function returns the true type name of a variable and resolves class names. <strong><em>get_debug_type<\/em><\/strong> works in the same way as the <strong><em>gettype<\/em><\/strong> function, but it returns a more useful output for classes, objects, arrays, and strings, so instead of this:<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true\">$bar = $arr['key'];\nif (!($bar instanceof Foo)) { \n  throw new TypeError('Expected ' . Foo::class . ' got ' . \n(is_object($bar) ? get_class($bar) : gettype($bar)));\n}\n<\/pre>\n<p><span style=\"font-family: 'courier new', courier, monospace; font-size: 12pt;\">You can now use this:<\/span><\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true \">if (!($bar instanceof Foo)) { \n  throw new TypeError('Expected ' . Foo::class . ' got ' . get_debug_type($bar));\n}<\/pre>\n<p><span style=\"font-family: 'courier new', courier, monospace; font-size: 12pt;\">You can see a full list of differences between <strong><em>get_debug_type()<\/em><\/strong> and <strong><em>gettype()<\/em><\/strong> here.<\/span><\/p>\n<p><strong><em>#str_starts_with() and str_ends_with():<\/em><\/strong> These new PHP functions check if a string starts or ends with a certain substring.<\/p>\n<pre class=\"theme:raygun nums:false lang:default decode:true \">str_starts_with(string $haystack, string $needle): bool\n\nstr_ends_with(string $haystack, string $needle): bool<\/pre>\n<p><span style=\"font-size: 12pt; font-family: 'courier new', courier, monospace;\">Both functions return false if <strong><em>$needle<\/em><\/strong> is longer than <strong><em>$haystack<\/em><\/strong>.<\/span><\/p>\n<h2 id=\"link4\" align=\"center\">Backward Compatibility<\/h2>\n<p>Since PHP 8 is a major update to the language, you can expect it to introduce some breaking changes that may break your existing code. In other words, chances are very high that you\u2019ll have to make significant changes to your code to get it running on PHP 8.<\/p>\n<p>If you have kept yourself up-to-date with the recent releases, upgrading to PHP 8 shouldn\u2019t be that difficult as most breaking changes were deprecated in version 7.x. As always, you can take help from the <a href=\"https:\/\/github.com\/php\/php-src\/blob\/master\/UPGRADING\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">upgrading document<\/a> that serves as an excellent guide for upgradation. However, if you still face any problems upgrading to PHP 8, you can always <a href=\"https:\/\/www.ipraxa.com\/hire-dedicated-php-developers.html\">hire certified PHP developers<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Since its inception in the early 90s, PHP has evolved from a fun way to track visits to a website to a powerful, autonomous tool used to develop large-scale, business-critical web systems. With an estimated 80% market share, it&#8217;s now the server-side programming language of choice for most web development professionals to create dynamic and <\/p>\n<p> <a class=\"text-btn read-more\" href=\"https:\/\/www.ipraxa.com\/blog\/php-8-features-improvements\/\">Read More <svg xml:space=\"preserve\" enable-background=\"new 0 0 30 18\" viewBox=\"0 0 30 18\" height=\"18px\" width=\"30px\" y=\"0px\" x=\"0px\" xmlns:xlink=\"http:\/\/www.w3.org\/1999\/xlink\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M20.305,16.212c-0.407,0.409-0.407,1.071,0,1.479s1.068,0.408,1.476,0l7.914-7.952c0.408-0.409,0.408-1.071,0-1.481\n\n\n\nl-7.914-7.952c-0.407-0.409-1.068-0.409-1.476,0s-0.407,1.071,0,1.48l7.185,7.221L20.305,16.212z\" class=\"handle\"\/><path d=\"M1,8h28.001c0.551,0,1,0.448,1,1c0,0.553-0.449,1-1,1H1c-0.553,0-1-0.447-1-1\n\n\n\nC0,8.448,0.447,8,1,8z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" class=\"bar\"\/><\/svg><\/a><\/p>\n","protected":false},"author":4,"featured_media":1493,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[5],"tags":[263,265,264,21],"acf":[],"_links":{"self":[{"href":"https:\/\/www.ipraxa.com\/blog\/wp-json\/wp\/v2\/posts\/1468"}],"collection":[{"href":"https:\/\/www.ipraxa.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ipraxa.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ipraxa.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ipraxa.com\/blog\/wp-json\/wp\/v2\/comments?post=1468"}],"version-history":[{"count":27,"href":"https:\/\/www.ipraxa.com\/blog\/wp-json\/wp\/v2\/posts\/1468\/revisions"}],"predecessor-version":[{"id":2919,"href":"https:\/\/www.ipraxa.com\/blog\/wp-json\/wp\/v2\/posts\/1468\/revisions\/2919"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ipraxa.com\/blog\/wp-json\/wp\/v2\/media\/1493"}],"wp:attachment":[{"href":"https:\/\/www.ipraxa.com\/blog\/wp-json\/wp\/v2\/media?parent=1468"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ipraxa.com\/blog\/wp-json\/wp\/v2\/categories?post=1468"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ipraxa.com\/blog\/wp-json\/wp\/v2\/tags?post=1468"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}