Hướng dẫn php iterate enum - php lặp enum

I want to iterate over enum:

enum Shapes
{
    case RECTANGLE;
    case SQUARE;
    case CIRCLE;
    case OVAL;
}

I get

composer require bensampo/laravel-enum
8 const not defined if I do this:

foreach (Shapes as $shape) { }

The best solution I came with is to manually create array for enum:

$shapes = [
    Shapes::RECTANGLE,
    Shapes::SQUARE,
    Shapes::CIRCLE,
    Shapes::OVAL,
];
foreach ($shapes as $shape) { }

Is there any better way to iterate over the enum?

Giới thiệu

Chào mọi người, sau một tháng thì mình đã trở lại đây (hehe).

Nếu như các bạn đã từng làm việc với các ngôn ngữ như Java, C#, C++,... thì hẳn là các bạn không còn xa lại gì với

composer require bensampo/laravel-enum
9. Còn đối với các bạn chưa từng nghe qua
composer require bensampo/laravel-enum
9 thì không sao bởi vì trong bài viết này chúng ta sẽ cùng tìm hiểu về
composer require bensampo/laravel-enum
9 và cách sử dụng
composer require bensampo/laravel-enum
9 trong
BenSampo\Enum\EnumServiceProvider
3 với pagake
BenSampo\Enum\EnumServiceProvider
4.

Enum là gì?

composer require bensampo/laravel-enum
9 là một kiểu dữ liệu đặc biệt, thường sử dụng cho việc định nghĩa một tập hợp cho các hằng số có giá trị cố định. Ví dụ như:

  • Các ngày trong tuần (Monday, Tuesday, ... Sunday)
  • Giới tính (Man, Woman, Other)
  • Các mùa trong năm (Spring, Summer, Autumn, Winter)
  • .....

Lợi ích của

composer require bensampo/laravel-enum
9:

  • Giảm các lỗi gây ra bởi chuyển đổi số hoặc nhập sai số.
  • Thuận lợi cho việc quản lý, dễ dàng thay đổi các giá trị trong tương lai.
  • Làm cho code tường minh hơn, dễ đọc hơn, giảm việc xuất hiện bug.

  • .....

Lợi ích của

composer require bensampo/laravel-enum
9:

Giảm các lỗi gây ra bởi chuyển đổi số hoặc nhập sai số.

Thuận lợi cho việc quản lý, dễ dàng thay đổi các giá trị trong tương lai.

Làm cho code tường minh hơn, dễ đọc hơn, giảm việc xuất hiện bug.

Tuy nhiên

BenSampo\Enum\EnumServiceProvider
7 nói chung và
BenSampo\Enum\EnumServiceProvider
3 nói riêng lại không hỗ trợ trực tiếp
composer require bensampo/laravel-enum
9, nhưng dù vậy chúng ta vẫn có thể sử dụng
composer require bensampo/laravel-enum
9 gián tiếp bằng các hằng số (const) trong các class.
Laravel >= 5.4 và PHP >= 7.1

Trong

BenSampo\Enum\EnumServiceProvider
3có một package vô cùng hữu ích hỗ trợ việc tạo và sử dụng
composer require bensampo/laravel-enum
9 đó là
BenSampo\Enum\EnumServiceProvider
4. Chúng ta cùng tìm hiểu package hữu ích này nhé.

composer require bensampo/laravel-enum

Laravel Enum

BenSampo\Enum\EnumServiceProvider

Cài đặt

Yêu cầu: Laravel >= 5.4 và PHP >= 7.1

  • Bạn hãy mở terminal lên và chạy lệnh sau để cài đặt package:
  • Nếu bạn sử dụng Laravel < 5.5, thì bạn cần copy dòng sau đây và thêm vào
    php artisan make:enum UserRole
    
    4 trong file
    php artisan make:enum UserRole
    
    5:
  • Tạo Enum và sử dụng

Ví dụ đặt ra: Giả sử trong hệ thống của mình, User có 3 quyền (role) với các giá trị tương ứng lưu trong DB là :

Administrator = 0

php artisan make:enum UserRole

Moderator = 1

<?php

namespace App\Enums;

use BenSampo\Enum\Enum;

final class UserRole extends Enum
{
    const Administrator = 1;
    const Moderator = 2;
    const Member = 3;
}

Member = 2

UserRole::Administrator  // return 0

Thông thường các bạn sẽ dùng file

