PHP и мобильные URL: от обнаружения до редиректа

Раздел: Веб-разработка на PHP -> Работа с URL в PHP

Основные подходы к работе с мобильными URL

Решение задачи определения мобильных устройств и перенаправления на мобильные версии сайта требует учета множества нюансов. Рассмотрим наиболее эффективные методы и альтернативные подходы.

Использование библиотеки Mobile Detect

Этот способ считается стандартом в PHP-сообществе. Библиотека Mobile_Detect предоставляет надежное определение мобильных телефонов, планшетов и даже конкретных операционных систем.

Установка через Composer:

composer require mobiledetect/mobiledetectlib

Php создание ссылки (создание ссылки в php)

Базовый пример проверки и редиректа:


<?php
require_once 'vendor/autoload.php';
use Detection\MobileDetect;

$detect = new MobileDetect();

if ($detect->isMobile() && !$detect->isTablet()) {
    // Исключаем уже мобильную версию
    if (strpos($_SERVER['REQUEST_URI'], '/mobile') === false) {
        header('Location: /mobile' . $_SERVER['REQUEST_URI']);
        exit;
    }
}
?>
  

Php текущая url (текущая url в php)

Здесь проверяется, что устройство мобильное (не планшет), и текущий URL не начинается с /mobile. Это предотвращает бесконечный редирект.

Типичные ошибки:

  • Отсутствие проверки уже мобильного URL приводит к циклическому редиректу.
  • Использование устаревшей версии библиотеки – база устройств не обновляется, появляются ложные срабатывания. Рекомендуется регулярно обновлять пакет через Composer.
  • Забыли учесть сессию: после редиректа на мобильную версию, при повторном заходе с того же устройства редирект не должен срабатывать. Решение – сохранять флаг в сессии или куки.

Улучшенный вариант с сессией


<?php
session_start();
if (!isset($_SESSION['mobile_redirect'])) {
    if ($detect->isMobile() && !$detect->isTablet() && strpos($_SERVER['REQUEST_URI'], '/mobile') === false) {
        $_SESSION['mobile_redirect'] = true;
        header('Location: /mobile' . $_SERVER['REQUEST_URI']);
        exit;
    }
}
?>
    

Mobile php url (мобильный url в php)

Теперь редирект выполняется только один раз для каждой сессии пользователя.

Цель использования: обеспечить корректное и производительное определение мобильных устройств с минимальными затратами на поддержку кода.

Как определить мобильное устройство с помощью регулярных выражений?

Если нет возможности установить внешнюю библиотеку, можно написать простую проверку на основе User-Agent.


<?php
function isMobile() {
    $userAgent = $_SERVER['HTTP_USER_AGENT'];
    $mobilePatterns = [
        'android', 'iphone', 'ipad', 'ipod', 'blackberry',
        'windows phone', 'opera mini', 'iemobile', 'mobile'
    ];
    foreach ($mobilePatterns as $pattern) {
        if (stripos($userAgent, $pattern) !== false) {
            return true;
        }
    }
    return false;
}

if (isMobile()) {
    // редирект
}
?>
  

Php open url (открытие url в php)

Проблемы:

  • Список может быть неполным – новые устройства или нестандартные агенты останутся неопознанными.
  • Ложные срабатывания на некоторых десктопных браузерах, которые эмулируют мобильные агенты.
  • Отсутствие различий между телефоном и планшетом.

Решение: комбинировать проверку с дополнительными заголовками, такими как HTTP_ACCEPT или шириной экрана через JavaScript (но это уже не PHP).

Случаи использования: минималистичные проекты, где не требуется высокая точность, или когда нужно быстрое решение без внешних зависимостей.

Как перенаправить на мобильную версию с сохранением исходного URL?

Необходимо не просто сменить поддомен, а сохранить путь и GET-параметры. Пример с использованием поддомена m.example.com:


<?php
if ($detect->isMobile()) {
    $currentUrl = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://') . 
                  'm.' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    header('Location: ' . $currentUrl);
    exit;
}
?>
  

Js php url (javascript и php url)

Ошибки:

  • Если поддомен уже используется, проверка должна исключать повторный редирект. Нужно проверять, что хост не начинается с m..
  • Потеря порта – если сайт работает на нестандартном порту, его необходимо явно указывать.

Решение:


if (strpos($_SERVER['HTTP_HOST'], 'm.') !== 0) {
    $port = ($_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) ? ':' . $_SERVER['SERVER_PORT'] : '';
    $redirectUrl = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://') . 
                   'm.' . $_SERVER['HTTP_HOST'] . $port . $_SERVER['REQUEST_URI'];
    header('Location: ' . $redirectUrl);
    exit;
}
    

Php строка url (строка url в php)

Также стоит учесть, что редирект на поддомен может нарушить cookie и сессии, если корневой домен не настроен правильно.

Цель: бесшовный переход на мобильную версию без изменения адреса страницы (для пользователя), что важно для UX.

