2009-02-28 3 views
8

Gli utenti selezionano la data da 3 menu a discesa (giorno, mese, anno). Li combinerò sul lato server per creare una stringa come "2008-12-30". Come posso quindi verificare che questa data sia nel formato corretto/solo numerico, ecc.?Come convalidare una data MySQL in PHP?

+0

Potete riformularlo leggermente; non è del tutto chiaro cosa stai cercando. Vuoi convalidare la data proveniente dalla query o vuoi convalidare i singoli componenti prima di inserirli nel database? – Rob

+0

Voglio combinare i componenti della data e convalidare la data combinata con il database. –

+1

Perché è stato downvoted? –

risposta

6

Se sono 3 menu a discesa separati, sarà necessario convalidarli come tre valori separati.

Vale a dire,

  • Convalida che la colonna anno è numerica e tra ciò che anni sono validi nella vostra applicazione
  • Convalida che la colonna mese è numerica
  • Convalida che la colonna giorno è numerica
  • Convalidare che sono tutti valori validi utilizzando la data di controllo()

Oppure, potresti semplicemente trasmettere loro tutti l a numero intero, combinarli insieme in una data e vedere se la data risultante è valida. Vale a dire,

$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 

Lo svantaggio di questo metodo è che funzionerà solo con date all'interno del campo timestamp Unix cioè 1970 al 2038 o giù di lì.

+0

Probabilmente vorrete controllare se è un numero intero, non se è numerico. is_numeric è vero sia per i float che per gli interi, ma is_int controlla solo gli interi. – gpojd

+0

is_int() non può funzionare su variabili inviate dall'utente, cioè variabili in $ _POST, perché queste sono sempre di tipo stringa. Potresti, comunque, lanciarli in numeri interi usando (int) $ _ POST ['var'] e poi confrontalo liberamente con il valore di stringa originale (usando ==). – thomasrutter

2

È possibile verificare che la data sia valida utilizzando checkdate. Se si desidera assicurarsi che i valori siano numerici e la lunghezza corretta, è possibile eseguire un'operazione semplice come is_int ctype_digit e una combinazione strlen prima di creare la data.

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

Ho cambiato la mia risposta da is_int a ctype_digit in base al commento di thomasrutter che is_int non gestirà correttamente le variabili POST. – gpojd

-1

Se si dispone di tre menu a discesa, i valori provenienti dai menu a discesa devono sempre essere numeri poiché si controllano i valori associati al mese (mostrato di seguito). Ciò porterebbe quindi alla conclusione che il risultato combinato è valido.

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

Se si forniscono fornire assistenza voci nei menu a discesa, come "Seleziona un mese", allora si può fare che il valore 0 e garantire che i valori provenienti da ogni casella di riepilogo è maggiore di zero.

C'è la possibilità che qualcuno modifichi il modulo HTML per fornire altri valori. Se questo è un problema, puoi usare la funzione PHP ctype_digit() per verificare che ogni valore fornito sia in realtà una cifra numerica.

Se la preoccupazione è che la data sia effettivamente valida, utilizzare la funzione checkdate().

+0

È possibile creare post su uno script senza l'uso di moduli. Posso scrivere un bot che fa un post sul tuo modulo e pubblica qualsiasi valore inserito per ogni campo senza l'uso di moduli. –

+0

È vero, ecco perché il suggerimento di usare ctype_digit() e checkdate() ha senso. Stavo basando la mia risposta sulla dichiarazione che avevi una forma. Anche se si utilizza uno script, non ci sono molti casi in questa istanza in cui non utilizzerebbe i valori nei moduli. – Paulo

1

Appena avuto lo stesso problema. Ho scritto una breve funzione che controlla se il formato è corretto, e anche se la data è vera:

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; 
} 

Speranza che aiuta.

+1

c'è checkdate(), amico –

+0

divertente, ora sto cercando di capire cosa c'è di sbagliato in me ... :) –

+0

ok ora capisco cosa volevo dire, perchè ho appena incontrato lo stesso problema oggi. checkdate() richiede tre parametri. quindi se hai una serie di date, non ti aiuta. la mia funzione prende una stringa e la formatta e controlla con checkdate() –

17

Personalmente ho trovato questo per essere il modo corretto ed elegante per determinare se la data è sia in base al formato e valida:

  • Tratta date come 20111-03-21 come non valido - a differenza checkdate()
  • nessun avviso PHP possibile (se viene fornito un parametro qualsiasi, naturalmente) - diversamente dalla maggior parte delle soluzioni explode()
  • richiede il salto anni in considerazione a differenza delle soluzioni espressioni regolari solo
  • pienamente compatibile con il formato di DATE mysql (10.03.21 è lo stesso 2010-03-21)

Ecco il metodo che è possibile utilizzare:

/** 
* 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

Sì, $ str dovrebbe essere cambiato in $ date ... [funzione modificata] – Ricky

+0

Grazie, in qualche modo quello che uso in produzione è corretto, mi dispiace per l'errore. – raveren

+0

buono! questo è utile –

4

sto usando questa funzione:

<?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 è vera, le altre sono false - e tha t è corretto

La funzione da Raveren (sopra) non coprirà le date valide con i timestamp !!! $ a restituisce falso là! E btw: checkdate() restituisce true per $ b anche se non è un tempo valido mysql datetime

+0

Grazie, la tua funzione mi ha aiutato :) –

+0

Questo * erroneamente * invalida '10.03.21 00: 00: 00' e non convaliderà le stringhe di data senza orario * a tutti * - che l'OP ha richiesto. – raveren