2014-07-25 39 views
7

Tôi đang làm việc trên một ứng dụng cho phép người dùng chỉnh sửa một số ngày trong biểu mẫu. Ngày được hiển thị theo định dạng Châu Âu (DD-MM-YYYY) trong khi cơ sở dữ liệu sử dụng định dạng YYYY-MM-DD mặc định.Cách xử lý nhập ngày tháng trong Laravel

Có một số cách để mã hóa/giải mã dữ liệu này qua lại từ các cơ sở dữ liệu cho người dùng, nhưng tất cả đều đòi hỏi phải có nhiều mã:

  • Sử dụng một hàm helper để chuyển đổi ngày trước khi lưu và sau khi lấy (rất cồng kềnh, đòi hỏi nhiều code)
  • Tạo một thuộc tính riêng biệt cho từng thuộc tính ngày tháng, và sử dụng các phương pháp setNameAttributegetNameAttribute để giải mã/mã hóa (còn cồng kềnh và xấu xí, đòi hỏi phải có bản dịch thêm/quy tắc cho mỗi thuộc tính)
  • Sử dụng JavaScript để chuyển đổi ngày khi người nói ding và gửi biểu mẫu (không đáng tin cậy)

Vậy cách hiệu quả nhất để lưu trữ, truy xuất và xác thực ngày và giờ từ người dùng là gì?

+0

Bạn có muốn xem liệu bạn có thể đạt được những gì bạn muốn bằng Carbon được tích hợp vào laravel không? – MikeWu

+0

Ngày phân tích chính nó không phải là vấn đề, tôi đã sử dụng Carbon cho điều đó. Vấn đề là nơi để đặt mã để chuyển đổi ngày, tôi không muốn thêm tấn mã chuyển đổi lặp lại trong bộ điều khiển/lượt xem của tôi. Ngoài ra Carbon ném một ngoại lệ khi bạn cố gắng phân tích một ngày có định dạng sai, đây không phải là lý tưởng khi giao dịch với đầu vào của người dùng. – Arne

Trả lời

7

Tại một số thời điểm, bạn phải chuyển đổi ngày từ định dạng chế độ xem sang định dạng cơ sở dữ liệu. Như bạn đã đề cập, có một số nơi để làm điều này, về cơ bản lựa chọn giữa back-end hoặc front-end.

Tôi thực hiện chuyển đổi ở phía máy khách (front-end) bằng javascript (bạn có thể sử dụng http://momentjs.com để trợ giúp việc này). Lý do là bạn có thể cần các định dạng khác nhau tùy thuộc vào ngôn ngữ mà máy khách đang sử dụng (được đặt trong trình duyệt hoặc trong tùy chọn tiểu sử của mình chẳng hạn). Thực hiện chuyển đổi định dạng trong giao diện người dùng cho phép bạn chuyển đổi dễ dàng sang các định dạng ngày khác nhau này.

Một ưu điểm khác là bạn có thể sử dụng thuộc tính protected $dates trong mô hình của bạn để xử lý Laravel (nhận và đặt) những ngày này tự động dưới dạng đối tượng Carbon, mà không cần bạn thực hiện việc này (xem https://github.com/laravel/framework/blob/master/src/Illuminate/Database/Eloquent/Model.php#L126).

Như để xác nhận, bạn cần sau đó có thể sử dụng quy tắc xác nhận built-in Laravel cho ngày tháng, như thế này:

'date' => 'required|date|date_format:Y-n-j' 
+5

"Bạn nên sử dụng ngày hoặc date_format khi xác thực trường, chứ không phải cả hai." - [Laravel Documents] (https://laravel.com/docs/5.2/validation#rule-date-format) – M165437

2

Trong khi client-side là tốt cho UX, nó không cho phép bạn chắc chắn, tất cả sẽ tốt.

Dù sao, bạn cũng sẽ cần xác thực/hội tụ phía máy chủ.

Nhưng đây là điều, nó cũng dễ dàng như thế này:

// after making sure it's valid date in your format 
// $dateInput = '21-02-2014' 

$dateLocale = DateTime::createFromFormat('d-m-Y', $dateInput); 

// or providing users timezone 
$dateLocale = 
    DateTime::createFromFormat('d-m-Y', $dateInput, new DateTime('Europe/London')); 

$dateToSave = $dateLocale 
      // ->setTimeZone(new TimeZone('UTC')) if necessary 
      ->format('Y-m-d'); 

et thì đấy!


Rõ ràng, bạn có thể sử dụng rực rỡ Carbon để làm cho nó thậm chí còn dễ dàng hơn:

$dateToSave = Carbon::createFromFormat('d-m-Y', $dateInput, 'Europe/London') 
     ->tz('UTC') 
     ->toDateString(); // '2014-02-21' 

Validation

Bạn nói rằng Carbon ném ngoại lệ nếu được cung cấp với đầu vào sai .Tất nhiên, nhưng đây là những gì bạn cần để xác nhận ngày:

'regex:/\d{1,2}-\d{1,2}-\d{4}/|date_format:d-m-Y' 

// accepts 1-2-2014, 01-02-2014 
// doesn't accept 01-02-14 

phần regex này là cần thiết, nếu bạn muốn đảm bảo một phần năm là 4digit, vì PHP sẽ xem xét ngày 01-02-14 hợp lệ, mặc dù sử dụng Y nhân vật dạng (thực hiện năm = 0014).

1

Cách tốt nhất tôi tìm thấy là ghi đè fromDateTime từ Eloquent.

class ExtendedEloquent extends Eloquent { 
    public function fromDateTime($value) 
    { 
     // If the value is in simple day, month, year format, we will format it using that setup. 
     // To keep using Eloquent's original fromDateTime method, we'll convert the date to timestamp, 
     // because Eloquent already handle timestamp. 
     if (preg_match('/^(\d{2})\/(\d{2})\/(\d{4})$/', $value)) { 
      $value = Carbon\Carbon::createFromFormat('d/m/Y', $value) 
       ->startOfDay() 
       ->getTimestamp(); 
     } 

     return parent::fromDateTime($value); 
    } 
} 

Tôi mới sử dụng PHP, vì vậy tôi không biết đó có phải là cách tiếp cận tốt nhất hay không. Hy vọng điều đó sẽ hữu ích.

Edit:

Tất nhiên, hãy nhớ để thiết lập tất cả các thuộc tính ngày của bạn trong dates bên trong mô hình của bạn. ví dụ:

protected $dates = array('IssueDate', 'SomeDate'); 
Các vấn đề liên quan