SlideShare a Scribd company logo
1 of 122
Download to read offline
PHP 8.1 Enums
Ayesh Karunaratne | https://aye.sh/talk/php-enums-phpjp-2021
PHP 8.1 Enums
Ayesh Karunaratne | https://aye.sh/talk/php-enums-phpjp-2021
@Ayeshlive | @phpwch
https://aye.sh | https://php.watch
Ayesh Karunaratne
Freelance Software Developer, Security Researcher, Full-time
traveler
ayesh@aye.sh
Kandy, Sri Lanka - Everywhere
PHP 8.1 Enums
PHP 8.1 Enumerations
PHP 8.1 Enumerations
PHP 8.1 Enumerations
PHP 8.1
Enumerations: RFC Created
04 Dec 2020
25 Nov 2021
03 Feb 2021 Voting started
17 Feb 2021 Voting ended: 44:7
03 Oct 2021 PHP Conference Japan 2021
Why we need Enums
How Enums can help
Enums in PHP 8.1
Enum Semantics
Usage Examples
Trying out Enums today
Backwards Compatibility
PHP 8.1: Enums
Why we need Enums
$handle = curl_init();
$options = [
CURLOPT_URL => 'https://example.com',
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
CURLOPT_RETURNTRANSFER => true,
];
curl_setopt_array($handle, $options);
curl_exec($handle);
Why we need Enums
$handle = curl_init();
$options = [
CURLOPT_URL => 'https://example.com',
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
CURLOPT_RETURNTRANSFER => true,
];
curl_setopt_array($handle, $options);
curl_exec($handle);
Why we need Enums
$handle = curl_init();
$options = [
CURLOPT_URL => 'https://example.com',
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
CURLOPT_RETURNTRANSFER => true,
];
var_dump($options);
curl_setopt_array($handle, $options);
curl_exec($handle);
Why we need Enums
$handle = curl_init();
$options = [
CURLOPT_URL => 'https://example.com',
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
CURLOPT_RETURNTRANSFER => true,
];
var_dump($options);
curl_setopt_array($handle, $options);
curl_exec($handle);
array(3) {
[10002]=> string(19) "https://example.com"
[84]=> int(3)
[19913]=> bool(true)
}
Why we need Enums
$handle = curl_init();
$options = [
CURLOPT_URL => 'https://example.com',
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
CURLOPT_RETURNTRANSFER => true,
];
var_dump($options);
curl_setopt_array($handle, $options);
curl_exec($handle);
array(3) {
[10002]=> string(19) "https://example.com"
[84]=> int(3)
[19913]=> bool(true)
}
define ('CURLOPT_URL', 10002);
define ('CURLOPT_HTTP_VERSION', 84);
define ('CURL_HTTP_VERSION_1_1', 2);
define ('CURL_HTTP_VERSION_2_0', 3);
define ('CURLOPT_RETURNTRANSFER', 19913);
Why we need Enums
$handle = curl_init();
$options = [
CURLOPT_URL => 'https://example.com',
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
CURLOPT_RETURNTRANSFER => true,
];
var_dump($options);
curl_setopt_array($handle, $options);
curl_exec($handle);
array(3) {
[10002]=> string(19) "https://example.com"
[84]=> int(3)
[19913]=> bool(true)
}
define ('CURLOPT_URL', 10002);
define ('CURLOPT_HTTP_VERSION', 84);
define ('CURL_HTTP_VERSION_1_1', 2);
define ('CURL_HTTP_VERSION_2_0', 3);
define ('CURLOPT_RETURNTRANSFER', 19913);
Why we need Enums
$handle = curl_init();
$options = [
CURLOPT_URL => 'https://example.com',
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
CURLOPT_RETURNTRANSFER => true,
];
var_dump($options);
curl_setopt_array($handle, $options);
curl_exec($handle);
array(3) {
[10002]=> string(19) "https://example.com"
[84]=> int(3)
[19913]=> bool(true)
}
define ('CURLOPT_URL', 10002);
define ('CURLOPT_HTTP_VERSION', 84);
define ('CURL_HTTP_VERSION_1_1', 2);
define ('CURL_HTTP_VERSION_2_0', 3);
define ('CURLOPT_RETURNTRANSFER', 19913);
Why we need Enums
function curl_setopt(CurlHandle $handle, int $option, mixed $value) : bool {}
Why we need Enums
Why we need Enums
function curl_setopt(CurlHandle $handle, int $option, mixed $value) : bool {}
curl_setopt($handle, 10003, 'https://example.com');
PHP Error: curl_setopt(): Argument #2 ($option) is not a valid cURL option in … on line …
curl_setopt($handle, 10002, 'https://example.com');
10002 - CURLOPT_URL
curl_setopt($handle, 10004, 'https://example.com');
10004 - CURLOPT_PROXY
Why we need Enums
function curl_setopt(CurlHandle $handle, int $option, mixed $value) : bool {}
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public string $status;
public function updateStatus(string $status): void {}
}
Why we need Enums
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public string $status;
public function updateStatus(string $status): void {}
}
$post = new Post();
$post->updateStatus(Post::POST_STATUS_PUBLISHED);
Why we need Enums
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public string $status;
public function updateStatus(string $status): void {}
}
$post = new Post();
$post->updateStatus('returned');
Why we need Enums
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public string $status;
public function updateStatus(string $status): void {}
}
$post = new Post();
$post->updateStatus('returned');
Why we need Enums
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public string $status;
public function updateStatus(string $status): void {}
}
Why we need Enums
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public string $status;
public function updateStatus(string $status): void {
if ( $status !== static::POST_STATUS_DRAFT
&& $status !== static::POST_STATUS_PENDING
&& $status !== static::POST_STATUS_RETURNED
&& $status !== static::POST_STATUS_PUBLISHED
) {
throw new InvalidArgumentException('Invalid state');
}
}
}
Why we need Enums
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public string $status;
public function updateStatus(string $status): void {
if ( $status !== static::POST_STATUS_DRAFT
&& $status !== static::POST_STATUS_PENDING
&& $status !== static::POST_STATUS_RETURNED
&& $status !== static::POST_STATUS_PUBLISHED
) {
throw new InvalidArgumentException('Invalid state');
}
}
}
Why we need Enums
https://en.wikipedia.org/wiki/Open-closed_principle
How Enums Can Help
How Enums Can Help
type PostStatus = "draft" | "pending" | "returned" | "published";
How Enums Can Help
type PostStatus = "draft" | "pending" | "returned" | "published";
function updateStatus(status: PostStatus) {}
How Enums Can Help
type PostStatus = "draft" | "pending" | "returned" | "published";
function updateStatus(status: PostStatus) {}
How Enums Can Help
type PostStatus = "draft" | "pending" | "returned" | "published";
function updateStatus(status: PostStatus) {}
updateStatus("potato");
Argument of type '"potato"' is not assignable to
parameter of type 'PostStatus'.
updateStatus("draft");
✔️
How Enums Can Help
How Enums Can Help
enum PostStatus {
DRAFT,
PENDING,
PUBLISHED,
RETURNED,
};
function updateStatus(status: PostStatus) {
}
updateStatus(PostStatus.DRAFT);
How Enums Can Help
enum PostStatus {
DRAFT = "draft",
PENDING = "pending",
PUBLISHED = "published",
RETURNED = "draft",
};
function updateStatus(status: PostStatus) {
}
updateStatus(PostStatus.DRAFT);
How Enums Can Help
enum PostStatus {
DRAFT = "draft",
PENDING = "pending",
PUBLISHED = "published",
RETURNED = "draft",
};
enum PostStatus {
DRAFT = "draft";
PENDING = "pending";
PUBLISHED = "published";
RETURNED = "draft";
};
enum PostStatus {
}
How Enums Can Help
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
How Enums Can Help
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public string $status;
public function updateStatus(string $status): void {
if ( $status !== static::POST_STATUS_DRAFT
&& $status !== static::POST_STATUS_PENDING
&& $status !== static::POST_STATUS_RETURNED
&& $status !== static::POST_STATUS_PUBLISHED
) {
throw new InvalidArgumentException('Invalid state');
}
}
}
$post = new Post();
$post->updateStatus(Post::POST_STATUS_PUBLISHED);
How Enums Can Help
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public string $status;
public function updateStatus(string $status): void {
if ( $status !== static::POST_STATUS_DRAFT
&& $status !== static::POST_STATUS_PENDING
&& $status !== static::POST_STATUS_RETURNED
&& $status !== static::POST_STATUS_PUBLISHED
) {
throw new InvalidArgumentException('Invalid state');
}
}
}
$post = new Post();
$post->updateStatus(Post::POST_STATUS_PUBLISHED);
How Enums Can Help
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public string $status;
public function updateStatus(string $status): void {
if ( $status !== static::POST_STATUS_DRAFT
&& $status !== static::POST_STATUS_PENDING
&& $status !== static::POST_STATUS_RETURNED
&& $status !== static::POST_STATUS_PUBLISHED
) {
throw new InvalidArgumentException('Invalid state');
}
}
}
$post = new Post();
$post->updateStatus(Post::POST_STATUS_PUBLISHED);
How Enums Can Help
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public PostStatus $status;
public function updateStatus(string $status): void {
if ( $status !== static::POST_STATUS_DRAFT
&& $status !== static::POST_STATUS_PENDING
&& $status !== static::POST_STATUS_RETURNED
&& $status !== static::POST_STATUS_PUBLISHED
) {
throw new InvalidArgumentException('Invalid state');
}
}
}
$post = new Post();
$post->updateStatus(Post::POST_STATUS_PUBLISHED);
How Enums Can Help
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public PostStatus $status;
public function updateStatus(PostStatus $status): void {
if ( $status !== static::POST_STATUS_DRAFT
&& $status !== static::POST_STATUS_PENDING
&& $status !== static::POST_STATUS_RETURNED
&& $status !== static::POST_STATUS_PUBLISHED
) {
throw new InvalidArgumentException('Invalid state');
}
}
}
$post = new Post();
$post->updateStatus(Post::POST_STATUS_PUBLISHED);
How Enums Can Help
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public PostStatus $status;
public function updateStatus(PostStatus $status): void {
if ( $status !== static::POST_STATUS_DRAFT
&& $status !== static::POST_STATUS_PENDING
&& $status !== static::POST_STATUS_RETURNED
&& $status !== static::POST_STATUS_PUBLISHED
) {
throw new InvalidArgumentException('Invalid state');
}
}
}
$post = new Post();
$post->updateStatus(Post::POST_STATUS_PUBLISHED);
How Enums Can Help
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public PostStatus $status;
public function updateStatus(PostStatus $status): void {
if ( $status !== static::POST_STATUS_DRAFT
&& $status !== static::POST_STATUS_PENDING
&& $status !== static::POST_STATUS_RETURNED
&& $status !== static::POST_STATUS_PUBLISHED
) {
throw new InvalidArgumentException('Invalid state');
}
}
}
$post = new Post();
$post->updateStatus(Post::POST_STATUS_PUBLISHED);
How Enums Can Help
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
class Post {
public const POST_STATUS_DRAFT = 'draft';
public const POST_STATUS_PENDING = 'pending';
public const POST_STATUS_RETURNED = 'returned';
public const POST_STATUS_PUBLISHED = 'published';
public PostStatus $status;
public function updateStatus(PostStatus $status): void {
if ( $status !== static::POST_STATUS_DRAFT
&& $status !== static::POST_STATUS_PENDING
&& $status !== static::POST_STATUS_RETURNED
&& $status !== static::POST_STATUS_PUBLISHED
) {
throw new InvalidArgumentException('Invalid state');
}
}
}
$post = new Post();
$post->updateStatus(PostStatus::PUBLISHED);
How Enums Can Help
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
class Post {
public PostStatus $status;
public function updateStatus(PostStatus $status): void {
}
}
$post = new Post();
$post->updateStatus(PostStatus::PUBLISHED);
How Enums Can Help
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
function setIsSponsored(bool $sponsored): void {
}
function isSponsored(): bool {
}
setIsSponsored(true);
setIsSponsored(false);
How Enums Can Help
Enums in PHP 8.1
Enums in PHP 8.1
enum Suit {
}
• Enums can have zero or more members
Enums in PHP 8.1
enum Suit {
case Clubs;
case Diamonds;
case Spades;
case Hearts;
}
• Enums can have zero or more members
Enums in PHP 8.1
enum Suit {
case Clubs;
case Diamonds;
case Spades;
case Hearts;
}
• Enums can have zero or more members
• Enum members are objects
is_object(Suit::Hearts);
// true
Enums in PHP 8.1
enum Suit {
case Clubs;
case Diamonds;
case Spades;
case Hearts;
}
• Enums can have zero or more members
• Enum members are objects
var_dump(Suit::Hearts);
// enum(Suit::Hearts)
Enums in PHP 8.1
namespace AppPlayingCards;
enum Suit {
case Clubs;
case Diamonds;
case Spades;
case Hearts;
}
• Enums can have zero or more members
• Enum members are objects
• Enums can be namespaced and autoloaded
Enums in PHP 8.1
namespace AppPlayingCards;
enum Suit: int {
case Clubs = 1;
case Diamonds = 2;
case Spades = 3;
case Hearts = 4;
}
• Enums can have zero or more members
• Enum members are objects
• Enums can be namespaced and autoloaded
• May contain string|int backed values
Enums in PHP 8.1
namespace AppPlayingCards;
enum Suit: string {
case Clubs = '♣️';
case Diamonds = '♦️';
case Spades = '♠️';
case Hearts = '♥️';
}
• Enums can have zero or more members
• Enum members are objects
• Enums can be namespaced and autoloaded
• May contain string|int backed values
Enums in PHP 8.1
namespace AppPlayingCards;
enum Suit: string {
const AWESOME = 'Yes';
case Clubs = '♣️';
case Diamonds = '♦️';
case Spades = '♠️';
case Hearts = '♥️';
}
• Enums can have zero or more members
• Enum members are objects
• Enums can be namespaced and autoloaded
• May contain string|int backed values
• May contain non-duplicated constants
Enums in PHP 8.1
namespace AppPlayingCards;
enum Suit: string {
const AWESOME = 'Yes';
case Clubs = '♣️';
case Diamonds = '♦️';
case Spades = '♠️';
case Hearts = '♥️';
public static function cheer(): void {
echo 'Yay!';
}
}
• Enums can have zero or more members
• Enum members are objects
• Enums can be namespaced and autoloaded
• May contain string|int backed values
• May contain non-duplicated constants
• May contain static methods
Suit::cheer();
// Yay!
Enums in PHP 8.1
namespace AppPlayingCards;
enum Suit: string {
const AWESOME = 'Yes';
case Clubs = ' ';
case Diamonds = ' ';
case Spades = ' ';
case Hearts = ' ';
public static function cheer(): void {
echo 'Yay!';
}
public function show(): void {
var_dump($this);
var_dump($this->name);
var_dump(self::Clubs->name);
var_dump($this->value);
var_dump(self::Clubs->value);
}
}
• Enums can have zero or more members
• Enum members are objects
• Enums can be namespaced and autoloaded
• May contain string|int backed values
• May contain non-duplicated constants
• May contain static methods
• May contain non-static methods
Suit::Clubs->show();
Enums in PHP 8.1
namespace AppPlayingCards;
enum Suit: string {
const AWESOME = 'Yes';
case Clubs = ' ';
case Diamonds = ' ';
case Spades = ' ';
case Hearts = ' ';
public static function cheer(): void {
echo 'Yay!';
}
public function show(): void {
var_dump($this);
var_dump($this->name);
var_dump(self::Clubs->name);
var_dump($this->value);
var_dump(self::Clubs->value);
}
}
• Enums can have zero or more members
• Enum members are objects
• Enums can be namespaced and autoloaded
• May contain string|int backed values
• May contain non-duplicated constants
• May contain static methods
• May contain non-static methods
• $this refers to the Enumerated element
Suit::Clubs->show();
enum(AppPlayingCardsSuit::Clubs)
Enums in PHP 8.1
namespace AppPlayingCards;
enum Suit: string {
const AWESOME = 'Yes';
case Clubs = ' ';
case Diamonds = ' ';
case Spades = ' ';
case Hearts = ' ';
public static function cheer(): void {
echo 'Yay!';
}
public function show(): void {
var_dump($this);
var_dump($this->name);
var_dump(self::Clubs->name);
var_dump($this->value);
var_dump(self::Clubs->value);
}
}
• Enums can have zero or more members
• Enum members are objects
• Enums can be namespaced and autoloaded
• May contain string|int backed values
• May contain non-duplicated constants
• May contain static methods
• May contain non-static methods
• $this refers to the Enumerated element
• ->nameproperty is the name of the member
Suit::Clubs->show();
enum(AppPlayingCardsSuit::Clubs)
string(5) "Clubs"
string(5) "Clubs"
Enums in PHP 8.1
namespace AppPlayingCards;
enum Suit: string {
const AWESOME = 'Yes';
case Clubs = ' ';
case Diamonds = ' ';
case Spades = ' ';
case Hearts = ' ';
public static function cheer(): void {
echo 'Yay!';
}
public function show(): void {
var_dump($this);
var_dump($this->name);
var_dump(self::Clubs->name);
var_dump($this->value);
var_dump(self::Clubs->value);
}
}
• Enums can have zero or more members
• Enum members are objects
• Enums can be namespaced and autoloaded
• May contain string|int backed values
• May contain non-duplicated constants
• May contain static methods
• May contain non-static methods
• $this refers to the Enumerated element
• ->nameproperty is the name of the member
• ->value property is the backed value
Suit::Clubs->show();
enum(AppPlayingCardsSuit::Clubs)
string(5) "Clubs"
string(5) "Clubs"
string(6) "♣️"
string(6) "♣️"
Enums in PHP 8.1
namespace AppPlayingCards;
enum Suit: string {
const AWESOME = 'Yes';
case Clubs = ' ';
case Diamonds = ' ';
case Spades = ' ';
case Hearts = ' ';
public static function cheer(): void {
echo 'Yay!';
}
public function show(): void {
var_dump($this);
var_dump($this->name);
var_dump(self::Clubs->name);
var_dump($this->value);
var_dump(self::Clubs->value);
}
}
• Enums can have zero or more members
• Enum members are objects
• Enums can be namespaced and autoloaded
• May contain string|int backed values
• May contain non-duplicated constants
• May contain static methods
• May contain non-static methods
• $this refers to the Enumerated element
• ->nameproperty is the name of the member
• ->value property is the backed value
Suit::Clubs->show();
enum(AppPlayingCardsSuit::Clubs)
string(5) "Clubs"
string(5) "Clubs"
string(6) "♣️"
string(6) "♣️"
enum PostStatus {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
Enums in PHP 8.1
Unit Enums
enum PostStatus implements UnitEnum {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
Enums in PHP 8.1
Unit Enums
enum PostStatus implements UnitEnum {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
interface UnitEnum {
public static function cases(): array;
}
Enums in PHP 8.1
Unit Enums
enum PostStatus implements UnitEnum {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
interface UnitEnum {
public static function cases(): array;
}
Enums in PHP 8.1
Unit Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
enum PostStatus implements UnitEnum {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
interface UnitEnum {
public static function cases(): array;
}
Enums in PHP 8.1
Unit Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
enum PostStatus implements UnitEnum {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
interface UnitEnum {
public static function cases(): array;
}
Enums in PHP 8.1
Unit Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
PostStatus::cases();
enum PostStatus implements UnitEnum {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
interface UnitEnum {
public static function cases(): array;
}
Enums in PHP 8.1
Unit Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
array(4) {
[0]=> enum(PostStatus::DRAFT)
[1]=> enum(PostStatus::PENDING)
[2]=> enum(PostStatus::RETURNED)
[3]=> enum(PostStatus::PUBLISHED)
}
PostStatus::cases();
enum PostStatus implements UnitEnum {
case DRAFT;
case PENDING;
case RETURNED;
case PUBLISHED;
}
interface UnitEnum {
public static function cases(): array;
}
Enums in PHP 8.1
Unit Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
array(4) {
[0]=> enum(PostStatus::DRAFT)
[1]=> enum(PostStatus::PENDING)
[2]=> enum(PostStatus::RETURNED)
[3]=> enum(PostStatus::PUBLISHED)
}
PostStatus::cases();
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
Backed Enums extend Unit Enums
Backed Enums
Enums in PHP 8.1
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(int|string $value): static;
public static function tryFrom(int|string $value): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(
int|string $value
): static;
public static function tryFrom(
int|string $value
): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(
int|string $value
): static;
public static function tryFrom(
int|string $value
): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(
int|string $value
): static;
public static function tryFrom(
int|string $value
): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
echo PostStatus::DRAFT->value;
// "draft"
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(
int|string $value
): static;
public static function tryFrom(
int|string $value
): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
echo PostStatus::DRAFT->value;
// "draft"
PostStatus::tryFrom('draft');
PostStatus::from('draft');
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(
int|string $value
): static;
public static function tryFrom(
int|string $value
): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
echo PostStatus::DRAFT->value;
// "draft"
PostStatus::tryFrom('draft');
PostStatus::from('draft');
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(
int|string $value
): static;
public static function tryFrom(
int|string $value
): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
echo PostStatus::DRAFT->value;
// "draft"
PostStatus::tryFrom('draft');
PostStatus::from('draft');
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(
int|string $value
): static;
public static function tryFrom(
int|string $value
): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
echo PostStatus::DRAFT->value;
// "draft"
PostStatus::tryFrom('draft');
PostStatus::from('draft');
enum(PostStatus::DRAFT)
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(
int|string $value
): static;
public static function tryFrom(
int|string $value
): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
echo PostStatus::DRAFT->value;
// "draft"
PostStatus::tryFrom('draft');
PostStatus::from('draft');
enum(PostStatus::DRAFT)
PostStatus::tryFrom('potato');
PostStatus::from('potato');
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(
int|string $value
): static;
public static function tryFrom(
int|string $value
): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
echo PostStatus::DRAFT->value;
// "draft"
PostStatus::tryFrom('draft');
PostStatus::from('draft');
enum(PostStatus::DRAFT)
PostStatus::tryFrom('potato');
PostStatus::from('potato');
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(
int|string $value
): static;
public static function tryFrom(
int|string $value
): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
echo PostStatus::DRAFT->value;
// "draft"
PostStatus::tryFrom('draft');
PostStatus::from('draft');
enum(PostStatus::DRAFT)
PostStatus::tryFrom('potato');
// null
PostStatus::from('potato');
Uncaught ValueError: "potato" is not a valid backing value
for enum "PostStatus"
enum PostStatus: string implements BackedEnum {
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
interface BackedEnum extends UnitEnum {
public static function from(
int|string $value
): static;
public static function tryFrom(
int|string $value
): ?static;
}
Enums in PHP 8.1
Backed Enums extend Unit Enums
Backed Enums
echo PostStatus::DRAFT->name;
// "DRAFT"
echo PostStatus::DRAFT->value;
// "draft"
PostStatus::tryFrom('draft');
PostStatus::from('draft');
enum(PostStatus::DRAFT)
PostStatus::tryFrom('potato');
// null
PostStatus::from('potato');
Uncaught ValueError: "potato" is not a valid backing value
for enum "PostStatus"
Enum Semantics
Enum Semantics
Enum
Enumerated type that contains a fixed number of members.
Enum Semantics
Enum
Enumerated type that contains a fixed number of members.
A type that is supported as parameter, return, and property type in PHP,
and the type is enforced by PHP itself.
Enum Semantics
Enum
Enumerated type that contains a fixed number of members.
All members are contained within a declared Enum.
Enum Semantics
Enum
Enumerated type that contains a fixed number of members.
Members of an Enum is fixed at the declaration time.
An enumerated member is identical to the same member everywhere.
Enums must not contain state.
Enum Semantics
Enumerated types
enum Suit {
case Spades;
case Hearts;
case Clubs;
case Diamonds;
}
function play_card(Suit $suit, string $card) {}
function pick_a_suit(): Suit {
return Suit::Spades;
}
play_card(Suit::Spades, 'A');
var_dump(pick_a_suit());
// enum(Suit::Spades)
Enum Semantics
enum Suit {
case Spades;
case Hearts;
case Clubs;
case Diamonds;
}
function play_card(Suit $suit, string $card) {}
function pick_a_suit(): Suit {
return Suit::Spades;
}
play_card(Fruits::Apple);
play_card(Languages::English);
play_card('potato');
Fatal error: Uncaught TypeError: play_card(): Argument #1
($suit) must be of type Suit, string given
Enumerated types
Enum Semantics
enum Suit {
case Spades;
case Hearts;
case Clubs;
case Diamonds;
}
Closed Set
Enum Semantics
enum Suit {
case Spades;
case Hearts;
case Clubs;
case Diamonds;
}
Fixed Members
Suit::Spades === Suit::Spades
Enum Semantics
enum Suit {
case Spades;
case Hearts;
case Clubs;
case Diamonds;
}
Fixed Members
enum RussianSuit extends Suit {}
Parse error: syntax error, unexpected token "extends",
expecting "{"
Enum Semantics
enum Suit {
case Spades;
case Hearts;
case Clubs;
case Diamonds;
private string $foo;
}
No Properties Allowed
Fatal error: Enums may not include properties
Enum Semantics
Backed Enums must assign values for all cases
enum HTTPMethods: string {
case GET;
case POST;
}
Fatal error: Case GET of backed enum HTTPMethods must have a value
Enum Semantics
Enum cases and values must be unique
Fatal error: Cannot redefine class
constant Test::FOO
enum Test {
case FOO;
case FOO;
}
enum Test: string {
case FOO = 'baz';
case BAR = 'baz';
}
Fatal error: Duplicate value in
enum Test for cases FOO and BAR
Enum Semantics
Class Semantics
namespace FooBar;
enum PostStatus: string implements EntityStatues {
use TestTrait;
case DRAFT = 'draft';
case PENDING = 'pending';
case RETURNED = 'returned';
case PUBLISHED = 'published’;
public static function showOff(): void {
echo __CLASS__ . static::class;
}
}
• Supports namespaces
• Supports traits
• Supports autoloading
• Supports magic constants
• Supports instanceof
• Supports methods
Usage Examples
Usage Examples
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
Usage Examples
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
class Post {
private int $id;
private string $title;
private PostStatus $status;
public function __construct(
int $id,
string $title,
PostStatus $status
) {
// ...
}
public function getStatus(): PostStatus {
return $this->status;
}
}
Usage Examples
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
class Post {
private int $id;
private string $title;
private PostStatus $status;
public function __construct(
int $id,
string $title,
PostStatus $status
) {
// ...
}
public function getStatus(): PostStatus {
return $this->status;
}
}
Usage Examples
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
class Post {
private int $id;
private string $title;
private PostStatus $status;
public function __construct(
int $id,
string $title,
PostStatus $status
) {
// ...
}
public function getStatus(): PostStatus {
return $this->status;
}
}
Usage Examples
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
class Post {
private int $id;
private string $title;
private PostStatus $status;
public function __construct(
int $id,
string $title,
PostStatus $status
) {
// ...
}
public function getStatus(): PostStatus {
return $this->status;
}
}
Usage Examples
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
} $stmt = $pdo->prepare("
SELECT *
FROM posts
WHERE post_status=?");
$stmt->execute([
PostStatus::PUBLISHED->value
]);
$post = $stmt->fetch();
class Post {
private int $id;
private string $title;
private PostStatus $status;
public function __construct(
int $id,
string $title,
PostStatus $status
) {
// ...
}
public function getStatus(): PostStatus {
return $this->status;
}
}
Usage Examples
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
} $stmt = $pdo->prepare("
SELECT *
FROM posts
WHERE post_status=?");
$stmt->execute([
PostStatus::PUBLISHED->value
]);
$post = $stmt->fetch();
class Post {
private int $id;
private string $title;
private PostStatus $status;
public function __construct(
int $id,
string $title,
PostStatus $status
) {
// ...
}
public function getStatus(): PostStatus {
return $this->status;
}
}
Usage Examples
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
class Post {
private int $id;
private string $title;
private PostStatus $status;
public function __construct(
int $id,
string $title,
PostStatus $status
) {
// ...
}
public function getStatus(): PostStatus {
return $this->status;
}
}
$sql = "
INSERT INTO
posts (id, title, post_status)
VALUES
(:id, :title, :post_status)";
$stmt= $pdo->prepare($sql);
$stmt->execute([
'id' => $post->getId(),
'title' => $post->getTitle(),
'post_status' => $post->getStatus()->value,
]);
Usage Examples
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
class Post {
private int $id;
private string $title;
private PostStatus $status;
public function __construct(
int $id,
string $title,
PostStatus $status
) {
// ...
}
public function getStatus(): PostStatus {
return $this->status;
}
}
$sql = "
INSERT INTO
posts (id, title, post_status)
VALUES
(:id, :title, :post_status)";
$stmt= $pdo->prepare($sql);
$stmt->execute([
'id' => $post->getId(),
'title' => $post->getTitle(),
'post_status' => $post->getStatus()->value,
]);
Usage Examples
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
class Post {
private int $id;
private string $title;
private PostStatus $status;
public function __construct(
int $id,
string $title,
PostStatus $status
) {
// ...
}
public function getStatus(): PostStatus {
return $this->status;
}
public function updateStatus(
PostStatus $status
): void {
}
}
$result = [
'id' => 42,
'title' => 'PHP Enums',
'post_status' => 'published',
];
$post = new Post(
$result['id'],
$result['title']
);
$post->updateStatus(
PostStatus::from($result['post_status'])
);
Usage Examples
enum PostStatus: string {
case DRAFT = 'draft';
case PENDING = 'pending’;
case RETURNED = 'returned';
case PUBLISHED = 'published';
}
class Post {
private int $id;
private string $title;
private PostStatus $status;
public function __construct(
int $id,
string $title,
PostStatus $status
) {
// ...
}
public function getStatus(): PostStatus {
return $this->status;
}
public function updateStatus(
PostStatus $status
): void {
}
}
$result = [
'id' => 42,
'title' => 'PHP Enums',
'post_status' => 'published',
];
$post = new Post(
$result['id'],
$result['title']
);
$post->updateStatus(
PostStatus::from($result['post_status'])
);
Trying out Enums today
Trying out Enums today
Try it online with 3v4l.org
Trying out Enums today
Nightly Docker Images
docker pull phpdaily/php:8.1-dev
Trying out Enums today
Self-compile PHP from source
$ git clone git@github.com:php/php-src.git
$ ./buildconf
$ ./configure
$ make -j$(nproc)
$ ./sapi/cli/php -a
https://php.watch/articles/compile-php-ubuntu
Backwards Compatibility
Backwards Compatibility
Enums is a new syntax
Enums is a new syntax introduced in PHP 8.1, and not
supported in older PHP versions.
Parse error: syntax error, unexpected identifier "PostStatus"
Backwards Compatibility
User-land PHP implementations
https://github.com/myclabs/php-enum
use MyCLabsEnumEnum;
class PostStatus extends Enum {
private const DRAFT = 'draft';
private const PENDING = 'pending';
private const RETURNED = 'returned';
private const PUBLISHED = 'published';
}
Further Resources
• https://aye.sh/talk/php-enums-phpjp-2021
• https://php.watch/versions/8.1/enums
• https://php.watch/versions/8.1
• https://wiki.php.net/rfc/enumerations
• https://phpinternals.news/73
• https://github.com/php/php-src/pull/6489/
• https://externals.io/message/112626
• https://github.com/phpdaily/php
• https://3v4l.org/
• https://php.watch/articles/compile-php-ubuntu
Questions?
@Ayeshlive ayesh@php.watch
No question is too small.
https://aye.sh/talk/php-enums-phpjp-2021
Thank You
Dank u
dankie
faleminderit
shukran
Շնորհակալություն
hvala
благодаря
gràcies
M
̀ h’gōi
děkuji
tak
tänan
kiitos
Благодаря ти
danke
ευχαριστώ
mahalo
.
‫תודה‬
dhanyavād
köszönöm
takk
terima kasih
grazie
arigatô
cảm ơn bạn
paldies
choukrane
ačiū
Благодарам
grazzi
Xièxiè
Баярлалаа
dziękuję
obrigado
mulţumesc
спасибо
xвала
Ďakujem
gracias
tack
nandri
kop khun
teşekkür ederim
Дякую
diolch
a dank
ngiyabonga
ස්තුතියි
ありがとうございました
PHP 8.1 Enums
Ayesh Karunaratne | https://aye.sh/talk/php-enums-phpjp-2021

More Related Content

What's hot

Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
Lin Yo-An
 
PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13
julien pauli
 

What's hot (20)

Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation Tutorial
 
Opaque Pointers Are Coming
Opaque Pointers Are ComingOpaque Pointers Are Coming
Opaque Pointers Are Coming
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)
 
Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)
 
Introduction in php
Introduction in phpIntroduction in php
Introduction in php
 
php 2 Function creating, calling, PHP built-in function
php 2 Function creating, calling,PHP built-in functionphp 2 Function creating, calling,PHP built-in function
php 2 Function creating, calling, PHP built-in function
 
PHP7 is coming
PHP7 is comingPHP7 is coming
PHP7 is coming
 
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur..."How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
 
Class 3 - PHP Functions
Class 3 - PHP FunctionsClass 3 - PHP Functions
Class 3 - PHP Functions
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
 
New in php 7
New in php 7New in php 7
New in php 7
 
Twig tips and tricks
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
 
Introduction in php part 2
Introduction in php part 2Introduction in php part 2
Introduction in php part 2
 
Cli the other sapi pbc11
Cli the other sapi pbc11Cli the other sapi pbc11
Cli the other sapi pbc11
 
Class 2 - Introduction to PHP
Class 2 - Introduction to PHPClass 2 - Introduction to PHP
Class 2 - Introduction to PHP
 
PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13
 
Php Tutorials for Beginners
Php Tutorials for BeginnersPhp Tutorials for Beginners
Php Tutorials for Beginners
 
Php string function
Php string function Php string function
Php string function
 

Similar to PHP Enums - PHPCon Japan 2021

java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docxjava compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
priestmanmable
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Design
unodelostrece
 

Similar to PHP Enums - PHPCon Japan 2021 (20)

PHP 8.1: Enums
PHP 8.1: EnumsPHP 8.1: Enums
PHP 8.1: Enums
 
Php Enums
Php EnumsPhp Enums
Php Enums
 
Intermediate PHP
Intermediate PHPIntermediate PHP
Intermediate PHP
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
PHP7 - Scalar Type Hints & Return Types
PHP7 - Scalar Type Hints & Return TypesPHP7 - Scalar Type Hints & Return Types
PHP7 - Scalar Type Hints & Return Types
 
Internationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP Applications
 
Solid principles
Solid principlesSolid principles
Solid principles
 
Advanced PHPUnit Testing
Advanced PHPUnit TestingAdvanced PHPUnit Testing
Advanced PHPUnit Testing
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docxjava compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
 
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze..."Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Design
 

Recently uploaded

Breaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdfBreaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdf
UK Journal
 

Recently uploaded (20)

Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
Breaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdfBreaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdf
 
Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 Warsaw
 
Using IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & IrelandUsing IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & Ireland
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024
 
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfSimplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM Performance
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří Karpíšek
 
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfLinux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
 
Intro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджераIntro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджера
 
Syngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdfSyngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdf
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John Staveley
 
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfHow Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 
ECS 2024 Teams Premium - Pretty Secure
ECS 2024   Teams Premium - Pretty SecureECS 2024   Teams Premium - Pretty Secure
ECS 2024 Teams Premium - Pretty Secure
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
 

PHP Enums - PHPCon Japan 2021

