12.7 C
New York
Tuesday, December 6, 2022

PHP 8 — Attributes, Match Expression and Other Improvements – InfoQ.com

Live Webinar and Q&A: Success in the Cloud: How to Avoid Kubernetes Deployment Pitfalls (Live Webinar November 15, 2022) Save Your Seat
Facilitating the Spread of Knowledge and Innovation in Professional Software Development


PHP 8 is a major update to PHP that introduces several new features and performance optimizations. In this first article of the PHP 8.x Article Series, we are going to introduce a number of new features including attributes, match expression, instanceof operator, new operator, a new JIT compiler, and more.
Wes Reisz speaks with long-time open-source contributor and startup founder Matt Butcher who is the CEO of Fermyon Technologies and is at the forefront of the Web Assembly (Wasm) work being done in the cloud. The two discuss Butcher’s belief we’re at the start of a 3rd wave of cloud computing, the state of the Wasm ecosystem, and what Fermyon’s doing in the space.
In this article, author discusses data pipeline and workflow scheduler Apache DolphinScheduler and how ML tasks are performed by Apache DolphinScheduler using Jupyter and MLflow components.
Testability can enable teams to make changes to their code bases without requiring extensive regression testing. To build testability, team members must collaborate and leverage each other’s unique skills. Unfortunately, effective collaboration does not come naturally to people and therefore needs leadership to nurture people’s ability to speak up and share their knowledge.
Daniel Mangum explores how bringing applications and infrastructure to a single control plane allows for building robust platforms that can accommodate heterogenous organizational structures.
Understand the emerging software trends you should pay attention to. Attend in-person on Oct 24-28, 2022.
Make the right decisions by uncovering how senior software developers at early adopter companies are adopting emerging trends. Register Now.
Adopt the right emerging trends to solve your complex engineering challenges. Register Now.
Your monthly guide to all the topics, technologies and techniques that every professional needs to know about. Subscribe for free.
InfoQ Homepage Articles PHP 8 — Attributes, Match Expression and Other Improvements
Oct 18, 2022 16 min read
by
Deepak Vohra
reviewed by
Sergio De Simone
This article is part of the article series "PHP 8.x". You can subscribe to receive notifications about new articles in this series via RSS.
PHP continues to be one of the most widely used scripting languages on  the web with 77.3% of all the websites whose server-side programming language is known using it according to w3tech. PHP 8 brings many new features and other improvements, which we shall explore in this article series.
Uncover emerging trends and practices from domain experts. Attend in-person at QCon San Francisco (October 24-28, 2022).
PHP 8 is a major update to PHP that introduces several new features and performance optimizations, including attributes, match expression, instanceof operator, new operator, a new JIT compiler, and more. 
Attributes provide a way to add metadata to classes, methods, functions, parameters, properties, and class constants. Attributes are similar to annotations that are supported by some other languages. The new operator, only available starting with PHP 8.1, can be used in initializers for default parameter values, static variables, and attribute arguments. The match expression  is a new control structure that evaluates a subject expression with multiply-branched conditional expressions using the identity operator and executes the matched branch. The instanceof operator, which previously could only be used with a class object, can also be used with any arbitrary expression . The JIT (Just-In-Time) compiler  brings performance and usability improvements. 
Some of the examples are based on  data structures requiring to download and install the php_ds extension from here. On Windows, download the  DLL for 8.1 Non Thread Safe (NTS) x64 from here, and extract the php_ds-1.4.0-8.1-nts-vs16-x64.zip file to a directory. Copy the php_ds.dll from the extracted directory to the .ext directory within the PHP 8.x installation root, for example C:php-8.1.9-nts-Win32-vs16-x64ext.  Add the following line to the php.ini configuration file:
extension=php_ds
Restart the PHP built-in server if it is already running.
Attributes are configuration directives used to annotate or decorate classes, methods, functions, parameters, properties, and class constants with structured and machine-readable metadata. “Structured” means the metadata information may be read and parsed, making attributes different from unstructured doc-comments, which are just plain strings.  Attributes can be used to provide configuration and other information that is relevant only some of the time, and therefore embedded, not hard-coded into the PHP script. The following is the typical sequence for using attributes:
Attributes can have several uses, such as:
By default, an attribute can be used on any or all of the supported declaration types. But an attribute use could be limited to one or more types of declarations using selected bitmask flags Attribute::TARGET_CLASS, Attribute::TARGET_FUNCTION, Attribute::TARGET_METHOD, Attribute::TARGET_PROPERTY, Attribute::TARGET_CLASS_CONSTANT. Attribute::TARGET_PARAMETER, Attribute::TARGET_ALL. The Attribute::TARGET_ALL flag is the default. An attribute can be used multiple times on a single declaration using the bitmask flag Attribute::IS_REPEATABLE. 
Next, we shall explore the use of attributes with an example. Consider that you want to sort an array using one or more sort functions, such as sort() for sorting in ascending order, rsort() for sorting in descending order, and shuffle() for shuffling in random order. You may also want to validate the input array to verify that it is not an empty array, or that it has at least two elements to make sorting relevant. The sort type information and the validation information could be provided in the form of attributes. 
First, declare an attribute class for validation.
Then, declare another attribute class for the sort type. The bitmask flags Attribute::TARGET_CLASS, and Attribute::IS_REPEATABLE indicate that the attribute is only meant to be used with a class declaration, and that the attribute is repeatable. 
Declare now an interface with a single method called sortArray().
Finally, declare a class that implements the Sort interface.
Within the class, declare two class properties, one for the sort type, and the second for the array to be sorted.
Declare a method to validate that the array to be sorted is not an empty array. Annotate the method with the #[Validate] attribute. Applying the attribute to the method makes the method discoverable using the Reflection APIs.
Declare a second method for validating that the array has at least two elements, and apply the #[Validate] attribute to it.
Implement the sortArray function. Based on the value of the SortType, make an ascending/descending/shuffle sort.
Add a function called performSort(Sort $sort) to perform the sort. In the function, apply the validations before performing the sort. 
Declare a class and apply the #[SortType] attribute to it. As the attribute is repeatable, apply the attribute multiple times to perform different types of sort. 
Finally, create an instance of the class SortImpl.
Get the class attributes using the Reflection API.
Iterate over the attributes array to call the performSort() function to perform the sort for each type of sort type, and output the result of the sort.
The complete sort.php script to demonstrate the use of attributes is available on GitHub. Copy the sort.php script to the scripts folder, and with the PHP built-in server running and listening at http://localhost:8000 call the sort.php script in a browser with url http://localhost:8000/scripts/sort.php. The result for the sort using the different sort types is displayed in the browser as shown in Figure 1.

