2009-02-28 38 views
8

Người dùng sẽ chọn ngày của họ từ 3 menu thả xuống (ngày, tháng, năm). Tôi sẽ kết hợp chúng ở phía máy chủ để tạo một chuỗi như '2008-12-30'. Làm cách nào tôi có thể xác thực để đảm bảo ngày này ở đúng định dạng/số, v.v ...?Làm cách nào để xác thực Ngày MYSQL bằng PHP?

+0

Bạn có thể tua lại điều này một chút; nó không hoàn toàn rõ ràng những gì bạn đang sau. Bạn có muốn xác thực ngày đến từ truy vấn hay bạn muốn xác thực các thành phần riêng lẻ trước khi chèn chúng vào cơ sở dữ liệu? – Rob

+0

Tôi muốn kết hợp các thành phần của ngày và xác thực ngày kết hợp với cơ sở dữ liệu. –

+1

Tại sao điều này lại bị bỏ phiếu? –

Trả lời

6

Nếu chúng là 3 trình đơn thả xuống riêng biệt, bạn sẽ cần xác thực chúng dưới dạng ba giá trị riêng biệt.

Ie,

  • Validate rằng cột năm là số và giữa bất cứ năm có giá trị trong ứng dụng của bạn
  • Validate rằng cột tháng là số
  • Validate rằng cột ngày là số
  • Xác thực rằng tất cả các giá trị đó đều là giá trị hợp lệ bằng cách sử dụng checkdate()

Hoặc, bạn có thể truyền chúng l đến số nguyên, kết hợp chúng lại với nhau thành một ngày và xem ngày kết quả có hợp lệ hay không. Tức là,

$time = mktime(0, 0, 0, (int)$_POST['month'], (int)$_POST['day'], (int)$_POST['year']); 

// in this example, valid values are between jan 1 2000 (server time) and now 
// modify as required 
if ($time < mktime(0, 0, 0, 1, 1, 2000) || $time > time()) 
    return 'Invalid!'; 

$mysqltime = date('Y-m-d', $time); 

// now insert $mysqltime into database 

Nhược điểm của phương pháp này là nó chỉ hoạt động với các ngày trong khoảng thời gian Unix khoảng 1970 đến 2038 hoặc hơn.

+0

Bạn có thể muốn kiểm tra xem đó có phải là số nguyên không, nếu không phải là số. is_numeric là true cho float cũng như các số nguyên, nhưng is_int chỉ kiểm tra các số nguyên. – gpojd

+0

is_int() không thể hoạt động trên các biến do người dùng gửi, tức là các biến trong $ _POST, bởi vì các biến này luôn là chuỗi kiểu. Bạn có thể, tuy nhiên, đúc chúng vào số nguyên bằng cách sử dụng (int) $ _ POST ['var'] và sau đó lỏng lẻo so sánh với giá trị chuỗi ban đầu (sử dụng ==). – thomasrutter

2

Bạn có thể kiểm tra xem ngày có hợp lệ không bằng cách sử dụng checkdate. Nếu bạn muốn đảm bảo rằng các giá trị là số và độ dài chính xác, bạn có thể làm điều gì đó đơn giản như một số is_int ctype_digit và kết hợp strlen trước khi bạn tạo ngày.

