https://dnlytras.com/blog/modern-php/ You have disabled Javascript, good luck with that. I built this website using Gatsby, how wrong I was. AboutBlogSnippets Modern PHP While I wasn't paying attention, PHP got quite good March 14th 2022*6 minutes read The last time I've used PHP was probably around 2017, although it was just in the context of supporting some WordPress sites. By that time 7.2 had already been released, but I had no idea. I wanted to avoid working with PHP at all costs. This month I took some time to check what good things have been added to the language that I was unaware of. To be honest, things are looking great. The list below is not exhaustive, I only reference what I'll be using, or find notable. * Array destructuring (v7.1) * Spread operator within arrays (v7.4) & (v8.1) * Match expressions (v8.0) * Enumerations (enums) (v8.1) * Arrow functions (v7.4) * Named parameters (v8.0) * Null coalescing operator (v7.0) * Null coalescing assignment operator (v7.4) * Null-safe operator (v8.0) * Spaceship operator (v7.0) * Multi catch exception handling (v7.1) * `str_starts_with`, `str_ends_with`, `str_contains` (v8.0) * Return Types (v7.0) * Union types (v8.0) * Null and Void return types (v7.1) * Never return type (v8.1) * Grouped imports (v7.0) * Constructor property promotion (v8.0) * WeakMaps (v8.0) Array destructuring Added in v7.1 // arrays $posts = [[1, 2, 3, 4], [5, 6, 7]]; [$publishedPosts, $draftPosts] = $posts; // or skip [, $draftPosts] = $posts; // associative arrays $post = [ 'title' => 'Modern Php', 'description' => '...', 'status' => 'Published' ]; ['title' => $title, 'description' => $description] = $post; Spread operator within arrays * Initial support for arrays in v7.4 * Support for string-keyed (associative) arrays in v8.1 // arrays $userPosts = [1, 2, 3, 4, 5]; $userPosts = [...$userPosts, 6]; // associative arrays $userPosts = [ 'id-a' => 'Published', 'id-b' => 'Draft', ]; $userPosts = [...$userPosts, 'id-c' => 'Draft']; Match expressions Added in v8.1 The one thing I'm most jealous it's missing in Javascript // using a switch statement switch ($status) { case 'Published': $message = 'The post has been published'; break; case 'Draft': $message = 'The post is in draft state'; break; } // as a match expression $message = match($status) { 'Published' => 'The post has been published', 'Draft' => 'The post is in draft state', }; Enumerations (enums) Added in v8.1 // previously using a class class Status { const DRAFT = 'Draft'; const PUBLISHED = 'Published'; const ARCHIVED = 'Archived'; } // using an enum enum PostStatus { case Draft; case Published; case Archived; } $status = PostStatus::Draft; Arrow functions Added in v7.4 fn (args) => expression (!) Arrow functions can't be multi-line $publishedPosts = array_filter($posts, fn($post) => $post->status === 'Published' ) Named parameters Added in v8.0 function enableThisConfig($optionA, $optionB, $somethingElse, $anotherOne) { // } // 6 months later reading this.. ?? enableThisConfig(true, true, false, 'DEV'); // using named params enableThisConfig( optionA: true, optionB: true, somethingElse: false, anotherOne: 'DEV', ); Null coalescing operator Added in v7.0 // this annoying thing $data['name'] = isset($data['name']) ? $data['name'] : 'Guest'; // to $data['name'] = $data['name'] ?? 'Guest'; Null coalescing assignment operator Added in v7.4 // our previous example $data['name'] = $data['name'] ?? 'Guest'; // to $data['name'] ??= 'Guest'; Null-safe operator Added in v8.0 class User { public function getPreferences() {} } class Preferences { public function getColorScheme() {} } $user = new User; // preferences could be null $colorScheme = $user->getPreferences()->getColorScheme(); // alternative $preferences = $user->getPreferences(); $colorScheme = $preferences ? $preferences->getColorScheme() : null; // using null-safe operator $colorScheme = $user->getPreferences()?->getColorScheme(); Spaceship operator Added in v7.0 $result = 1 <=> 1 // 0 $result = 1 <=> 2 // -1 $result = 2 <=> 1 // 1 $array = [1, 4, 5, 6, 7, 8 ,9 ,2]; usort($array, fn($a, $b) => $a <=> $b); Multi-catch exception handling Added in v7.1 try { // ... } catch(ErrorA | ErrorB $e) { // } catch(Exception $e) { // general case } New string utils Added in v8.0 Previously we would use strpos or some other creative solution. $string = 'Modern PHP'; if (str_starts_with($string, 'Modern')) {} if (str_ends_with($string, 'PHP')) {} if (str_contains($string, 'Modern')) {} Return types Added in v7.0 function getPost(int $postId): Post { // } Union types Added in v8.0 function updateTotal(int|float $cost) { // } Null and Void return types Added in v7.1 // Notice the `?` before the type function getPost(int $postId): ?Post { // can return null } function setPostTitle(int $postId, string $title): void { persistInDB($postId, $postTitle); // won't return anything, or optionally can do: // `return;` } Never return type Added in v8.1 function notImplemented(): never { throw new Exception('Not implemented'); } Import grouping Added in v7.0 A small but welcome addition // all in separate lines use App\Entity\Task; use App\Entity\Reminder; use App\Entity\Todo; // now use App\Entity\{Task, Reminder, Todo}; Constructor property promotion Added in v8.0 // from this class User { public string $name; public Address $address; public function __construct(string $name, Address $address) { $this->name = $name; $this->address = $address; } } // to this class User { public function __construct(protected string $name, protected Address $address) { // nothing else needed } } Weakmaps Not really using Weakmaps, not even in Javascript, but I find it a great addition // code taken from https://php.watch/versions/8.0/weakmap class CommentRepository { private WeakMap $comments_cache; public function getCommentsByPost(Post $post): ?array { if (!isset($this->comments_cache[$post])) { $this->comments_cache[$post] = $this->loadComments($post); } return $this->comments_cache[$post] } } --------------------------------------------------------------------- I have to say I'm very happy to see these features, and I look forward to the next PHP releases with great excitement. Although I'll be mostly working with Laravel and its extensive library (collections & helpers) watching the language grow is lovely. --------------------------------------------------------------------- Previous: "Nominal types in TypeScript" Back to Blog Dimitrios Lytras Building scalable & performant web applications Get in Touch Send me an e-mailSchedule a meeting Navigation HomeAboutWorkBlogSnippets