martedì 15 dicembre 2009

Date in PHP e MYSQL

Traduco questo ottimo articolo di Richard Lord: Dates in PHP and MySQL , perchè l'ho trovato molto utile e interessante.

Vedo molta gente nei forum e nei miei corsi chiedere quale sia il miglior modo (o il modo) per gestire le date archiviate in un database MySQL e utilizzate dal codice PHP. Di seguito tre soluzioni, ma prima il problema.

Il PHP usa timestamps unix per tutte le funzioni relative alle date. Ha metodi per convertire questi timestamps in praticamente qualsiasi formato testuale possiate desiderare ma internamente usa il formato timestamp. Il timestamp è semplicemente un intero senza segno. Nello specifico, è il numero di secondi trascorsi dalla mezzanotte del 1 Gennaio 1970 (in base all'ora di Greenwich).

MySQL ha a disposizione tre tipi di campi data. Sono: DATETIME, DATE, e TIMESTAMP. Un campo DATETIME salva data e orario come una stringa nella forma AAAA-MM-GG HH:MM:SS (es. 2006-12-25 13:43:15). Un campo DATE usa solo la parte della data del formato precedente AAAA-MM-GG (es. 2006-12-25). Un campo TIMESTAMP, nonostante il nome, non somiglia per nulla al timestamp unix usato in PHP. Un campo TIMESTAMP è semplicemente un campo DATETIME che si aggiorna automaticamente all'orario corrente ogni volta che i contenuti del campo vengono modificati (è una semplificazione ma a grandi linee corretta, e i dettagli non sono importanti in questo caso). In particolare, dalla versione 4.1 di MySQL il formato TIMESTAMP è esattamente uguale al formato DATETIME.

Perciò il problema è come lavorare con questi due differenti formati di data - il numero intero timestamp di PHP e la stringa DATETIME di MySQL. Ci sono tre soluzioni di uso comune...

  1. Una comune soluzione è archiviare le date in campi DATETIME e usare le funzioni PHP date() e strtotime() per convertire i timestamp PHP e i DATETIME MySQL. Le funzioni saranno usate come nell'esempio seguente:

    $mysqldate = date( 'Y-m-d H:i:s', $phpdate );
    $phpdate = strtotime( $mysqldate );
  2. La nostra seconda opzione è lasciare che MySQL faccia il lavoro sporco. MySQL ha delle funzioni che possiamo usare per convertire i dati nel momento in cui accediamo al database. UNIX_TIMESTAMP converte il formato DATETIME nel timestamp di PHP e FROM_UNIXTIME converte il timestamp di PHP nel DATETIME di MySQL. Le funzioni vengono usate all'interno della query SQL. Perciò inseriamo e aggiorniamo le date usando query come queste:

    $query = "UPDATE table SET
    datetimefield = FROM_UNIXTIME($phpdate)
    WHERE...";
    $query = "SELECT UNIX_TIMESTAMP(datetimefield)
    FROM table WHERE...";
  3. La nostra ultima possibilità è semplicemente usare il timestamp di PHP ovunque. Poichè il timestamp di PHP è un numero intero senza segno, è sufficiente usare un campo INTEGER senza segno nel MySQL per salvare il timestamp. In questo modo non ci sono conversioni e possiamo semplicemente spostare i timestamp di PHP dentro e fuori il database senza alcun problema.

    Fate attenzione comunque al fatto che usando un campo INTEGER senza segno per salvare le vostre date perderete molte delle funzionalità di MySQL perchè MySQL non riconoscerà le vostre date come date. Potrete ancora ordinare i dati nei vostri campi data poichè i timestamp di PHP aumentano in modo regolare nel tempo, ma se vorrete usare una qualsiasi delle funzioni data o tempo di MySQL dovrete prima usare la funzione FROM_UNIXTIME per ottenere un valore MySQL DATETIME.

    Ad ogni modo, se state usando il database solo per salvare le informazioni di data e ogni manipolazione di queste verrà effettuata dal PHP allora non c'è problema.

Così finalmente siamo giunti al momento della scelta di quale usare. Per me, se non avete la necessità di manipolare le date con MySQL allora non c'è discussione: l'ultima alternativa è la migliore. E' semplice da usare ed è la più efficiente in termini di spazio occupato nella tabella e velocità di esecuzione in fase di lettura e scrittura.

Comunque, alcune query potrebbero risultare più complicate dato che le vostre date non sono in un campo data (es. selezionare tutti gli utenti che compiono gli anni oggi) e potreste rimetterci nelle esecuzioni prolungate. Se è questo il caso, meglio usare una delle altre due opzioni. Quale delle due, dipende da voi, se preferite far lavorare MySQL o il PHP. Io tendo ad usare l'opzione 2 ma non c'è una risposta giusta o una sbagliata - fate la vostra scelta.

Per riassumere, per chi va dritto all'ultimo paragrafo, la maggior parte delle volte uso l'opzione n. 3 ma occasionalmente uso l'opzione 2 se ho la necessità di far sapere a MySQL che i campi contengono una data.

2 commenti:

Sky ha detto...

Anche io uso quasi sempre l'ultima alternativa :)

Comunque l'articolo è interessante, ottima idea tradurlo in italiano!

Daniele

Andrea ha detto...

Bell'articolo, la gestione delle date è sempre complicata in effetti, poi bisogna anche leggere i dati dal database e usarli, ad esempio per confrontare due date o visualizzare una data in formato normale in una pagina.
Un altro articolo a riguardo è qui:

http://www.imparare-php.com/convertire-data-in-formato-date-di-mysql-120/

Posta un commento