// untested 
if(!ctype_digit)($month) || strlen($month) != 2) { 
    // handle error 
} 
// repeat for $day and $year 
if (checkdate($month, $day, $year) { 
    // do your work 
} 
+0

Tôi đã thay đổi câu trả lời của mình từ is_int thành ctype_digit dựa trên nhận xét của thomasrutter rằng is_int sẽ không xử lý các biến POST một cách chính xác. – gpojd

-1

Nếu bạn có ba menu thả xuống thì giá trị đến từ menu thả xuống phải luôn là số do bạn kiểm soát các giá trị được liên kết với tháng (được hiển thị bên dưới). Điều này sau đó sẽ dẫn đến kết luận rằng kết quả kết hợp là hợp lệ.

<option value="01">January</option> 

Nếu bạn cung cấp cung cấp các mục hỗ trợ trong việc thăng trầm thả như "Chọn một tháng", sau đó bạn có thể làm cho giá trị 0 và đảm bảo rằng các giá trị đến từ mỗi hộp thả là lớn hơn không.

Có khả năng ai đó sẽ thay đổi biểu mẫu HTML để cung cấp các giá trị khác. Nếu đây là một mối quan tâm thì bạn có thể sử dụng hàm PHP ctype_digit() để kiểm tra xem mỗi giá trị được cung cấp có thực sự là một chữ số hay không.

Nếu bạn lo ngại rằng ngày thực sự hợp lệ, hãy sử dụng chức năng checkdate().

+0

Có thể tạo các bài đăng lên kịch bản mà không cần sử dụng biểu mẫu. Tôi có thể viết một bot tạo một bài đăng lên biểu mẫu của bạn và đăng bất kỳ giá trị nào mà tôi đưa vào cho từng trường mà không cần sử dụng biểu mẫu. –

+0

Đó là sự thật đó là lý do tại sao đề nghị sử dụng ctype_digit() và checkdate() có ý nghĩa. Tôi đã căn cứ vào câu trả lời của tôi trên tuyên bố rằng bạn đã có một hình thức. Ngay cả khi bạn sử dụng một tập lệnh, không có nhiều trường hợp trong trường hợp này, trong đó nó sẽ không sử dụng các giá trị trong các biểu mẫu. – Paulo

1

Chỉ gặp vấn đề tương tự. Tôi đã viết một hàm ngắn để kiểm tra xem định dạng có chính xác hay không và nếu ngày đó là có thật:

function valid_mysql_date($str){ 
    $date_parts = explode('-',$str); 
    if (count($date_parts) != 3) return false; 
    if ((strlen($date_parts[0]) != 4) || (!is_numeric($date_parts[0]))) return false; 
    if ((strlen($date_parts[1]) != 2) || (!is_numeric($date_parts[1]))) return false; 
    if ((strlen($date_parts[2]) != 2) || (!is_numeric($date_parts[2]))) return false; 
    if (!checkdate($date_parts[1], $date_parts[2] , $date_parts[0])) return false; 
    return true; 
} 

hy vọng điều đó sẽ hữu ích.

+1

có checkdate(), dude –

+0

vui, bây giờ tôi đang cố gắng hiểu những gì sai với tôi ... :) –

+0

ok bây giờ tôi thấy những gì tôi có nghĩa là, vì tôi chỉ chạy vào cùng một vấn đề ngày hôm nay. checkdate() yêu cầu ba tham số. vì vậy nếu bạn có một chuỗi ngày, nó không giúp bạn. chức năng của tôi nhận được một chuỗi và các định dạng nó và kiểm tra với checkdate() –

17

Cá nhân tôi thấy điều này là các cách chính xác và thanh lịch để xác định xem ngày vừa theo định dạnghợp lệ:

  • xử lý ngày như 20111-03-21 là không hợp lệ - không giống như checkdate()
  • không có cảnh báo PHP nào (nếu có một tham số nào được cung cấp, một cách tự nhiên) - không giống như hầu hết các giải pháp explode()
  • có bước nhảy vọt năm vào tài khoản không giống như các giải pháp regex chỉ
  • hoàn toàn tương thích với các định dạng mysql DATE (10.03.21 cũng giống như 2010-03-21)

Dưới đây là phương pháp mà bạn có thể sử dụng:

/** 
* Tests if a string is a valid mysql date. 
* 
* @param string date to check 
* @return boolean 
*/ 
function validateMysqlDate($date) 
{ 
    return preg_match('#^(?P<year>\d{2}|\d{4})([- /.])(?P<month>\d{1,2})\2(?P<day>\d{1,2})$#', $date, $matches) 
      && checkdate($matches['month'],$matches['day'],$matches['year']); 
} 
+0

Vâng, $ str nên được thay đổi thành $ date ... [function edited] – Ricky

+0

Cảm ơn, bằng cách nào đó cái tôi sử dụng trong sản xuất là chính xác, xin lỗi vì sai lầm. – raveren

+0

tốt! điều này là hữu ích –

4

tôi đang sử dụng chức năng này:

<?php 
function validateMysqlDate($date){ 
    if (preg_match("/^(\d{4})-(\d{2})-(\d{2}) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $date, $matches)) { 
     if (checkdate($matches[2], $matches[3], $matches[1])) { 
      return true; 
     } 
    } 
    return false; 
} 

// check it: 
    $a = validateMysqlDate('2012-12-09 09:04:00'); 
    $b = validateMysqlDate('20122-12-09 09:04:00'); 
    $c = validateMysqlDate('2012-12_09 09:04:00'); 
    $d = validateMysqlDate(''); 
    var_dump($a); 
    var_dump($b); 
    var_dump($c); 
    var_dump($d); 
?> 

$ a là đúng, người khác là sai - và tha t là chính xác

Chức năng từ Raveren (ở trên) sẽ không bao gồm ngày hợp lệ với dấu thời gian !!! $ a trả về false ở đó! Và btw: checkdate() sẽ trả lại giá trị true cho $ b mặc dù nó không phải là ngày giờ mysql hợp lệ

+0

Cảm ơn, chức năng của bạn đã giúp tôi :) –

+0

Điều này sẽ * không chính xác * làm mất hiệu lực '10.03.21 00: 00: 00' và sẽ không xác nhận chuỗi ngày tháng mà không có thời gian * * * mà OP yêu cầu. – raveren

Các vấn đề liên quan