Имитация различных серверных дат в PHP - PullRequest
8 голосов
/ 17 июля 2010

Можно ли заставить приложение PHP думать, что время и дата сервера компенсируется большой настраиваемой величиной (например, 6 месяцев назад или через 6 месяцев)?

Справочная информация: у нас есть веб-приложение, котороеимеет дело со спортивными событиями, и сейчас мы хотели бы запустить его в нашей среде разработки таким образом, чтобы веб-сайт думал, что это осень 2009 года, а не лето 2010 года. Это потому, что у нас есть отличные данные с сезона прошлого года и сезона этого годаеще не началось, поэтому тестирование новых функций будет проще с использованием множества реальных данных вместо создания новых тестовых данных за 2010 год.

Мы не хотим фактически изменять дату и время сервера.В настоящее время наилучшим вариантом является изменение всех вызовов date () в коде на my_date (), а затем добавление смещения my_date () к фактической системной дате.

Казалось, что эта функция будет полезна в подобных ситуациях для других, поэтому мне было просто любопытно, есть ли более простой способ сделать это глобально через некоторый параметр конфигурации без изменения кода.Я сделал RTM.

Ответы [ 3 ]

2 голосов
/ 17 июля 2010

Вы можете использовать пользовательский класс DateTime:

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

В вашей начальной загрузке просто установите $timeModifier так:

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

И тогда вы можете использовать его так из любого места:

$now = new My_DateTime();
echo $now->format('Y-m-d H:i:s'); // 2010-01-17 16:41:49
2 голосов
/ 17 июля 2010

Вы можете установить Runkit на сервере разработки и переопределить все необходимые функции dateTime для возврата измененного значения, например,

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

, где datetime-monkeypatches.php будет содержать ваши патчи для требуемогофункции.Таким образом, вам не придется менять свой фактический код.Это похоже на использование адаптера к исходным функциям, и пока вы храните их в этом отдельном файле, он остается поддерживаемым.

Другой вариант - использовать http://antecedent.github.io/patchwork

Пэчворкявляется библиотекой PHP, которая позволяет переопределять пользовательские функции и методы во время выполнения, свободно реплицируя функциональность runkit_function_redefine в чистом коде PHP 5.3, что, помимо прочего, позволяет заменять статические и частные методы на двойники теста.

2 голосов
/ 17 июля 2010

Я никогда не пробовал, но, может быть, libfaketime может помочь, здесь: это позволяет "подделать" время для процесса.

Дляпример, см. эту статью: Изменение времени, в течение которого процесс думает, что это время, с помощью libfaketime


Но, как сказано в , этот билет PHPUnit Trac, это, вероятно, то, что должно быть сделано с использованием вашего собственного эквивалента функций дат ...

Что означает, как вы уже догадались, что лучшим решением, если вы можете себе это позволить, действительно будет использованиеВаша собственная my_date() функция везде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...