Figure 1. Result of sorting using attributes 
Because the shuffle sort is a random sort the result for shuffle is likely to be different  each time the script is run, as shown in Figure 2.

Figure 2. Shuffle sort produces a different result
Because the sample array to sort has 4 elements, none of the validations fails. If the sample array is empty, on the contrary, the same script, with only the sample array changed, generates a runtime exception message : Uncaught RuntimeException: Array is empty; please provide a non-empty array. Similarly, if the sample array has only 1 element a runtime exception is generated with message : Uncaught RuntimeException: Please provide an array of size 2 or more. 
The new operator is used to create an instance of a class. As of PHP 8.1, the new operator can be used in arbitrary expressions with the following syntax in which the expression must be wrapped in parentheses. 
The new operator can be used in initializers for parameter default values, static variable initializers, global constant initializers, and attribute arguments as explored next with examples.
To demonstrate the use of the new operator in function parameter default values, we shall use a variation of the array sort example. Consider a class called SortArray that declares a method sortArray($arrayToSort) to sort an array in ascending order. 
A second class called ReverseSortArray declares a method to sort an array in descending order.
Declare now a function that accepts any arbitrary array and an array sorter to sort the array. The default array sorter could be defined using  the new operator to create an instance of the SortArray.
The complete script is available on GitHub. Run the sample script on the built-in server with url http://localhost:8000/scripts/sample.php
The output is shown here:
The new operator may be used in static variable initializers and global constant initializers. The new operator is not supported, though, in static and non-static class property initializers, nor in class constant initializers. The following script demonstrates which variable and constant initializers are supported, and which aren't. 
As you would expect, the new operator can be used in attribute arguments, too. We shall use the same example we used to demonstrate the Attributes feature with one difference. Remember that we used the #[SortType] attribute to annotate the QSort class with the attribute arguments being passed to it as strings.
For this case, declare a class called Str that accepts a string argument as a constructor argument.
Use the new operator in the attribute arguments as follows.
 Run the script in the built-in server with the same output as before, as shown in Figure 3.