Как создать deep link для мобильного приложения?

Мобильные приложения часто регистрируют собственные схемы URL, например myapp://. В PHP можно генерировать такие ссылки и обеспечить fallback на веб-версию.


<?php
function buildDeepLink($path, $params = []) {
    $scheme = 'myapp://' . ltrim($path, '/');
    if (!empty($params)) {
        $scheme .= '?' . http_build_query($params);
    }
    // Fallback – если приложение не установлено, открыть в браузере
    $fallbackUrl = 'https://example.com/' . $path . '?' . http_build_query($params);
    // Пример использования: блок JavaScript или мета-тег
    return [
        'deep_link' => $scheme,
        'fallback' => $fallbackUrl
    ];
}

$link = buildDeepLink('profile/123', ['utm_source' => 'mobile']);
echo $link['deep_link'];
?>
  

Url class php (класс url в php)

Проблемы:

  • Не все устройства поддерживают пользовательские схемы. Для iOS рекомендуется Universal Links, для Android – App Links.
  • На некоторых устройствах fallback может не сработать, если браузер перехватывает неизвестную схему.

Решение: использовать сервисы типа Firebase Dynamic Links или Branch.io, которые автоматически выбирают подходящий механизм.

Случаи: маркетинговые кампании, когда нужно направить пользователя в установленное приложение, а при его отсутствии – на сайт.

Как обрабатывать параметр мобильной версии в URL?

Иногда решение о версии сайта принимается на основе GET-параметра, например ?mobile=1. Это удобно для тестирования.


<?php
$isMobileView = false;
if (isset($_GET['mobile'])) {
    $isMobileView = filter_var($_GET['mobile'], FILTER_VALIDATE_BOOLEAN);
    setcookie('mobile_view', $isMobileView ? '1' : '0', time()+86400*30);
}

if (!$isMobileView && isset($_COOKIE['mobile_view'])) {
    $isMobileView = $_COOKIE['mobile_view'] === '1';
}

if ($isMobileView) {
    // подключить мобильный шаблон
    include 'mobile_template.php';
} else {
    include 'desktop_template.php';
}
?>
  

Ошибки:

  • Параметр mobile может быть подделан пользователем – необходимо валидировать.
  • Запоминание выбора через куки может работать некорректно, если куки отключены.
  • SEO-проблемы: разные URL с одинаковым контентом – нужна каноническая ссылка.

Решение: установить канонический URL без параметра, а для мобильной версии использовать редирект 302 либо использовать отдельный поддомен.

Цель: предоставить пользователю или разработчику возможность принудительно включить мобильную версию для тестирования или личных предпочтений.

- Engine php url (движок url в php)
- Url form php (url формы в php)
- Php base url (базовый url в php)

Расширенные примеры работы с мобильными URL

Пример 1: Полноценный класс для редиректа с сессией и исключениями

Пример

<?php
namespace App\Mobile;

use Detection\MobileDetect;

class MobileRedirector
{
    private $detect;
    private $mobilePathPrefix = '/mobile';
    private $excludedPaths = ['/admin', '/api'];

    public function __construct()
    {
        $this->detect = new MobileDetect();
    }

    public function handle()
    {
        session_start();

        // Если уже был редирект в этой сессии – пропускаем
        if (!empty($_SESSION['mobile_redirect_done'])) {
            return;
        }

        // Исключаем определённые пути
        foreach ($this->excludedPaths as $path) {
            if (strpos($_SERVER['REQUEST_URI'], $path) === 0) {
                return;
            }
        }

        // Если устройство мобильное (не планшет) и ещё не на мобильной версии
        if ($this->detect->isMobile() && !$this->detect->isTablet()) {
            if (strpos($_SERVER['REQUEST_URI'], $this->mobilePathPrefix) !== 0) {
                $_SESSION['mobile_redirect_done'] = true;
                $redirectUrl = $this->mobilePathPrefix . $_SERVER['REQUEST_URI'];
                header('Location: ' . $redirectUrl, true, 302);
                exit;
            }
        }
    }
}

$redirector = new MobileRedirector();
$redirector->handle();
?>
// Результат: при заходе с мобильного телефона происходит однократный редирект на /mobile/...
// Администраторы и API не затрагиваются.

Пояснение: класс инкапсулирует логику, легко расширяется добавлением новых исключений или изменением префикса. Сессия предотвращает повторный редирект при последующих запросах в рамках сессии.

Пример 2: Генерация deep link с поддержкой Universal Links и App Links

Пример

