Ответ
Нет, функция time() в PHP не является чистой.
Чистая функция должна соответствовать двум критериям:
- Детерминированность: Для одинаковых входных аргументов всегда возвращает одинаковый результат.
- Отсутствие побочных эффектов (side-effects): Не изменяет внешнее состояние (глобальные переменные, файлы, БД).
Функция time() нарушает первый критерий, так как ее результат зависит от внешнего, изменяющегося состояния — системного времени.
// НЕ чистая функция: результат разный при каждом вызове.
echo time(); // 1710000000
sleep(1);
echo time(); // 1710000001
Как сделать код, зависящий от времени, тестируемым? Инкапсулируйте зависимость.
// 1. Внедрение зависимости через параметр (предпочтительно для чистоты).
function formatOrderDate(int $timestamp): string {
return date('Y-m-d H:i:s', $timestamp);
}
// В тесте можем передать любое фиксированное время.
formatOrderDate(1672531200); // '2023-01-01 00:00:00'
// 2. Использование инъекции зависимости в классе.
class TimeSensitiveService {
private $timeProvider;
public function __construct(callable $timeProvider = null) {
$this->timeProvider = $timeProvider ?? 'time';
}
public function isCacheValid(int $cacheTime): bool {
$currentTime = ($this->timeProvider)();
return ($currentTime - $cacheTime) < 3600;
}
}
// В продакшене: new TimeSensitiveService();
// В тесте: new TimeSensitiveService(fn() => 1672531200); Ответ 18+ 🔞
А, ну это ж классика, блядь! Чистые функции — это как обещание не пить в пятницу: звучит красиво, но на деле постоянно кто-то срывается. И главный нарушитель спокойствия — этот ваш time().
Смотри, чистая функция — это святое, ёпта. Два железных правила: дала одинаковые аргументы — получишь одинаковый ответ, и при этом она нихуя вокруг себя не ломает и не пачкает. Никаких глобальных переменных, записей в базу или, ядрёна вошь, вывода в консоль.
А теперь посмотри на этого подлеца, time(). Он что делает? Каждый раз, когда его вызываешь, он смотрит на часы и выдаёт новую цифру. Это ж полный пиздец с точки зрения детерминированности! Сегодня он вернёт одно, через секунду — уже другое. Какое тут, на хуй, тестирование? Ты не можешь написать тест и быть уверенным, что завтра он сработает так же. Это же доверия ебать ноль.
// Это не функция, а обманщик с тремя картами.
echo time(); // Допустим, 1710000000
sleep(1); // Подождали чуть...
echo time(); // Бля, а уже 1710000001! Изменщик!
Так как же быть, если время нужно? А вот тут надо включать э бошка думай. Нельзя просто так взять и вызвать time() посреди своей бизнес-логики. Это путь в ад непроверяемого кода.
Самый правильный подход — это инкапсулировать эту зависимость, как опасную болезнь в карантин. Сделать так, чтобы твоя логика принимала время как аргумент, а не выпрашивала его у системы сама.
// 1. Способ для аристократов: передаём время параметром.
function formatOrderDate(int $timestamp): string {
return date('Y-m-d H:i:s', $timestamp);
}
// В тесте мы — боги. Диктуем любое время.
formatOrderDate(1672531200); // Всегда будет '2023-01-01 00:00:00'. Красота!
// 2. Способ для ООП-шников: внедряем "поставщика времени" в класс.
class TimeSensitiveService {
private $timeProvider; // Сюда мы засунем либо стандартный time(), либо свою заглушку
public function __construct(callable $timeProvider = null) {
// Если нам не подсунули свою функцию, используем стандартную, грешную.
$this->timeProvider = $timeProvider ?? 'time';
}
public function isCacheValid(int $cacheTime): bool {
$currentTime = ($this->timeProvider)(); // Вот тут магия!
return ($currentTime - $cacheTime) < 3600;
}
}
// В реальной работе: $service = new TimeSensitiveService(); // Использует time()
// В тестовой песочнице: $service = new TimeSensitiveService(fn() => 1672531200); // Время заморожено!
Вот видишь разницу? В первом случае функция чистая, как слеза младенца. Во втором — класс становится предсказуемым. Мы можем в тестах подсунуть ему заглушку, которая всегда возвращает одно и то же число, и наш код будет вести себя стабильно. А в бою он спокойно работает с реальным временем.
Итог простой: time() — хитрая жопа, которая ломает чистоту. Но если эту зависимость вынести за скобки и контролировать её извне, то жить можно. И тесты писать можно. И спать спокойно.