  • 1. PHP 8.1 Enums Ayesh Karunaratne | https://aye.sh/talk/php-enums-phpjp-2021
  • 2. PHP 8.1 Enums Ayesh Karunaratne | https://aye.sh/talk/php-enums-phpjp-2021
  • 3. @Ayeshlive | @phpwch https://aye.sh | https://php.watch Ayesh Karunaratne Freelance Software Developer, Security Researcher, Full-time traveler ayesh@aye.sh Kandy, Sri Lanka - Everywhere
  • 8. PHP 8.1 Enumerations: RFC Created 04 Dec 2020 25 Nov 2021 03 Feb 2021 Voting started 17 Feb 2021 Voting ended: 44:7 03 Oct 2021 PHP Conference Japan 2021
  • 9. Why we need Enums How Enums can help Enums in PHP 8.1 Enum Semantics Usage Examples Trying out Enums today Backwards Compatibility PHP 8.1: Enums
  • 10. Why we need Enums
  • 11. $handle = curl_init(); $options = [ CURLOPT_URL => 'https://example.com', CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, CURLOPT_RETURNTRANSFER => true, ]; curl_setopt_array($handle, $options); curl_exec($handle); Why we need Enums
  • 12. $handle = curl_init(); $options = [ CURLOPT_URL => 'https://example.com', CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, CURLOPT_RETURNTRANSFER => true, ]; curl_setopt_array($handle, $options); curl_exec($handle); Why we need Enums
  • 13. $handle = curl_init(); $options = [ CURLOPT_URL => 'https://example.com', CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, CURLOPT_RETURNTRANSFER => true, ]; var_dump($options); curl_setopt_array($handle, $options); curl_exec($handle); Why we need Enums
  • 14. $handle = curl_init(); $options = [ CURLOPT_URL => 'https://example.com', CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, CURLOPT_RETURNTRANSFER => true, ]; var_dump($options); curl_setopt_array($handle, $options); curl_exec($handle); array(3) { [10002]=> string(19) "https://example.com" [84]=> int(3) [19913]=> bool(true) } Why we need Enums
  • 15. $handle = curl_init(); $options = [ CURLOPT_URL => 'https://example.com', CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, CURLOPT_RETURNTRANSFER => true, ]; var_dump($options); curl_setopt_array($handle, $options); curl_exec($handle); array(3) { [10002]=> string(19) "https://example.com" [84]=> int(3) [19913]=> bool(true) } define ('CURLOPT_URL', 10002); define ('CURLOPT_HTTP_VERSION', 84); define ('CURL_HTTP_VERSION_1_1', 2); define ('CURL_HTTP_VERSION_2_0', 3); define ('CURLOPT_RETURNTRANSFER', 19913); Why we need Enums
  • 16. $handle = curl_init(); $options = [ CURLOPT_URL => 'https://example.com', CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, CURLOPT_RETURNTRANSFER => true, ]; var_dump($options); curl_setopt_array($handle, $options); curl_exec($handle); array(3) { [10002]=> string(19) "https://example.com" [84]=> int(3) [19913]=> bool(true) } define ('CURLOPT_URL', 10002); define ('CURLOPT_HTTP_VERSION', 84); define ('CURL_HTTP_VERSION_1_1', 2); define ('CURL_HTTP_VERSION_2_0', 3); define ('CURLOPT_RETURNTRANSFER', 19913); Why we need Enums
  • 17. $handle = curl_init(); $options = [ CURLOPT_URL => 'https://example.com', CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, CURLOPT_RETURNTRANSFER => true, ]; var_dump($options); curl_setopt_array($handle, $options); curl_exec($handle); array(3) { [10002]=> string(19) "https://example.com" [84]=> int(3) [19913]=> bool(true) } define ('CURLOPT_URL', 10002); define ('CURLOPT_HTTP_VERSION', 84); define ('CURL_HTTP_VERSION_1_1', 2); define ('CURL_HTTP_VERSION_2_0', 3); define ('CURLOPT_RETURNTRANSFER', 19913); Why we need Enums
  • 18. function curl_setopt(CurlHandle $handle, int $option, mixed $value) : bool {} Why we need Enums
  • 19. Why we need Enums function curl_setopt(CurlHandle $handle, int $option, mixed $value) : bool {}
  • 20. curl_setopt($handle, 10003, 'https://example.com'); PHP Error: curl_setopt(): Argument #2 ($option) is not a valid cURL option in … on line … curl_setopt($handle, 10002, 'https://example.com'); 10002 - CURLOPT_URL curl_setopt($handle, 10004, 'https://example.com'); 10004 - CURLOPT_PROXY Why we need Enums function curl_setopt(CurlHandle $handle, int $option, mixed $value) : bool {}
  • 21. class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public string $status; public function updateStatus(string $status): void {} } Why we need Enums
  • 22. class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public string $status; public function updateStatus(string $status): void {} } $post = new Post(); $post->updateStatus(Post::POST_STATUS_PUBLISHED); Why we need Enums
  • 23. class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public string $status; public function updateStatus(string $status): void {} } $post = new Post(); $post->updateStatus('returned'); Why we need Enums
  • 24. class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public string $status; public function updateStatus(string $status): void {} } $post = new Post(); $post->updateStatus('returned'); Why we need Enums
  • 25. class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public string $status; public function updateStatus(string $status): void {} } Why we need Enums
  • 26. class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public string $status; public function updateStatus(string $status): void { if ( $status !== static::POST_STATUS_DRAFT && $status !== static::POST_STATUS_PENDING && $status !== static::POST_STATUS_RETURNED && $status !== static::POST_STATUS_PUBLISHED ) { throw new InvalidArgumentException('Invalid state'); } } } Why we need Enums
  • 27. class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public string $status; public function updateStatus(string $status): void { if ( $status !== static::POST_STATUS_DRAFT && $status !== static::POST_STATUS_PENDING && $status !== static::POST_STATUS_RETURNED && $status !== static::POST_STATUS_PUBLISHED ) { throw new InvalidArgumentException('Invalid state'); } } } Why we need Enums https://en.wikipedia.org/wiki/Open-closed_principle
  • 29. How Enums Can Help type PostStatus = "draft" | "pending" | "returned" | "published";
  • 30. How Enums Can Help type PostStatus = "draft" | "pending" | "returned" | "published"; function updateStatus(status: PostStatus) {}
  • 31. How Enums Can Help type PostStatus = "draft" | "pending" | "returned" | "published"; function updateStatus(status: PostStatus) {}
  • 32. How Enums Can Help type PostStatus = "draft" | "pending" | "returned" | "published"; function updateStatus(status: PostStatus) {} updateStatus("potato"); Argument of type '"potato"' is not assignable to parameter of type 'PostStatus'. updateStatus("draft"); ✔️
  • 34. How Enums Can Help enum PostStatus { DRAFT, PENDING, PUBLISHED, RETURNED, }; function updateStatus(status: PostStatus) { } updateStatus(PostStatus.DRAFT);
  • 35. How Enums Can Help enum PostStatus { DRAFT = "draft", PENDING = "pending", PUBLISHED = "published", RETURNED = "draft", }; function updateStatus(status: PostStatus) { } updateStatus(PostStatus.DRAFT);
  • 36. How Enums Can Help enum PostStatus { DRAFT = "draft", PENDING = "pending", PUBLISHED = "published", RETURNED = "draft", }; enum PostStatus { DRAFT = "draft"; PENDING = "pending"; PUBLISHED = "published"; RETURNED = "draft"; };
  • 37. enum PostStatus { } How Enums Can Help
  • 38. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } How Enums Can Help
  • 39. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public string $status; public function updateStatus(string $status): void { if ( $status !== static::POST_STATUS_DRAFT && $status !== static::POST_STATUS_PENDING && $status !== static::POST_STATUS_RETURNED && $status !== static::POST_STATUS_PUBLISHED ) { throw new InvalidArgumentException('Invalid state'); } } } $post = new Post(); $post->updateStatus(Post::POST_STATUS_PUBLISHED); How Enums Can Help
  • 40. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public string $status; public function updateStatus(string $status): void { if ( $status !== static::POST_STATUS_DRAFT && $status !== static::POST_STATUS_PENDING && $status !== static::POST_STATUS_RETURNED && $status !== static::POST_STATUS_PUBLISHED ) { throw new InvalidArgumentException('Invalid state'); } } } $post = new Post(); $post->updateStatus(Post::POST_STATUS_PUBLISHED); How Enums Can Help
  • 41. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public string $status; public function updateStatus(string $status): void { if ( $status !== static::POST_STATUS_DRAFT && $status !== static::POST_STATUS_PENDING && $status !== static::POST_STATUS_RETURNED && $status !== static::POST_STATUS_PUBLISHED ) { throw new InvalidArgumentException('Invalid state'); } } } $post = new Post(); $post->updateStatus(Post::POST_STATUS_PUBLISHED); How Enums Can Help
  • 42. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public PostStatus $status; public function updateStatus(string $status): void { if ( $status !== static::POST_STATUS_DRAFT && $status !== static::POST_STATUS_PENDING && $status !== static::POST_STATUS_RETURNED && $status !== static::POST_STATUS_PUBLISHED ) { throw new InvalidArgumentException('Invalid state'); } } } $post = new Post(); $post->updateStatus(Post::POST_STATUS_PUBLISHED); How Enums Can Help
  • 43. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public PostStatus $status; public function updateStatus(PostStatus $status): void { if ( $status !== static::POST_STATUS_DRAFT && $status !== static::POST_STATUS_PENDING && $status !== static::POST_STATUS_RETURNED && $status !== static::POST_STATUS_PUBLISHED ) { throw new InvalidArgumentException('Invalid state'); } } } $post = new Post(); $post->updateStatus(Post::POST_STATUS_PUBLISHED); How Enums Can Help
  • 44. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public PostStatus $status; public function updateStatus(PostStatus $status): void { if ( $status !== static::POST_STATUS_DRAFT && $status !== static::POST_STATUS_PENDING && $status !== static::POST_STATUS_RETURNED && $status !== static::POST_STATUS_PUBLISHED ) { throw new InvalidArgumentException('Invalid state'); } } } $post = new Post(); $post->updateStatus(Post::POST_STATUS_PUBLISHED); How Enums Can Help
  • 45. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public PostStatus $status; public function updateStatus(PostStatus $status): void { if ( $status !== static::POST_STATUS_DRAFT && $status !== static::POST_STATUS_PENDING && $status !== static::POST_STATUS_RETURNED && $status !== static::POST_STATUS_PUBLISHED ) { throw new InvalidArgumentException('Invalid state'); } } } $post = new Post(); $post->updateStatus(Post::POST_STATUS_PUBLISHED); How Enums Can Help
  • 46. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } class Post { public const POST_STATUS_DRAFT = 'draft'; public const POST_STATUS_PENDING = 'pending'; public const POST_STATUS_RETURNED = 'returned'; public const POST_STATUS_PUBLISHED = 'published'; public PostStatus $status; public function updateStatus(PostStatus $status): void { if ( $status !== static::POST_STATUS_DRAFT && $status !== static::POST_STATUS_PENDING && $status !== static::POST_STATUS_RETURNED && $status !== static::POST_STATUS_PUBLISHED ) { throw new InvalidArgumentException('Invalid state'); } } } $post = new Post(); $post->updateStatus(PostStatus::PUBLISHED); How Enums Can Help
  • 47. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } class Post { public PostStatus $status; public function updateStatus(PostStatus $status): void { } } $post = new Post(); $post->updateStatus(PostStatus::PUBLISHED); How Enums Can Help
  • 48. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } function setIsSponsored(bool $sponsored): void { } function isSponsored(): bool { } setIsSponsored(true); setIsSponsored(false); How Enums Can Help
  • 50. Enums in PHP 8.1 enum Suit { } • Enums can have zero or more members
  • 51. Enums in PHP 8.1 enum Suit { case Clubs; case Diamonds; case Spades; case Hearts; } • Enums can have zero or more members
  • 52. Enums in PHP 8.1 enum Suit { case Clubs; case Diamonds; case Spades; case Hearts; } • Enums can have zero or more members • Enum members are objects is_object(Suit::Hearts); // true
  • 53. Enums in PHP 8.1 enum Suit { case Clubs; case Diamonds; case Spades; case Hearts; } • Enums can have zero or more members • Enum members are objects var_dump(Suit::Hearts); // enum(Suit::Hearts)
  • 54. Enums in PHP 8.1 namespace AppPlayingCards; enum Suit { case Clubs; case Diamonds; case Spades; case Hearts; } • Enums can have zero or more members • Enum members are objects • Enums can be namespaced and autoloaded
  • 55. Enums in PHP 8.1 namespace AppPlayingCards; enum Suit: int { case Clubs = 1; case Diamonds = 2; case Spades = 3; case Hearts = 4; } • Enums can have zero or more members • Enum members are objects • Enums can be namespaced and autoloaded • May contain string|int backed values
  • 56. Enums in PHP 8.1 namespace AppPlayingCards; enum Suit: string { case Clubs = '♣️'; case Diamonds = '♦️'; case Spades = '♠️'; case Hearts = '♥️'; } • Enums can have zero or more members • Enum members are objects • Enums can be namespaced and autoloaded • May contain string|int backed values
  • 57. Enums in PHP 8.1 namespace AppPlayingCards; enum Suit: string { const AWESOME = 'Yes'; case Clubs = '♣️'; case Diamonds = '♦️'; case Spades = '♠️'; case Hearts = '♥️'; } • Enums can have zero or more members • Enum members are objects • Enums can be namespaced and autoloaded • May contain string|int backed values • May contain non-duplicated constants
  • 58. Enums in PHP 8.1 namespace AppPlayingCards; enum Suit: string { const AWESOME = 'Yes'; case Clubs = '♣️'; case Diamonds = '♦️'; case Spades = '♠️'; case Hearts = '♥️'; public static function cheer(): void { echo 'Yay!'; } } • Enums can have zero or more members • Enum members are objects • Enums can be namespaced and autoloaded • May contain string|int backed values • May contain non-duplicated constants • May contain static methods Suit::cheer(); // Yay!
  • 59. Enums in PHP 8.1 namespace AppPlayingCards; enum Suit: string { const AWESOME = 'Yes'; case Clubs = ' '; case Diamonds = ' '; case Spades = ' '; case Hearts = ' '; public static function cheer(): void { echo 'Yay!'; } public function show(): void { var_dump($this); var_dump($this->name); var_dump(self::Clubs->name); var_dump($this->value); var_dump(self::Clubs->value); } } • Enums can have zero or more members • Enum members are objects • Enums can be namespaced and autoloaded • May contain string|int backed values • May contain non-duplicated constants • May contain static methods • May contain non-static methods Suit::Clubs->show();
  • 60. Enums in PHP 8.1 namespace AppPlayingCards; enum Suit: string { const AWESOME = 'Yes'; case Clubs = ' '; case Diamonds = ' '; case Spades = ' '; case Hearts = ' '; public static function cheer(): void { echo 'Yay!'; } public function show(): void { var_dump($this); var_dump($this->name); var_dump(self::Clubs->name); var_dump($this->value); var_dump(self::Clubs->value); } } • Enums can have zero or more members • Enum members are objects • Enums can be namespaced and autoloaded • May contain string|int backed values • May contain non-duplicated constants • May contain static methods • May contain non-static methods • $this refers to the Enumerated element Suit::Clubs->show(); enum(AppPlayingCardsSuit::Clubs)
  • 61. Enums in PHP 8.1 namespace AppPlayingCards; enum Suit: string { const AWESOME = 'Yes'; case Clubs = ' '; case Diamonds = ' '; case Spades = ' '; case Hearts = ' '; public static function cheer(): void { echo 'Yay!'; } public function show(): void { var_dump($this); var_dump($this->name); var_dump(self::Clubs->name); var_dump($this->value); var_dump(self::Clubs->value); } } • Enums can have zero or more members • Enum members are objects • Enums can be namespaced and autoloaded • May contain string|int backed values • May contain non-duplicated constants • May contain static methods • May contain non-static methods • $this refers to the Enumerated element • ->nameproperty is the name of the member Suit::Clubs->show(); enum(AppPlayingCardsSuit::Clubs) string(5) "Clubs" string(5) "Clubs"
  • 62. Enums in PHP 8.1 namespace AppPlayingCards; enum Suit: string { const AWESOME = 'Yes'; case Clubs = ' '; case Diamonds = ' '; case Spades = ' '; case Hearts = ' '; public static function cheer(): void { echo 'Yay!'; } public function show(): void { var_dump($this); var_dump($this->name); var_dump(self::Clubs->name); var_dump($this->value); var_dump(self::Clubs->value); } } • Enums can have zero or more members • Enum members are objects • Enums can be namespaced and autoloaded • May contain string|int backed values • May contain non-duplicated constants • May contain static methods • May contain non-static methods • $this refers to the Enumerated element • ->nameproperty is the name of the member • ->value property is the backed value Suit::Clubs->show(); enum(AppPlayingCardsSuit::Clubs) string(5) "Clubs" string(5) "Clubs" string(6) "♣️" string(6) "♣️"
  • 63. Enums in PHP 8.1 namespace AppPlayingCards; enum Suit: string { const AWESOME = 'Yes'; case Clubs = ' '; case Diamonds = ' '; case Spades = ' '; case Hearts = ' '; public static function cheer(): void { echo 'Yay!'; } public function show(): void { var_dump($this); var_dump($this->name); var_dump(self::Clubs->name); var_dump($this->value); var_dump(self::Clubs->value); } } • Enums can have zero or more members • Enum members are objects • Enums can be namespaced and autoloaded • May contain string|int backed values • May contain non-duplicated constants • May contain static methods • May contain non-static methods • $this refers to the Enumerated element • ->nameproperty is the name of the member • ->value property is the backed value Suit::Clubs->show(); enum(AppPlayingCardsSuit::Clubs) string(5) "Clubs" string(5) "Clubs" string(6) "♣️" string(6) "♣️"
  • 64. enum PostStatus { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } Enums in PHP 8.1 Unit Enums
  • 65. enum PostStatus implements UnitEnum { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } Enums in PHP 8.1 Unit Enums
  • 66. enum PostStatus implements UnitEnum { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } interface UnitEnum { public static function cases(): array; } Enums in PHP 8.1 Unit Enums
  • 67. enum PostStatus implements UnitEnum { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } interface UnitEnum { public static function cases(): array; } Enums in PHP 8.1 Unit Enums echo PostStatus::DRAFT->name; // "DRAFT"
  • 68. enum PostStatus implements UnitEnum { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } interface UnitEnum { public static function cases(): array; } Enums in PHP 8.1 Unit Enums echo PostStatus::DRAFT->name; // "DRAFT"
  • 69. enum PostStatus implements UnitEnum { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } interface UnitEnum { public static function cases(): array; } Enums in PHP 8.1 Unit Enums echo PostStatus::DRAFT->name; // "DRAFT" PostStatus::cases();
  • 70. enum PostStatus implements UnitEnum { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } interface UnitEnum { public static function cases(): array; } Enums in PHP 8.1 Unit Enums echo PostStatus::DRAFT->name; // "DRAFT" array(4) { [0]=> enum(PostStatus::DRAFT) [1]=> enum(PostStatus::PENDING) [2]=> enum(PostStatus::RETURNED) [3]=> enum(PostStatus::PUBLISHED) } PostStatus::cases();
  • 71. enum PostStatus implements UnitEnum { case DRAFT; case PENDING; case RETURNED; case PUBLISHED; } interface UnitEnum { public static function cases(): array; } Enums in PHP 8.1 Unit Enums echo PostStatus::DRAFT->name; // "DRAFT" array(4) { [0]=> enum(PostStatus::DRAFT) [1]=> enum(PostStatus::PENDING) [2]=> enum(PostStatus::RETURNED) [3]=> enum(PostStatus::PUBLISHED) } PostStatus::cases();
  • 72. enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; } Backed Enums extend Unit Enums Backed Enums Enums in PHP 8.1
  • 73. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums
  • 74. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from(int|string $value): static; public static function tryFrom(int|string $value): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums
  • 75. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from( int|string $value ): static; public static function tryFrom( int|string $value ): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums echo PostStatus::DRAFT->name; // "DRAFT"
  • 76. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from( int|string $value ): static; public static function tryFrom( int|string $value ): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums echo PostStatus::DRAFT->name; // "DRAFT"
  • 77. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from( int|string $value ): static; public static function tryFrom( int|string $value ): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums echo PostStatus::DRAFT->name; // "DRAFT" echo PostStatus::DRAFT->value; // "draft"
  • 78. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from( int|string $value ): static; public static function tryFrom( int|string $value ): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums echo PostStatus::DRAFT->name; // "DRAFT" echo PostStatus::DRAFT->value; // "draft" PostStatus::tryFrom('draft'); PostStatus::from('draft');
  • 79. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from( int|string $value ): static; public static function tryFrom( int|string $value ): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums echo PostStatus::DRAFT->name; // "DRAFT" echo PostStatus::DRAFT->value; // "draft" PostStatus::tryFrom('draft'); PostStatus::from('draft');
  • 80. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from( int|string $value ): static; public static function tryFrom( int|string $value ): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums echo PostStatus::DRAFT->name; // "DRAFT" echo PostStatus::DRAFT->value; // "draft" PostStatus::tryFrom('draft'); PostStatus::from('draft');
  • 81. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from( int|string $value ): static; public static function tryFrom( int|string $value ): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums echo PostStatus::DRAFT->name; // "DRAFT" echo PostStatus::DRAFT->value; // "draft" PostStatus::tryFrom('draft'); PostStatus::from('draft'); enum(PostStatus::DRAFT)
  • 82. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from( int|string $value ): static; public static function tryFrom( int|string $value ): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums echo PostStatus::DRAFT->name; // "DRAFT" echo PostStatus::DRAFT->value; // "draft" PostStatus::tryFrom('draft'); PostStatus::from('draft'); enum(PostStatus::DRAFT) PostStatus::tryFrom('potato'); PostStatus::from('potato');
  • 83. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from( int|string $value ): static; public static function tryFrom( int|string $value ): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums echo PostStatus::DRAFT->name; // "DRAFT" echo PostStatus::DRAFT->value; // "draft" PostStatus::tryFrom('draft'); PostStatus::from('draft'); enum(PostStatus::DRAFT) PostStatus::tryFrom('potato'); PostStatus::from('potato');
  • 84. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from( int|string $value ): static; public static function tryFrom( int|string $value ): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums echo PostStatus::DRAFT->name; // "DRAFT" echo PostStatus::DRAFT->value; // "draft" PostStatus::tryFrom('draft'); PostStatus::from('draft'); enum(PostStatus::DRAFT) PostStatus::tryFrom('potato'); // null PostStatus::from('potato'); Uncaught ValueError: "potato" is not a valid backing value for enum "PostStatus"
  • 85. enum PostStatus: string implements BackedEnum { case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published'; } interface BackedEnum extends UnitEnum { public static function from( int|string $value ): static; public static function tryFrom( int|string $value ): ?static; } Enums in PHP 8.1 Backed Enums extend Unit Enums Backed Enums echo PostStatus::DRAFT->name; // "DRAFT" echo PostStatus::DRAFT->value; // "draft" PostStatus::tryFrom('draft'); PostStatus::from('draft'); enum(PostStatus::DRAFT) PostStatus::tryFrom('potato'); // null PostStatus::from('potato'); Uncaught ValueError: "potato" is not a valid backing value for enum "PostStatus"
  • 87. Enum Semantics Enum Enumerated type that contains a fixed number of members.
  • 88. Enum Semantics Enum Enumerated type that contains a fixed number of members. A type that is supported as parameter, return, and property type in PHP, and the type is enforced by PHP itself.
  • 89. Enum Semantics Enum Enumerated type that contains a fixed number of members. All members are contained within a declared Enum.
  • 90. Enum Semantics Enum Enumerated type that contains a fixed number of members. Members of an Enum is fixed at the declaration time. An enumerated member is identical to the same member everywhere. Enums must not contain state.
  • 91. Enum Semantics Enumerated types enum Suit { case Spades; case Hearts; case Clubs; case Diamonds; } function play_card(Suit $suit, string $card) {} function pick_a_suit(): Suit { return Suit::Spades; } play_card(Suit::Spades, 'A'); var_dump(pick_a_suit()); // enum(Suit::Spades)
  • 92. Enum Semantics enum Suit { case Spades; case Hearts; case Clubs; case Diamonds; } function play_card(Suit $suit, string $card) {} function pick_a_suit(): Suit { return Suit::Spades; } play_card(Fruits::Apple); play_card(Languages::English); play_card('potato'); Fatal error: Uncaught TypeError: play_card(): Argument #1 ($suit) must be of type Suit, string given Enumerated types
  • 93. Enum Semantics enum Suit { case Spades; case Hearts; case Clubs; case Diamonds; } Closed Set
  • 94. Enum Semantics enum Suit { case Spades; case Hearts; case Clubs; case Diamonds; } Fixed Members Suit::Spades === Suit::Spades
  • 95. Enum Semantics enum Suit { case Spades; case Hearts; case Clubs; case Diamonds; } Fixed Members enum RussianSuit extends Suit {} Parse error: syntax error, unexpected token "extends", expecting "{"
  • 96. Enum Semantics enum Suit { case Spades; case Hearts; case Clubs; case Diamonds; private string $foo; } No Properties Allowed Fatal error: Enums may not include properties
  • 97. Enum Semantics Backed Enums must assign values for all cases enum HTTPMethods: string { case GET; case POST; } Fatal error: Case GET of backed enum HTTPMethods must have a value
  • 98. Enum Semantics Enum cases and values must be unique Fatal error: Cannot redefine class constant Test::FOO enum Test { case FOO; case FOO; } enum Test: string { case FOO = 'baz'; case BAR = 'baz'; } Fatal error: Duplicate value in enum Test for cases FOO and BAR
  • 99. Enum Semantics Class Semantics namespace FooBar; enum PostStatus: string implements EntityStatues { use TestTrait; case DRAFT = 'draft'; case PENDING = 'pending'; case RETURNED = 'returned'; case PUBLISHED = 'published’; public static function showOff(): void { echo __CLASS__ . static::class; } } • Supports namespaces • Supports traits • Supports autoloading • Supports magic constants • Supports instanceof • Supports methods
  • 101. Usage Examples enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; }
  • 102. Usage Examples enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; } class Post { private int $id; private string $title; private PostStatus $status; public function __construct( int $id, string $title, PostStatus $status ) { // ... } public function getStatus(): PostStatus { return $this->status; } }
  • 103. Usage Examples enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; } class Post { private int $id; private string $title; private PostStatus $status; public function __construct( int $id, string $title, PostStatus $status ) { // ... } public function getStatus(): PostStatus { return $this->status; } }
  • 104. Usage Examples enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; } class Post { private int $id; private string $title; private PostStatus $status; public function __construct( int $id, string $title, PostStatus $status ) { // ... } public function getStatus(): PostStatus { return $this->status; } }
  • 105. Usage Examples enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; } class Post { private int $id; private string $title; private PostStatus $status; public function __construct( int $id, string $title, PostStatus $status ) { // ... } public function getStatus(): PostStatus { return $this->status; } }
  • 106. Usage Examples enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; } $stmt = $pdo->prepare(" SELECT * FROM posts WHERE post_status=?"); $stmt->execute([ PostStatus::PUBLISHED->value ]); $post = $stmt->fetch(); class Post { private int $id; private string $title; private PostStatus $status; public function __construct( int $id, string $title, PostStatus $status ) { // ... } public function getStatus(): PostStatus { return $this->status; } }
  • 107. Usage Examples enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; } $stmt = $pdo->prepare(" SELECT * FROM posts WHERE post_status=?"); $stmt->execute([ PostStatus::PUBLISHED->value ]); $post = $stmt->fetch(); class Post { private int $id; private string $title; private PostStatus $status; public function __construct( int $id, string $title, PostStatus $status ) { // ... } public function getStatus(): PostStatus { return $this->status; } }
  • 108. Usage Examples enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; } class Post { private int $id; private string $title; private PostStatus $status; public function __construct( int $id, string $title, PostStatus $status ) { // ... } public function getStatus(): PostStatus { return $this->status; } } $sql = " INSERT INTO posts (id, title, post_status) VALUES (:id, :title, :post_status)"; $stmt= $pdo->prepare($sql); $stmt->execute([ 'id' => $post->getId(), 'title' => $post->getTitle(), 'post_status' => $post->getStatus()->value, ]);
  • 109. Usage Examples enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; } class Post { private int $id; private string $title; private PostStatus $status; public function __construct( int $id, string $title, PostStatus $status ) { // ... } public function getStatus(): PostStatus { return $this->status; } } $sql = " INSERT INTO posts (id, title, post_status) VALUES (:id, :title, :post_status)"; $stmt= $pdo->prepare($sql); $stmt->execute([ 'id' => $post->getId(), 'title' => $post->getTitle(), 'post_status' => $post->getStatus()->value, ]);
  • 110. Usage Examples enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; } class Post { private int $id; private string $title; private PostStatus $status; public function __construct( int $id, string $title, PostStatus $status ) { // ... } public function getStatus(): PostStatus { return $this->status; } public function updateStatus( PostStatus $status ): void { } } $result = [ 'id' => 42, 'title' => 'PHP Enums', 'post_status' => 'published', ]; $post = new Post( $result['id'], $result['title'] ); $post->updateStatus( PostStatus::from($result['post_status']) );
  • 111. Usage Examples enum PostStatus: string { case DRAFT = 'draft'; case PENDING = 'pending’; case RETURNED = 'returned'; case PUBLISHED = 'published'; } class Post { private int $id; private string $title; private PostStatus $status; public function __construct( int $id, string $title, PostStatus $status ) { // ... } public function getStatus(): PostStatus { return $this->status; } public function updateStatus( PostStatus $status ): void { } } $result = [ 'id' => 42, 'title' => 'PHP Enums', 'post_status' => 'published', ]; $post = new Post( $result['id'], $result['title'] ); $post->updateStatus( PostStatus::from($result['post_status']) );
  • 113. Trying out Enums today Try it online with 3v4l.org
  • 114. Trying out Enums today Nightly Docker Images docker pull phpdaily/php:8.1-dev
  • 115. Trying out Enums today Self-compile PHP from source $ git clone git@github.com:php/php-src.git $ ./buildconf $ ./configure $ make -j$(nproc) $ ./sapi/cli/php -a https://php.watch/articles/compile-php-ubuntu
  • 117. Backwards Compatibility Enums is a new syntax Enums is a new syntax introduced in PHP 8.1, and not supported in older PHP versions. Parse error: syntax error, unexpected identifier "PostStatus"
  • 118. Backwards Compatibility User-land PHP implementations https://github.com/myclabs/php-enum use MyCLabsEnumEnum; class PostStatus extends Enum { private const DRAFT = 'draft'; private const PENDING = 'pending'; private const RETURNED = 'returned'; private const PUBLISHED = 'published'; }
  • 119. Further Resources • https://aye.sh/talk/php-enums-phpjp-2021 • https://php.watch/versions/8.1/enums • https://php.watch/versions/8.1 • https://wiki.php.net/rfc/enumerations • https://phpinternals.news/73 • https://github.com/php/php-src/pull/6489/ • https://externals.io/message/112626 • https://github.com/phpdaily/php • https://3v4l.org/ • https://php.watch/articles/compile-php-ubuntu
  • 120. Questions? @Ayeshlive ayesh@php.watch No question is too small. https://aye.sh/talk/php-enums-phpjp-2021
  • 121. Thank You Dank u dankie faleminderit shukran Շնորհակալություն hvala благодаря gràcies M ̀ h’gōi děkuji tak tänan kiitos Благодаря ти danke ευχαριστώ mahalo . ‫תודה‬ dhanyavād köszönöm takk terima kasih grazie arigatô cảm ơn bạn paldies choukrane ačiū Благодарам grazzi Xièxiè Баярлалаа dziękuję obrigado mulţumesc спасибо xвала Ďakujem gracias tack nandri kop khun teşekkür ederim Дякую diolch a dank ngiyabonga ස්තුතියි ありがとうございました
  • 122. PHP 8.1 Enums Ayesh Karunaratne | https://aye.sh/talk/php-enums-phpjp-2021