php artisan make:enum UserRole
6 để quản lý các giá trị này để nhằm mục đích dễ dàng thay đổi khi cần thiết.
composer require bensampo/laravel-enum
9 cũng có tác dụng tương tự, ngoài ra nó còn làm cho code trờ nên tường mình hơn. Ở ví dụ này mình sẽ sử dụng
composer require bensampo/laravel-enum
9 nhé:

use App\Enums\UserRole;

Mình sẽ tạo một

composer require bensampo/laravel-enum
9 tên là
<?php

namespace App\Enums;

use BenSampo\Enum\Enum;

final class UserRole extends Enum
{
    const Administrator = 1;
    const Moderator = 2;
    const Member = 3;
}

0 để lưu các quyền của User trong hệ thống và các giá trị tương ứng của nó bằng lệnh sau:

  • Một Enum

    <?php
    
    namespace App\Enums;
    
    use BenSampo\Enum\Enum;
    
    final class UserRole extends Enum
    {
        const Administrator = 1;
        const Moderator = 2;
        const Member = 3;
    }
    
    
    0 sẽ được tạo ra ở trong folder
    <?php
    
    namespace App\Enums;
    
    use BenSampo\Enum\Enum;
    
    final class UserRole extends Enum
    {
        const Administrator = 1;
        const Moderator = 2;
        const Member = 3;
    }
    
    
    2, bạn cần thêm các giá trị role của User vào file này như sau:

    $table->tinyInteger('role')->unsigned()->default(UserRole::Member);
    
  • Vậy là chúng ta đã có một Enum đơn giản, và sử dụng nó cũng vô cùng đơn giản như sau:

    foreach (Shapes as $shape) { }
    
    0
  • Các bạn có thể sử dụng

    composer require bensampo/laravel-enum
    
    9 này ở bất cứ chỗ nào mà bạn muốn. Lưu ý rằng bạn cần phải
    <?php
    
    namespace App\Enums;
    
    use BenSampo\Enum\Enum;
    
    final class UserRole extends Enum
    {
        const Administrator = 1;
        const Moderator = 2;
        const Member = 3;
    }
    
    
    4 Enum
    <?php
    
    namespace App\Enums;
    
    use BenSampo\Enum\Enum;
    
    final class UserRole extends Enum
    {
        const Administrator = 1;
        const Moderator = 2;
        const Member = 3;
    }
    
    
    0 ở đầu mỗi file nhé:

    foreach (Shapes as $shape) { }
    
    1
  • Một số ví dụ về sử dụng Enum đơn giản:

