2010-07-17 1 views
7

È possibile fare un'applicazione PHP pensare che il server datetime sia compensato da una grande quantità configurabile (come 6 mesi fa, o 6 mesi da ora)?Simula diversi server datetimes in PHP

Sfondo: Abbiamo un'applicazione web che si occupa di eventi sportivi e in questo momento vorremmo eseguirlo nel nostro ambiente di sviluppo in modo tale che il sito web pensi che sia l'autunno 2009 anziché l'estate 2010. Questo perché abbiamo ottimi dati dalla stagione autunnale dell'anno scorso e la stagione di quest'anno non è ancora iniziata, quindi testare nuove funzionalità sarebbe più facile con scad dati reali invece di creare nuovi dati di test per il 2010.

Non vogliamo cambia effettivamente la data e l'ora del server. L'opzione migliore corrente sembra essere quella di cambiare tutte le chiamate date() nel codice a my_date() e quindi avere my_date() aggiungere l'offset alla data di sistema effettiva.

Sembrava che questa funzione sarebbe stata utile in situazioni simili per altri, quindi ero curioso di sapere se esiste un modo più semplice per farlo globalmente attraverso alcuni parametri di configurazione senza modificare il codice. Ho fatto RTM.

+0

Grazie a tutti per le risposte.Se avessi una reputazione potrei dare a ciascuno di voi un +1 perché tutte le risposte sono state utili in un modo o nell'altro. – royappa

risposta

2

È possibile installare Runkit sul server di sviluppo e ridefinire tutte le funzioni dateTime necessarie per restituire un valore modificato, ad es.

if(APP_ENV === 'testing') { 
    include 'datetime-monkeypatches.php'; 
} 

dove datetime-monkeypatches.php contiene le patch per le funzioni richieste. In questo modo non dovrai modificare il tuo codice attuale. È come usare un adattatore per le funzioni originali e finché si mantiene in quel file separato, rimane manutenibile.

Un'altra possibilità sarebbe quella di utilizzare http://antecedent.github.io/patchwork

mosaico è una libreria PHP che rende possibile ridefinire funzioni e metodi definiti dall'utente in fase di esecuzione, liberamente replicando la funzionalità runkit_function_redefine in puro codice PHP 5.3, che, tra le altre cose, consente di sostituire i metodi statici e privati ​​con i duplicati di prova.

+0

Questo potrebbe funzionare per noi, indagheremo. Grazie! – royappa

2

Non l'ho mai provato, ma forse libfaketime potrebbe aiutare, qui: consente di "falsificare" il tempo per un processo.

Ad esempio, si veda questo articolo: Changing what time a process thinks it is with libfaketime


Ma, come detto in this ticket of PHPUnit's Trac, questo è probabilmente qualcosa che dovrebbe essere fatto utilizzando il proprio equivalente di funzioni date ...

Il che significa, come avete indovinato, che la soluzione migliore, se potete permettervelo, sarebbe davvero quella di usare la vostra funzione my_date() ovunque.

+0

Sfortunatamente questo è su un server gestito, quindi non abbiamo accesso root su quella particolare casella. Molto interessante, però! – royappa

+0

Un esempio sull'utilizzo con il server integrato di PHP: 'faketime '2016-04-01 12:00' php -S localhost: 8013' – Trendfischer

2

Si potrebbe utilizzare una classe DateTime personalizzato:

class My_DateTime extends DateTime 
{ 
    public static $timeModifier = NULL; 

    public function __construct($now = 'now', DateTimeZone $timezone = NULL) 
    { 
     parent::__construct($now); 
     if($timezone !== NULL) { 
      $this->setTimezone($timezone); 
     } 
     if(self::$timeModifier !== NULL) { 
      $this->modify(self::$timeModifier); 
     } 
    } 
} 

Nel vostro bootstrap è sufficiente impostare il $timeModifier in questo modo:

if(APP_ENV === 'testing') { 
    My_DateTime::$timeModifier = '-6 months'; 
} 

E poi si può usare in questo modo da qualsiasi luogo:

$now = new My_DateTime(); 
echo $now->format('Y-m-d H:i:s'); // 2010-01-17 16:41:49 
+0

Purtroppo stiamo usando la chiamata data() nativa in un gruppo di posti . – royappa

+1

@royappa bene, si. Dovresti sostituire tutte le chiamate native. Proprio come faresti quando usi una funzione personalizzata my_date. – Gordon

+0

Sì, capito. Grazie. – royappa