Figure 3. The result from using new in attribute arguments
Earlier we mentioned some contexts in which the new operator is not supported, that is static and non-static class property initializers,  and class constant initializers. Additionally, the new operator is not supported in the following contexts:
The following script generates an error for the statements commented out:
PHP 8 introduces a new match expression as a control flow structure that matches a given subject expression with one or more alternative branches using identity comparison, and returns a value that is the result from the matched branch. The match expression is similar to a switch statement but different as follows:
Next, we  demonstrate the use of the match expression with some examples. 
To start off with a simple example, the match expression in the following script matches the integer value of 1, given as the subject expression, with multiple conditional expressions including the default pattern.
Run the script in the built-in engine by calling the script in a browser with url
http://localhost:8000/scripts/match.php. The output is:
B
In the following script, the subject expression is not matched by any of the non-default conditional expressions.
The output is:
Default
The default condition can't be grouped with other conditions as shown in the script:
When the script is run, it generates the error:
A relatively complex example, the following script has a variable initialized from the  DsVector  class. The subject expression accesses the vector variable in array notation. 
Call the script in a browser with url  http://localhost:8000/scripts/match.php
The result is:
b
The return value may also be assigned to a variable, and the match conditions may be any arbitrary expressions. In the following script, the match expression matches the boolean value true as the subject expression with conditional expressions that call other built-in string functions. 
The output is:
Unlike the loose comparison made by a switch statement, the match expression makes a strict comparison and no type coercion is made. First, an example of a loose comparison with a switch statement. The following script matches the first condition and outputs the value of a
In contrast, the match in the following script makes a strict comparison and matches the default condition to output Default.
The match expression makes an identity comparison using the identity operator (===), which implies that even NULL values are matched. As the DsVector::push() method returns NULL, the match expression in the following script actually matches the NULL values returned by the DsVector::push() method.  
The first condition gets matched and the output is:
Identity comparison ( === ) can be applied to arbitrary values even to when no value is returned. The NULL value returned by match can be assigned to a variable. The following script matches a NULL value, and the first condition gets matched.
Call the script with url http://localhost:8000/scripts/sample.php and the output is:
NULL
Multiple conditional expressions may be comma separated. First, an example with single conditions as in the following script. 
The output is :
Take the same example and add multiple conditions separated by a comma.
The misspelled ‘puush’ that is listed as the second alternative in the first conditional expression list gets matched and the output is:
The match expression must be exhaustive. In the following script  the subject expression is not matched by any of the conditions.
As a result, an error is output:
Another new feature is that the instanceof operator accepts any arbitrary expression. The only two requirements are :
To demonstrate the new instanceof operator, create a PHP script sample.php. Declare three variables for collections of different types such as DsVector, and DsSet.
Add an arbitrary function that returns a class, such as DsVector::class as a string. 
Output the results for using the instanceof operator with different collection variables. The instanceof operator takes an expression that evaluates to a string in each call. The sample.php is listed.
The script runs ok with PHP 8 and generates output:
PHP 8 introduces Just-in-time (JIT) compilation with the following goals:
Two JIT compilation engines are introduced: Tracing JIT, and Function JIT. Function JIT only optimizes code within the scope of a single function, whereas Tracing JIT optimizes the whole stack trace. Tracing JIT is shown to improve performance 3 times on synthetic benchmarks, and 1.5 to 2 times on long-running queries. Tracing JIT is shown to improve performance by more than 4 times on the Mandelbrot benchmark
In this article we have introduced some of the most relevant improvements to PHP 8 syntax, including attributes, the operator new, match expressions, and more. In the next article we shall explore improvements to classes and constructors.
 
This article is part of the article series "PHP 8.x". You can subscribe to receive notifications about new articles in this series via RSS.
PHP continues to be one of the most widely used scripting languages on  the web with 77.3% of all the websites whose server-side programming language is known using it according to w3tech. PHP 8 brings many new features and other improvements, which we shall explore in this article series.

Becoming an editor for InfoQ was one of the best decisions of my career. It has challenged me and helped me grow in so many ways. We’d love to have more people join our team.

A round-up of last week’s content on InfoQ sent out every Tuesday. Join a community of over 250,000 senior developers. View an example

We protect your privacy.
You need to Register an InfoQ account or or login to post comments. But there’s so much more behind being registered.
Get the most out of the InfoQ experience.
Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

A round-up of last week’s content on InfoQ sent out every Tuesday. Join a community of over 250,000 senior developers. View an example

We protect your privacy.
Real-world technical talks. No product pitches.
Practical ideas to inspire you and your team.
QCon San Francisco – Oct 24-28, In-person.

QCon San Francisco brings together the world’s most innovative senior software engineers across multiple domains to share their real-world implementation of emerging trends and practices.
Uncover emerging software trends and practices to solve your complex engineering challenges, without the product pitches.Save your spot now
InfoQ.com and all content copyright © 2006-2022 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we’ve ever worked with.
Privacy Notice, Terms And Conditions, Cookie Policy

source

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles