Работа с UTM метками на PHP: парсинг, хранение и интеграция с аналитикой
Обработка UTM меток в PHP: методы и практические примеры
Основное решение: класс UtmTracker для надёжного парсинга и сохранения меток
Наиболее эффективный способ обработки UTM меток - создать специализированный класс, который извлекает параметры из URL, очищает их от XSS-атак, валидирует и сохраняет в сессию (или куки) для последующей передачи в аналитические системы (Google Analytics, CRM).
<?php
class UtmTracker {
private $params = [];
private $allowed = ['utm_source','utm_medium','utm_campaign','utm_term','utm_content'];
public function __construct(string $url = null) {
if ($url === null) {
$url = ($_SERVER['REQUEST_URI'] ?? '/');
}
$this->parse($url);
$this->store();
}
private function parse(string $url) {
$parts = parse_url($url);
if (!isset($parts['query'])) return;
parse_str($parts['query'], $query);
foreach ($this->allowed as $key) {
if (isset($query[$key])) {
$value = urldecode($query[$key]);
$value = filter_var($value, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
$this->params[$key] = $value;
}
}
}
private function store() {
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
foreach ($this->params as $key => $value) {
$_SESSION['utm'][$key] = $value;
}
}
public function getAll(): array {
return $this->params;
}
public function get(string $key): ?string {
return $this->params[$key] ?? null;
}
}
?>
обработка php (обработка данных в php)
Использование: $tracker = new UtmTracker(); после этого метки доступны в $_SESSION['utm'].
Типичные проблемы и их решение:
- Ошибка "session_start(): Session cannot be started after headers have already been sent" - вызывать UtmTracker до любого вывода HTML.
- Параметры с решёткой (#) - parse_url() игнорирует всё после #, что обычно корректно для UTM.
- Невалидная кодировка - применяется urldecode(), но если URL уже декодирован, это может привести к двойному декодированию. Рекомендуется передавать оригинальный URL из $_SERVER['REQUEST_URI'].
Как быстро получить UTM метки из URL без лишних зависимостей?
Если не требуется длительное хранение, можно использовать простой парсинг с помощью parse_url() и parse_str():
$url = 'https://example.com/?utm_source=google&utm_medium=cpc';
$query = parse_url($url, PHP_URL_QUERY);
parse_str($query, $params);
$utmKeys = ['utm_source','utm_medium','utm_campaign','utm_term','utm_content'];
$utm = array_intersect_key($params, array_flip($utmKeys));
print_r($utm);
Php learning (обучение php)
Проблема: при отсутствии меток возвращается пустой массив. Также не учитывается возможность множественных параметров с одинаковым именем (массивы). Для UTM это редкость, но parse_str() создаст массив, что может сломать логику. Решение: проверять тип значения и приводить к строке.
Как сохранить UTM метки на несколько дней для отслеживания источника перехода?
Используйте куки с длительным сроком жизни. Пример:
if (isset($_GET['utm_source'])) {
$expire = time() + 30 * 24 * 60 * 60; // 30 дней
foreach (['utm_source','utm_medium','utm_campaign','utm_term','utm_content'] as $key) {
if (!empty($_GET[$key])) {
setcookie($key, $_GET[$key], $expire, '/', '', false, true);
}
}
}
// Получение из куки:
$source = $_COOKIE['utm_source'] ?? null;
Php учебник (учебник по php)
Ошибки: куки не устанавливаются, если был вывод контента (заголовки уже отправлены). Используйте буферизацию вывода. Также куки с httponly не доступны из JavaScript, что может помешать frontend-аналитике.
Как упростить обработку UTM меток с помощью готовой библиотеки?
Пакет svycka/utm-php (composer require svycka/utm-php) предоставляет готовый класс для парсинга:
use UTM\UTM;
$url = 'https://example.com/?utm_source=facebook&utm_medium=social';
$utm = new UTM($url);
$data = $utm->all();
print_r($data);
// Результат: ['source' => 'facebook', 'medium' => 'social', ...]
Apis php (api на php)
Проблемы: библиотека может не обновляться или не поддерживать все PHP-версии. При использовании composer необходимо обеспечить autoload. Также библиотека может не обрабатывать кодировку так, как нужно вашему проекту.
Как интегрировать UTM обработку в Laravel-приложение?
Создайте middleware, который парсит входящий запрос и сохраняет метки в сессию:
// app/Http/Middleware/UtmMiddleware.php
namespace App\Http\Middleware;
use Closure;
class UtmMiddleware {
public function handle($request, Closure $next) {
$utmKeys = ['utm_source','utm_medium','utm_campaign','utm_term','utm_content'];
foreach ($utmKeys as $key) {
if ($request->has($key)) {
session(['utm.' . $key => $request->input($key)]);
}
}
return $next($request);
}
}
// зарегистрировать в Kernel.php
Проблема: при использовании AJAX-запросов сессия может быть заблокирована, что приведёт к задержкам. Также нужно учитывать, что метки могут приходить в GET-параметрах, а middleware обрабатывает все запросы, что может сохранить мусор.
Расширенные примеры обработки UTM меток
Пример 1: Полный класс с сохранением в сессию и куки
<?php
class UtmManager {
private array $data = [];
private const KEYS = ['utm_source','utm_medium','utm_campaign','utm_term','utm_content'];
public function __construct(string $url = null) {
$url = $url ?? ($_SERVER['REQUEST_URI'] ?? '');
$this->extractFromUrl($url);
$this->storeSession();
$this->storeCookie(30);
}
private function extractFromUrl(string $url): void {
$query = parse_url($url, PHP_URL_QUERY);
if (!$query) return;
parse_str($query, $params);
foreach (self::KEYS as $key) {
if (isset($params[$key])) {
$val = $params[$key];
if (is_array($val)) $val = $val[0]; // берём первый элемент
$this->data[$key] = htmlspecialchars(strip_tags(urldecode($val)), ENT_QUOTES, 'UTF-8');
}
}
}
private function storeSession(): void {
if (session_status() === PHP_SESSION_NONE) session_start();
foreach ($this->data as $k => $v) {
$_SESSION['utm'][$k] = $v;
}
}
private function storeCookie(int $days): void {
foreach ($this->data as $k => $v) {
setcookie($k, $v, time() + $days * 86400, '/', '', false, true);
}
}
public function getAll(): array { return $this->data; }
}
// Использование
$mgr = new UtmManager();
print_r($mgr->getAll());
?>
// При переходе по ссылке ?utm_source=test&utm_medium=email
Array
(
[utm_source] => test
[utm_medium] => email
)
Пример 2: Обработка UTM меток из HTTP_REFERER
$referer = $_SERVER['HTTP_REFERER'] ?? '';
if ($referer) {
$query = parse_url($referer, PHP_URL_QUERY);
parse_str($query, $params);
$utm = array_intersect_key($params, array_flip(['utm_source','utm_medium']));
if (!empty($utm)) {
file_put_contents('utm.log', json_encode($utm) . PHP_EOL, FILE_APPEND);
}
}
// В лог запишется: {"utm_source":"google","utm_medium":"organic"}
Пример 3: Передача UTM меток в JavaScript для dataLayer (Google Tag Manager)
$utm = new UtmTracker(); // класс из базового решения
$data = $utm->getAll();
?>
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'utm_loaded',
'utmSource': '<?= addslashes($data['utm_source'] ?? '') ?>',
'utmMedium': '<?= addslashes($data['utm_medium'] ?? '') ?>',
'utmCampaign': '<?= addslashes($data['utm_campaign'] ?? '') ?>'
});
</script>
Пример 4: Обработка массива URL (например, загрузка UTM из файла)
$urls = [
'https://site.com/?utm_source=a&utm_medium=b',
'https://site.com/?utm_source=c&utm_term=test&utm_content=123',
];
$results = [];
foreach ($urls as $url) {
$query = parse_url($url, PHP_URL_QUERY);
parse_str($query, $p);
$results[] = array_intersect_key($p, array_flip(['utm_source','utm_medium','utm_campaign','utm_term','utm_content']));
}
print_r($results);
Array
(
[0] => Array
(
[utm_source] => a
[utm_medium] => b
)
[1] => Array
(
[utm_source] => c
[utm_term] => test
[utm_content] => 123
)
)
Пример 5: Защита от дублирования - сохранение меток только если они не были установлены ранее
session_start();
if (!isset($_SESSION['utm'])) {
$utm = [];
foreach (['utm_source','utm_medium','utm_campaign'] as $key) {
if (isset($_GET[$key])) {
$utm[$key] = $_GET[$key];
}
}
if (!empty($utm)) {
$_SESSION['utm'] = $utm;
}
}
// При повторном заходе с другими UTM, старые значения останутся неизменными.