Giả dụ ai đang làm một dự án công trình mà ứng dụng của mình được áp dụng ở các quốc gia, vậy thì mỗi nơi khác biệt lại bao gồm một múi giờ riêng rẽ (VD như nước ta và Nhật phiên bản múi giờ chênh lệch nhau 2h) dẫn đến sự việc lưu timestamp vào DB sẽ ảnh hưởng conflict với sẽ có những lúc hiển thị time sai.
Vậy cách giải quyết vấn đề này là gì? Thì trong bài viết hôm nay mình xin phía dẫn các bạn set multiple timezone trong project laravel nha! cumming nạ
1. Giới thiệuNhư mọi bạn cũng biết Laravel cũng cấp cho bọn họ folder config - dùng làm chứa những file thông số kỹ thuật cho Laravel. Cùng mặc định khi bạn create 1 project Laravel timezone default sẽ được set khoác định trong file config/app.php và mình bao gồm thể thay đổi nó thành ngẫu nhiên múi giờ nào bạn muốn ạ.
/* |-------------------------------------------------------------------------- | Application Timezone |-------------------------------------------------------------------------- | | Here you may specify the default timezone for your application, which | will be used by the PHP date và date-time functions. We have gone | ahead and set this khổng lồ a sensible mặc định for you out of the box. | */ "timezone" => "UTC",Tuy nhiên lại trở về bài toán ngơi nghỉ trên, vậy nếu mình muốn sử dụng những timezone không giống nhau thì sao? làm giải pháp nào? Thì hiện giờ chúng mình cùng đọc tiếp phần 2 của chính mình nhé!
2. Các bước thực hiện1. Create project
Bước trước tiên mình sẽ tạo 1 project Laravel bằng cách run comman sau:
composer create-project laravel/laravel multi-timezoneTrong ví dụ thử nghiệm này mình bỏ qua quá trình setup và seed data, mình sử dụng luôn luôn table gồm sẵn users.Sau lúc create hoàn thành project mình tìm đến file config/app.php và tìm tới "timezone" nhằm set timezone mang định họ sẽ sử dụng nè. VD ở đây mình đang set timezone mặc định là Tokyo
"timezone" => env("TIMEZONE", "Asia/Tokyo"),Bước tiếp theo bọn họ sẽ create TimeZoneMiddleware và thông số kỹ thuật cho nó nhé!
2. Create TimeZoneMiddleware
Run comman:php artisan make:middleware TimeZoneMiddleware
Sau lúc câu lệnh chạy xong, mình đang đi đk middleware vào app/Http/Kernel.php tại trực thuộc tính $routeMiddleware để gán middleware đó cho một route cầm cố thể.
protected $routeMiddleware = < \ other middlewares "timezone" => AppHttpMiddlewareTimeZoneMiddleware::class, >;PHP cung cấp cho họ hàm date_default_timezone_set() và dùng làm set quý giá timezone cho hệ thống, sau khoản thời gian set thì toàn bộ các hàm xử lí thời gian sẽ sử dụng timezone này.Sau khi thông số kỹ thuật cho TimeZoneMiddleware thì mình gồm một tệp tin app/Http/Middleware/TimeZoneMiddleware.php như sau:
hasHeader("X-Timezone")) ? $request->header("X-Timezone") : config("app.timezone"); date_default_timezone_set($timezone); return $next($request); }}Ở đây mình sẽ tiến hành kiểm tra header request truyền lên. Với nếu k gửi lên X-Timezone thì mình set nó sử dụng giá trị mang định trong tệp tin config/app.php.Ting ting vậy là mình đã đi được nửa đoạn đường rồi đó ạ hí hí.
Xem thêm: Tải Game Lux Ios / Apk - Chắp Cánh Giàu Sang: Luxclub
3. SetAttribute and GetAttribute in BaseModel
Giờ đây các bạn có thể hình dung biện pháp mình giải quyết và xử lý bài toán trên sẽ là trong database của bọn họ mình chỉ lưu trữ dữ liệu timestamp tại một dạng mặc định. Từ đó phụ thuộc timezone truyền lên mà bạn cũng có thể set với get dữ liệu ra đúng thật mình mong muốn.
Laravel đã cung ứng Eloquent: Mutators khá hay - kia là khi chúng ta set hoặc get một attributes nào này đã được định nghĩa thì các lần ta điện thoại tư vấn đến attributes kia đều auto chạy vào function setAttribute/getAttribute. Để hiểu thêm chi tiết các bạn đọc tại đây nhé!Ở phía trên mình gồm tạo 1 BaseModel và model User được extend trường đoản cú đây, trong này còn có viết 2 function setAttribute & getAttribute như sau:
attributes<$key> = Carbon::createFromFormat("Y-m-d H:i:s", $value, $timezone->getTimezone()) ->setTimezone(config("app.timezone")); } return parent::setAttribute($key, $value); } /** * Get an attribute from the model. * *
return mixed */ public function getAttribute($key) $array = < "created_at", "updated_at", >; if (in_array($key, $array)) $timezone = new DateTime("now"); $value = $this->getAttributeValue($key); if (!($value instanceof Carbon)) $value = Carbon::parse($value); return Carbon::createFromFormat("Y-m-d H:i:s", $value, config("app.timezone")) ->setTimezone($timezone->getTimezone()); return parent::getAttribute($key); }Nhìn tên function bọn họ cũng tù mù đoán ra ý nghĩa của chúng đúng k ạ, tuy nhiên mình vẫn sẽ phân tích và lý giải qua một chút nhé:
Và bây giờ muốn sử dụng họ chỉ nên thêm middleware đó vào trc mỗi API bắt buộc dùng với truyền lên Headers X-Token là uki nạ: VD
Route::group(<"prefix" => "v1", "namespace" => "ApiV1", "middleware" => <"timezone">>, function () Route::resource("users", "UsersController"););Sau khi cấu hình xong vớ cả, hiện thời mỗi lần chúng ta create/update mặc định created_at or updated_at sẽ mặc định gửi và giữ time theo múi tiếng Tokyo, thật thuận lợi phải ko ạ.
3. Kết luậnBài viết này mình đã share với số đông người về kiểu cách config khi làm việc với dự án công trình nhiều timezone bằng việc đưa câu hỏi về dạng lưu lại một dạng timezone mặc định vào database. Rất vui được khi được mọi người đọc bài và cỗ vũ ạ