<?php
function generateDeepLink($path, $params = [], $iosAppId = null, $androidPackage = null)
{
    $deepLink = [
        'ios_scheme' => 'myapp://' . ltrim($path, '/'),
        'android_scheme' => 'myapp://' . ltrim($path, '/')
    ];

    // Добавляем параметры
    $query = http_build_query($params);
    if ($query) {
        $deepLink['ios_scheme'] .= '?' . $query;
        $deepLink['android_scheme'] .= '?' . $query;
    }

    // Для Universal Links (iOS) – https://example.com/path
    // Для App Links (Android) – https://example.com/path (аналогично)
    if ($iosAppId) {
        $deepLink['ios_universal'] = 'https://example.com/' . $path . ($query ? '?' . $query : '');
    }
    if ($androidPackage) {
        $deepLink['android_applinks'] = 'https://example.com/' . $path . ($query ? '?' . $query : '');
    }

    // Fallback – обычная веб-ссылка
    $deepLink['fallback'] = 'https://example.com/' . $path . ($query ? '?' . $query : '');

    return $deepLink;
}

$result = generateDeepLink('product/42', ['ref' => 'push'], 'com.example.app', 'com.example.app');
echo json_encode($result, JSON_PRETTY_PRINT);
?>
{
    "ios_scheme": "myapp://product/42?ref=push",
    "android_scheme": "myapp://product/42?ref=push",
    "ios_universal": "https://example.com/product/42?ref=push",
    "android_applinks": "https://example.com/product/42?ref=push",
    "fallback": "https://example.com/product/42?ref=push"
}

Пояснение: функция возвращает массив ссылок, которые можно использовать в HTML-метатегах или JavaScript для умного редиректа. Кастомные схемы используются, если приложение установлено; в противном случае – открывается веб-версия.

Пример 3: Параметр мобильной версии с валидацией и куками

Пример

<?php
class MobileViewSelector
{
    private $mobileParam = 'mobile';
    private $cookieName = 'mobile_selection';
    private $cookieLifetime = 30; // дней

    public function getCurrentView()
    {
        // Определяем, какой вид показывать
        $mobileView = null;

        // Проверяем GET-параметр
        if (isset($_GET[$this->mobileParam])) {
            $mobileView = filter_var($_GET[$this->mobileParam], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
            if ($mobileView !== null) {
                // Сохраняем выбор в куки
                $this->setCookie($mobileView);
            }
        }

        // Если параметра не было – проверяем куки
        if ($mobileView === null && isset($_COOKIE[$this->cookieName])) {
            $mobileView = ($_COOKIE[$this->cookieName] === '1');
        }

        // По умолчанию – определяем через User-Agent
        if ($mobileView === null) {
            $detect = new MobileDetect();
            $mobileView = $detect->isMobile() && !$detect->isTablet();
        }

        return $mobileView;
    }

    private function setCookie($value)
    {
        $val = $value ? '1' : '0';
        setcookie($this->cookieName, $val, time() + 86400 * $this->cookieLifetime, '/');
    }
}

$selector = new MobileViewSelector();
$isMobile = $selector->getCurrentView();
// Далее используется $isMobile для выбора шаблона
if ($isMobile) {
    echo 'Показываем мобильную версию';
} else {
    echo 'Показываем десктопную версию';
}
?>
// При первом посещении с мобильного – мобильная версия.
// После добавления ?mobile=0 в URL – сохраняется куки и показывается десктопная версия.

Пояснение: класс управляет логикой выбора версии, при этом GET-параметр имеет наивысший приоритет, затем – куки, затем – автоматическое определение. Валидация через FILTER_VALIDATE_BOOLEAN предотвращает инъекции.

Пример 4: Фильтрация и обработка входящего URL для мобильного приложения

Пример

<?php
// Предположим, приложение отправляет запрос на сервер с deep link параметрами
// Необходимо безопасно извлечь данные и проверить подпись

function processIncomingMobileUrl($rawData)
{
    // Входные данные предположительно JSON
    $data = json_decode($rawData, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        return ['error' => 'Invalid JSON'];
    }

    // Валидация обязательных полей
    $required = ['path', 'user_id', 'timestamp'];
    foreach ($required as $field) {
        if (empty($data[$field])) {
            return ['error' => 'Missing required field: ' . $field];
        }
    }

    // Проверка подписи (например, HMAC)
    $secret = 'my_secret_key';
    $signature = hash_hmac('sha256', $data['path'] . $data['user_id'] . $data['timestamp'], $secret);
    if (!isset($data['signature']) || $data['signature'] !== $signature) {
        return ['error' => 'Invalid signature'];
    }

    // Дополнительная очистка пути (запрещаем ../)
    $cleanPath = preg_replace('/[^a-zA-Z0-9_\/\-]/', '', $data['path']);
    if (strpos($cleanPath, '..') !== false) {
        return ['error' => 'Invalid path'];
    }

    return ['success' => true, 'path' => $cleanPath, 'user_id' => (int)$data['user_id']];
}

$incoming = '{"path":"profile/1234","user_id":"42","timestamp":"1700000000","signature":"abc..."}';
$result = processIncomingMobileUrl($incoming);
print_r($result);
?>
Array
(
    [success] => 1
    [path] => profile/1234
    [user_id] => 42
)

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

Мобильный URL в PHP - comments

En
Mobile php url (php)