Top 10 New Features in PHP 8.1
This article introduces the ten most important new features of PHP 8.1—including enums, fibers, the never return type, readonly properties, final class constants, array_is_list(), fsync/fdatasync, string‑key array unpacking, the $_FILES full_path key, and the IntlDatePatternGenerator class—each explained with clear code examples.
PHP 8.1 was released on 2021‑11‑25 and brings a JIT compiler together with a set of language enhancements that improve developer productivity and performance.
Top 10 New Features in PHP 8.1
1. Enums
PHP 8.1 adds native support for enumerations, allowing developers to define a set of named values, optionally backed by a string or integer.
<code><?php
/** Declare an enumeration.
* It can also contain an optional 'string' or 'int' value. This is called a backed Enum.
* Backed enums (if used) must follow these rules:
* - Declare the scalar type (string or int) in the enum declaration.
* - All cases have values.
* - All cases use the same scalar type.
* - Each case has a unique value.
*/
enum UserRole: string {
case ADMIN = '1';
case GUEST = '2';
case WRITER = '3';
case EDITOR = '4';
}
// Access a case and its name
echo UserRole::WRITER->name; // outputs "WRITER"
// Access a case and its value
echo UserRole::WRITER->value; // outputs "3"
?>
</code>2. Fibers
Fibers provide a low‑level concurrency primitive that lets PHP code run in cooperative multitasking fashion. A Fiber has its own stack and can be started, suspended, and resumed from within PHP.
<code><?php
$fiber = new Fiber(function(): void {
echo "Welcome to Fiber!\n"; // before suspension
Fiber::suspend();
echo "Welcome back to Fiber!\n"; // after resumption
});
echo "Starting a Fiber\n";
$fiber->start();
echo "Fiber has been suspended\n";
echo "Resuming the Fiber\n";
$fiber->resume();
echo "Fiber completed execution\n";
?>
</code>3. never Return Type
The never return type indicates that a function will never return to its caller because it always throws an exception or terminates the script (e.g., via exit() or die() ).
<code><?php
class Route {
/**
* Redirect to a URL and terminate execution.
* @param string $url
* @param int $httpCode
* @return never
*/
public static function redirect(string $url, int $httpCode = 301): never {
header("Location: {$url}", true, $httpCode);
die();
}
}
Route::redirect('https://www.google.com');
?>
</code>4. readonly Properties
Properties declared with the readonly modifier can be assigned only once, typically inside the constructor, and any further modification results in a fatal error.
<code><?php
class User {
public readonly int $authUserID;
public function __construct(int $userID) {
$this->authUserID = $userID; // allowed
}
public function updateAuthUserID(int $userID): void {
// This will trigger a fatal error because the property is readonly
$this->authUserID = $userID;
}
}
$user = new User(30);
echo $user->authUserID; // prints 30
$user->updateAuthUserID(50); // fatal error
?>
</code>5. final Class Constants
Class constants can now be marked as final , preventing them from being overridden in child classes.
<code><?php
class UserRole {
final public const ADMIN = '1';
}
class User extends UserRole {
// Attempting to override will cause a fatal error
// public const ADMIN = '2';
}
?>
</code>6. array_is_list() Function
The new array_is_list() function checks whether an array has sequential integer keys starting at 0, i.e., whether it behaves like a list.
<code><?php
array_is_list([]); // true
array_is_list([1, 2, 3]); // true
array_is_list(['a' => 1, 2, 3]); // false (non‑sequential keys)
?>
</code>7. fsync() and fdatasync() Functions
Both functions flush buffered data to the underlying storage. fsync() also synchronizes metadata, while fdatasync() syncs only the file data, making it slightly faster.
<code><?php
$fileName = 'notes.txt';
$file = fopen($fileName, 'w+');
fwrite($file, 'Paragraph 1');
fwrite($file, "\r\n");
fwrite($file, 'Paragraph 2');
fsync($file); // or fdatasync($file);
fclose($file);
?>
</code>8. String‑Key Array Unpacking
PHP 8.1 extends the spread operator (...) to work with arrays that have string keys, allowing them to be unpacked together with numeric‑key arrays.
<code><?php
$fruits1 = ['Jonathan Apples', 'Sapote'];
$fruits2 = ['Pomelo', 'Jackfruit'];
$unpackedFruits = [...$fruits1, ...$fruits2, ...['Red Delicious']];
var_dump($unpackedFruits);
?>
</code>9. $_FILES full_path Key for Directory Uploads
The full_path entry in the $_FILES superglobal stores the relative path of each uploaded file, enabling whole‑directory uploads via the webkitdirectory attribute.
<code><?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
var_dump($_FILES);
}
?>
<form method="POST" enctype="multipart/form-data">
<input name="myfiles[]" type="file" webkitdirectory multiple />
<button type="submit">Submit</button>
</form>
</code>10. IntlDatePatternGenerator Class
The new IntlDatePatternGenerator class generates locale‑aware date patterns, offering more flexibility than the older IntlDateFormatter .
<code><?php
$skeleton = "YYYY-MM-dd";
$today = \DateTimeImmutable::createFromFormat('Y-m-d', date('Y-m-d'));
$generator = new \IntlDatePatternGenerator('en_US');
$enUSPattern = $generator->getBestPattern($skeleton);
echo "Date in en‑US: " . \IntlDateFormatter::formatObject($today, $enUSPattern, 'en_US') . "\n";
$generator = new \IntlDatePatternGenerator('en_IN');
$enINPattern = $generator->getBestPattern($skeleton);
echo "Date in en‑IN: " . \IntlDateFormatter::formatObject($today, $enINPattern, 'en_IN') . "\n";
?>
</code>By mastering these new capabilities, developers can write cleaner, more efficient, and more expressive PHP code in their current and future projects.
php中文网 Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.