2010-07-17 26 views
7

Bir PHP uygulaması, sunucu tarih zamanının büyük yapılandırılabilir bir miktarla (6 ay önce veya 6 ay sonra) dengelendiğini düşünebilir mi?PHP'de farklı sunucu sürümlerini simüle edin

Arka plan: Şu anda spor etkinlikleriyle ilgilenen bir web uygulamasına sahibiz ve şu anda web sitemizin 2010 yazının yerine 2009 Güz 2009 olduğunu düşünecek şekilde geliştirme ortamımızda çalıştırmak istiyoruz. Geçtiğimiz yılın sonbahar sezonu için harika verilerimiz var ve bu yıl henüz başlamadı, bu yüzden yeni özellikler test etmek, 2010 için yeni test verisi oluşturmak yerine gerçek verilerdeki taklitlerle daha kolay olurdu.

Biz istemiyoruz aslında sunucunun tarih ve saatini değiştirir. Geçerli en iyi seçenek, koddaki tüm tarih() çağrılarını my_date() değerine çevirmek ve sonra da my_date() öğesinin gerçek sistem tarihine uzaklık eklemesini sağlamaktır.

Bu özellik başkaları için benzer durumlarda yararlı olabilir gibi görünüyordu, bu yüzden kod değiştirmeden bazı yapılandırma parametresi aracılığıyla küresel olarak bunu yapmanın daha kolay bir yolu olup olmadığını merak ettim. RTM yaptım.

+0

Yanıtlar için herkese teşekkürler.Bir ünüm olsaydı, her birinize bir +1 verebilirdim çünkü tüm cevaplar bir şekilde yardımcı oldu. – royappa

cevap

2

Geliştirme sunucusuna Runkit yükleyebilirsiniz. ve değiştirilmiş bir değeri döndürmek için gereken tüm dateTime işlevlerini yeniden tanımlayın, ör. datetime-monkeypatches.php gerekli fonksiyonlar için yamalar içerecektir

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

. Bu şekilde gerçek kodunuzu değiştirmek zorunda kalmazsınız. Orijinal işlevlere bir adaptör kullanmak gibi ve bunları ayrı bir dosyada sakladığınız sürece, korunabilir durumda kalır.

Diğer bir seçenek, http://antecedent.github.io/patchwork

Patchwork mümkün gevşek saf PHP 5.3 kodunda işlevselliği runkit_function_redefine kopyalayan, çalışma zamanında kullanıcı tanımlı işlevler ve yöntemler yeniden tanımlama yapan bir PHP kütüphanesidir kullanmak olurdu, diğer şeylerin yanı sıra, test çiftleriyle statik ve özel yöntemleri değiştirmenizi sağlar.

+0

Bu bizim için çalışabilir, araştıracaktır. Teşekkürler! – royappa

2

Hiç denemedim, ancak belki de libfaketime yardımcı olabilir, burada: bir işlem için zaman "sahte" sağlar. this ticket of PHPUnit's Trac dediği gibi gibi ... muhtemelen tarihleri ​​fonksiyonlarının kendi eşdeğeri kullanılarak yapılmalıdır şey, demek

Changing what time a process thinks it is with libfaketime


Ama:

Örneğin, bu makaleye bakın Tahmin ederseniz, en iyi çözümün, eğer bunu karşılayabiliyorsanız, her yerde kendi my_date() işlevini kullanmanız olacaktır. basitçe böyle $timeModifier ayarlayın bootstrap olarak

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

:

+0

Maalesef bu bir yönetilen sunucuda olduğundan, söz konusu kutuda root erişimi yoktur. Yine de çok ilginç! – royappa

+0

PHP'nin yerleşik sunucusuyla ilgili bir örnek: 'faketime '2016-04-01 12:00' php -S localhost: 8013' – Trendfischer

2

Özel bir DateTime sınıfı kullanabilirsiniz

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

Sonra her yerden bu gibi kullanabilirsiniz:

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

Maalesef, bir sürü yerdeki yerel tarih() çağrısı kullanıyoruz . – royappa

+1

@royappa, evet. Tüm yerel aramaları değiştirmeniz gerekir. Özel bir my_date işlevi kullanırken yaptığınız gibi. – Gordon

+0

Evet, anlaşıldı. Teşekkürler. – royappa

İlgili konular