Dùng trong <?php namespace App\Enums; use BenSampo\Enum\Enum; final class UserRole extends Enum { const Administrator = 1; const Moderator = 2; const Member = 3; } 6 để tạo giá trị mặc định cho các cột:

  • Dùng trong các

    <?php
    
    namespace App\Enums;
    
    use BenSampo\Enum\Enum;
    
    final class UserRole extends Enum
    {
        const Administrator = 1;
        const Moderator = 2;
        const Member = 3;
    }
    
    
    7 hay các
    <?php
    
    namespace App\Enums;
    
    use BenSampo\Enum\Enum;
    
    final class UserRole extends Enum
    {
        const Administrator = 1;
        const Moderator = 2;
        const Member = 3;
    }
    
    
    8 để kiểm tra quyền admin của hệ thống:
    : trả về một mảng chứa các key của Enum

    Dùng trong các biểu thức, phương thức, ... ở
    <?php
    
    namespace App\Enums;
    
    use BenSampo\Enum\Enum;
    
    final class UserRole extends Enum
    {
        const Administrator = 1;
        const Moderator = 2;
        const Member = 3;
    }
    
    
    9:
  • ........: trả về một mảng chứa các giá trị của Enum

    foreach (Shapes as $shape) { }
    
    3
  • Các phương thức hỗ trợ: trả về key của

    UserRole::Administrator  // return 0
    
    0

    foreach (Shapes as $shape) { }
    
    4
  • getKeys(): trả về một mảng chứa các key của Enum: trả về giá trị của

    UserRole::Administrator  // return 0
    
    1

    foreach (Shapes as $shape) { }
    
    5
  • foreach (Shapes as $shape) { }
    
    2 : kiểm tra các key trong Enum có chứa
    UserRole::Administrator  // return 0
    
    2 hay không

    foreach (Shapes as $shape) { }
    
    6
  • getValues(): trả về một mảng chứa các giá trị của Enum: kiểm tra các giá trị trong Enum có chứa

    UserRole::Administrator  // return 0
    
    3 hay không. Tham số
    UserRole::Administrator  // return 0
    
    4 dùng để bật/tắt chế độ so sánh tuyệt đối (===), giá trị mặc định của
    UserRole::Administrator  // return 0
    
    4 là false.

    foreach (Shapes as $shape) { }
    
    7
  • getKey(string|int $value): trả về key của

    UserRole::Administrator  // return 0
    
    0 : trả về mô tả của
    UserRole::Administrator  // return 0
    
    0 (giá trị trả về mặc định là key).

    foreach (Shapes as $shape) { }
    
    8

    getValue(string $key): trả về giá trị của

    UserRole::Administrator  // return 0
    
    1

    foreach (Shapes as $shape) { }
    
    9
    $shapes = [
        Shapes::RECTANGLE,
        Shapes::SQUARE,
        Shapes::CIRCLE,
        Shapes::OVAL,
    ];
    foreach ($shapes as $shape) { }
    
    0
  • hasKey(string $key): kiểm tra các key trong Enum có chứa

    UserRole::Administrator  // return 0
    
    2 hay không: trả về một key ngẫu nhiên trong Enum. Phương thức này cực kì hữu dụng khi dùng trong việc
    UserRole::Administrator  // return 0
    
    8.

    $shapes = [
        Shapes::RECTANGLE,
        Shapes::SQUARE,
        Shapes::CIRCLE,
        Shapes::OVAL,
    ];
    foreach ($shapes as $shape) { }
    
    1
  • hasValue(string|int $value, bool $strict = true): kiểm tra các giá trị trong Enum có chứa

    UserRole::Administrator  // return 0
    
    3 hay không. Tham số
    UserRole::Administrator  // return 0
    
    4 dùng để bật/tắt chế độ so sánh tuyệt đối (===), giá trị mặc định của
    UserRole::Administrator  // return 0
    
    4 là false.
    : trả về một giá trị ngẫu nhiên trong Enum. Phương thức này cực kì hữu dụng khi dùng trong việc
    UserRole::Administrator  // return 0
    
    8.

    $shapes = [
        Shapes::RECTANGLE,
        Shapes::SQUARE,
        Shapes::CIRCLE,
        Shapes::OVAL,
    ];
    foreach ($shapes as $shape) { }
    
    2
  • getDescription(string|int $value) : trả về mô tả của

    UserRole::Administrator  // return 0
    
    0 (giá trị trả về mặc định là key).: Enum được trả về dưới dạng một mảng với key và value tương ứng

    $shapes = [
        Shapes::RECTANGLE,
        Shapes::SQUARE,
        Shapes::CIRCLE,
        Shapes::OVAL,
    ];
    foreach ($shapes as $shape) { }
    
    3
  • Bạn cũng có thể

    UserRole::Administrator  // return 0
    
    7 phương thức này để custom giá trị trả về:: trả về một mảng có dạng [value => description].

    $shapes = [
        Shapes::RECTANGLE,
        Shapes::SQUARE,
        Shapes::CIRCLE,
        Shapes::OVAL,
    ];
    foreach ($shapes as $shape) { }
    
    4

    getRandomKey(): trả về một key ngẫu nhiên trong Enum. Phương thức này cực kì hữu dụng khi dùng trong việc

    UserRole::Administrator  // return 0
    
    8.

  • getRandomValue(): trả về một giá trị ngẫu nhiên trong Enum. Phương thức này cực kì hữu dụng khi dùng trong việc

    UserRole::Administrator  // return 0
    
    8.: trả về một thể hiện của Enum

    $shapes = [
        Shapes::RECTANGLE,
        Shapes::SQUARE,
        Shapes::CIRCLE,
        Shapes::OVAL,
    ];
    foreach ($shapes as $shape) { }
    
    5

toArray(): Enum được trả về dưới dạng một mảng với key và value tương ứng

toSelectArray(): trả về một mảng có dạng [value => description].

Phương thức này cực kì hữu ích khi bạn muốn đổ các giá trị role này kèm với đa ngôn ngữ tương ứng ra một

use App\Enums\UserRole;
0 để hiển thị. Đầu tiên bạn
UserRole::Administrator  // return 0
7 phương thức
use App\Enums\UserRole;
2 và custom các giá trị trả về với đa ngôn ngữ, sau đó bạn có thể sử dụng phương thức
use App\Enums\UserRole;
3 này để lấy và đổ ra Select box.

$shapes = [
    Shapes::RECTANGLE,
    Shapes::SQUARE,
    Shapes::CIRCLE,
    Shapes::OVAL,
];
foreach ($shapes as $shape) { }
6

