# Рекомендации для разработчиков лендингов

В документе собраны технические советы и правила для разработчиков, которые создают лендинги для работы в среде tracker-sandbox.

# Использование curl в PHP

Чтобы скрипты не прерывались неожиданно, важно учитывать ограничения по времени выполнения:

  • Максимальное время работы PHP-скрипта задаётся с помощью переменной TRACKER_LANDING_PAGES_TIMEOUT (в секундах).

  • Если curl-запрос работает дольше заданного времени, то принудительно прерывается.

  • Поэтому обязательно указывайте таймаут в CURLOPT_TIMEOUT — значение на 1 секунду меньше, чем TRACKER_LANDING_PAGES_TIMEOUT.

Пример настройки таймаута:

$systemTimeout = getenv('TRACKER_LANDING_PAGES_TIMEOUT') ?: 10;
$curlTimeout = max(1, $systemTimeout - 1);

$ch = curl_init('https://example.com/api');

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, $curlTimeout);

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo 'Ошибка curl: ' . curl_error($ch);
} else {
    echo 'Ответ: ' . $response;
}

curl_close($ch);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Таймауты в curl крайне важны при работе с медленными внешними API или когда используется цепочка curl-вызовов внутри лендинга.

# Использование гостевого Redis (Guest Redis)

Внутри контейнера tracker-sandbox доступен встроенный Redis-сервис, предназначенный только для временного хранения данных, отладки и тестирования. Используйте Redis-сервис, если не подходит кэширование в памяти или в файлах.

# Особенности

  • Redis доступен только локально, внутри контейнера.

  • Подключение осуществляется по авторизационным данным, которые система предоставляет с помощью переменных окружения.

  • Храните данные в Redis только временно — возможно удаление или перезапись.

# Пример подключения на PHP 8.3 с использованием phpredis

<?php

$redis = new Redis();

try {
    $redisHost = getenv('GUEST_REDIS_HOST');
    $redisPort = getenv('GUEST_REDIS_PORT');
    $redisUser = getenv('GUEST_REDIS_KEITARO_USER');
    $redisPassword = getenv('GUEST_REDIS_KEITARO_PASSWORD');

    $redis->connect($redisHost, $redisPort);

    if (!$redis->auth([$redisUser, $redisPassword])) {
        throw new RedisException("Ошибка авторизации Redis: неверные имя пользователя или пароль");
    }

    $redis->set('example_key', 'hello world');
    $value = $redis->get('example_key');

    echo "Получено значение: " . $value . PHP_EOL;

} catch (RedisException $e) {
    echo "Ошибка Redis: " . $e->getMessage() . PHP_EOL;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# Отказ от file_put_contents в пользу Redis

Использование файловой системы (file_put_contents(), fopen(), fwrite() и т. п.) не рекомендуется по следующим причинам:

  • При параллельных запросах возможен конфликт файлов.

  • После завершения запроса не з=гарантируется сохранение временных файлов.

  • Между перезапусками контейнера возможна очистка или переинициализация файловой системы.

  • Потенциальные проблемы с правами доступа и ограничениями open_basedir.

Рекомендуется использовать гостевой Redis — как безопасное и быстрое хранилище для временных данных.

# Пример: замена file_put_contents

Производилось:

$data = json_encode(['foo' => 'bar']);
file_put_contents('/tmp/my-cache.json', $data);
1
2

Стало:

$redis->set('my-cache-key', json_encode(['foo' => 'bar']));
1

# Пример: замена file_get_contents

Производилось:

$data = file_get_contents('/tmp/my-cache.json');
$array = json_decode($data, true);
1
2

Стало:

$data = $redis->get('my-cache-key');
$array = json_decode($data, true);
1
2

Используйте логически осмысленные ключи, по возможности с префиксами (landing:lead_data:123), чтобы избежать пересечений и упростить отладку.

Если данные необходимо хранить ограниченное время, используйте setex():

$redis->setex('temp:token', 60, 'abc123'); // срок действия — 60 секунд
1