Với thể hiện của Enum thì bạn có thể truy cập trực tiếp đến các thuộc tính của Enum:

$shapes = [
    Shapes::RECTANGLE,
    Shapes::SQUARE,
    Shapes::CIRCLE,
    Shapes::OVAL,
];
foreach ($shapes as $shape) { }
7

Sử dụng thể hiện của Enum làm tham số cho các phương thức:

$shapes = [
    Shapes::RECTANGLE,
    Shapes::SQUARE,
    Shapes::CIRCLE,
    Shapes::OVAL,
];
foreach ($shapes as $shape) { }
8

Trong đó phương thức

use App\Enums\UserRole;
4 dùng để kiểm tra thể hiện Enum có bằng với các giá trị Enum hợp lệ không.

$shapes = [
    Shapes::RECTANGLE,
    Shapes::SQUARE,
    Shapes::CIRCLE,
    Shapes::OVAL,
];
foreach ($shapes as $shape) { }
9

Validation Enum

Bạn có thể validate

use App\Enums\UserRole;
5 và
use App\Enums\UserRole;
6 bằng cách sử dụng các
use App\Enums\UserRole;
7:

  • Bằng Rule:
    composer require bensampo/laravel-enum
    
    0 Đối với
    use App\Enums\UserRole;
    
    8 thì mặc định chế độ so sánh tuyệt đối (===) sẽ được bật (
    use App\Enums\UserRole;
    
    9). Bạn có thể tắt nó đi như sau:
    composer require bensampo/laravel-enum
    
    1
  • Bằng Rule Object:
    composer require bensampo/laravel-enum
    
    2 Tương tự, bạn có thể tắt chế độ so sánh tuyệt đối của
    $table->tinyInteger('role')->unsigned()->default(UserRole::Member);
    
    0:
    composer require bensampo/laravel-enum
    
    3 Lưu ý rằng, nếu bạn dùng
    $table->tinyInteger('role')->unsigned()->default(UserRole::Member);
    
    1 thì bạn cần phải
    <?php
    
    namespace App\Enums;
    
    use BenSampo\Enum\Enum;
    
    final class UserRole extends Enum
    {
        const Administrator = 1;
        const Moderator = 2;
        const Member = 3;
    }
    
    
    4
    $table->tinyInteger('role')->unsigned()->default(UserRole::Member);
    
    3 và
    $table->tinyInteger('role')->unsigned()->default(UserRole::Member);
    
    4 tương ứng ở đầu mỗi file:
    composer require bensampo/laravel-enum
    
    4

Đa ngôn ngữ (Localization)

Ngoài việc sử dụng đa ngôn ngữ với phương thức

$table->tinyInteger('role')->unsigned()->default(UserRole::Member);
5 trong phương thức
use App\Enums\UserRole;
2 ở trên, bạn còn có thể sử dụng tính năng đa ngôn ngữ của
BenSampo\Enum\EnumServiceProvider
4.

Đầu tiên bạn cần tạo file

$table->tinyInteger('role')->unsigned()->default(UserRole::Member);
8 trong các thư mục ngôn ngữ
$table->tinyInteger('role')->unsigned()->default(UserRole::Member);
9 như sau:

  • foreach (Shapes as $shape) { }
    
    00:
    composer require bensampo/laravel-enum
    
    5
  • foreach (Shapes as $shape) { }
    
    01
    composer require bensampo/laravel-enum
    
    6

Sau đó bạn chỉ cần

foreach (Shapes as $shape) { }
02 interface
foreach (Shapes as $shape) { }
03 trong Enum
<?php

namespace App\Enums;

use BenSampo\Enum\Enum;

final class UserRole extends Enum
{
    const Administrator = 1;
    const Moderator = 2;
    const Member = 3;
}

0 là xong:

composer require bensampo/laravel-enum
7

Các mô tả (description) của

composer require bensampo/laravel-enum
9 sẽ tự động thay đổi giá trị tùy theo ngôn ngữ của hệ thống đang dùng.

Kết luận

Qua bài viết trên mình đã giới thiệu cho các bạn

composer require bensampo/laravel-enum
9 cũng như cách sử dụng
composer require bensampo/laravel-enum
9 trong
BenSampo\Enum\EnumServiceProvider
3 với package
BenSampo\Enum\EnumServiceProvider
4. Hy vọng bài viết này sẽ có ích đối với các bạn

Tham khảo

https://github.com/BenSampo/laravel-enum