PHP

Как сделать свой сервис коротких ссылок

С ростом популярности социальных сетей типа Twitter, где длина сообщения ограничена, возникла необходимость в специальных сервисах для сокращения длинных ссылок. В результате появилось много сайтов, где вы можете ввести длинную ссылку и вместо нее получить короткую. При переходе по такой ссылке вы сперва попадаете на сайт-редиректор, а уже с него выполняется автоматический переход на нужную ссылку. Я даже встречал такие сокращенные ссылки в печатных изданиях, а не только в интернете. Ничего сложного в реализации такого сервиса нет, и сейчас мы сделаем что-нибудь подобное.

Начинается все с покупки короткого доменного имени. Все красивые имена уже разобраны или захвачены киберсквоттерами, но кое-что еще можно найти. В конце концов, рядовому пользователю нет особой разницы, по красивой ссылке идти или по некрасивой, главное чтобы она помещалась в его сообщение. Хорошо, домен у нас есть, едем дальше.

А дальше нам надо продумать структуру базы данных, в которой будут храниться короткие ссылки и их соответствия. Поскольку мы делаем сейчас самый простейший сервис, то пусть структура базы будет такой:
CREATE TABLE IF NOT EXISTS `redirector_links` (
`link_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'ID ссылки в базе',
`link_hash` VARCHAR(32) COMMENT 'Хэш ссылки',
`link_url` TEXT COMMENT 'Адрес ссылки',
PRIMARY KEY (`link_id`),
KEY `link_hash` (`link_hash`)
) ENGINE=MyISAM

Хэш ссылки нужен для того, чтобы не создавать в базе дубли для повторяющихся ссылок. В принципе, сюда же можно добавить счетчик для сбора статистики переходов, добавить принадлежность к какому-нибудь владельцу и т.п. Все зависит от поставленных задач.

Следующий шаг - выбор формата коротких ссылок. Оптимально, чтобы они имели вид "http://site/id", где id - это индекс ссылки в нашей базе, по которой будет выполнен переход. Можно использовать привычную числовую систему, а можно сэкономить еще несколько байт в ссылке за счет использования других символов кроме цифр. Например, возьмем все буквы английского алфавита, причем строчные и прописные будут считаться различными "цифрами". Вместе с десятичными цифрами получится 62 символа. Но традиционными средствами PHP с такими "числами" работать нельзя. Для этого нам потребуются две вспомогательные функции для преобразования числа из десятичной системы счисления в 62-ричную и обратно:
// Функция получения кода ссылки из индекса
function dec2link($id) {
    $digits='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $link='';
    do {
        $dig=$id%62;
        $link=$digits[$dig].$link;
        $id=floor($id/62);
    } while($id!=0);
    return $link;
}

// Функция получения индекса из кода ссылки
function link2dec($link) {
    $digits=Array('0'=>0,  '1'=>1,  '2'=>2,  '3'=>3,  '4'=>4,  '5'=>5,  '6'=>6,
                  '7'=>7,  '8'=>8,  '9'=>9,  'a'=>10, 'b'=>11, 'c'=>12, 'd'=>13,
                  'e'=>14, 'f'=>15, 'g'=>16, 'h'=>17, 'i'=>18, 'j'=>19, 'k'=>20,
                  'l'=>21, 'm'=>22, 'n'=>23, 'o'=>24, 'p'=>25, 'q'=>26, 'r'=>27,
                  's'=>28, 't'=>29, 'u'=>30, 'v'=>31, 'w'=>32, 'x'=>33, 'y'=>34,
                  'z'=>35, 'A'=>36, 'B'=>37, 'C'=>38, 'D'=>39, 'E'=>40, 'F'=>41,
                  'G'=>42, 'H'=>43, 'I'=>44, 'J'=>45, 'K'=>46, 'L'=>47, 'M'=>48,
                  'N'=>49, 'O'=>50, 'P'=>51, 'Q'=>52, 'R'=>53, 'S'=>54, 'T'=>55,
                  'U'=>56, 'V'=>57, 'W'=>58, 'X'=>59, 'Y'=>60, 'Z'=>61);
    $id=0;
    for ($i=0; $i<strlen($link); $i++) {
        $id+=$digits[$link[(strlen($link)-$i-1)]]*pow(62,$i);
    }
    return $id;
}

Что нам это дает? Ну, например, семизначное десятичное число 2906248 преобразуется в четырехзначное число "cc2Y", экономия в три символа налицо. Можно подумать, что это "экономия на спичках", но мы же пишем сервис КОРОТКИХ ссылок. Теперь нам надо настроить сервер, чтобы он мог обрабатывать переходы по коротким ссылкам. Это делается через файл .htaccess примерно следующим образом:
DirectoryIndex index.php

RewriteEngine on
Options +FollowSymlinks
RewriteBase /

RewriteRule ^([0-9a-z]+)$ /index.php?link=$1 [NE]

Теперь при переходе по короткой ссылке ее идентификатор будет передан скрипту index.php, затем идентификатор преобразуется из нашей 62-ричной системы счисления в обычное десятичное число и по этому ID выбирается соответствующая запись в базе. Если запись есть - выполняется переадресация на соответствующую ссылку, если записи нет - выводится сообщение об ошибке. На переадресации остановлюсь поподробнее. Ее лучше сделать одновременно несколькими способами, а именно сперва через заголовок сервера "Status: 301 Moved Permanently" и "Location: URL", затем на странице выполняется автоматическая переадресация средствами HTML через тег <meta http-equiv=Refresh content='0; url=URL'>, там же выполняется скрипт JavaScript document.location.href='URL'; и для совсем уже клинических случаев выводится обычная ссылка вида "нажмите сюда, чтобы перейти". Такое решение позволит выполнить переход в любом браузере, независимо от того, поддерживает ли он скрипты, обрабатывает ли заголовки и т.п. Получается что-то вроде такого:
// Ссылка для перехода
$link='http://www.manhunter.ru';
 
// Переадресация заголовками
Header('Status: 301 Moved Permanently');
Header('Location: '.$link);
 
// Переадресация HTML
echo '<meta http-equiv="Refresh" content="0; url='.htmlspecialchars($link).'">';
 
// Переадресация JavaScript
echo '<script type="text/javascript">';
echo 'document.location.href=unescape("'.rawurlencode($link).'");';
echo '</script>';
 
// Ручной переход
echo '<a href="'.htmlspecialchars($link).'">';
echo 'Нажмите сюда для перехода по запрошенной ссылке</a>';

Переходим к добавлению ссылок в базу. Здесь алгоритм следующий: пользователь вводит длинную ссылку, сервис заносит ее в базу и возвращает короткую ссылку вида http://site/id, сформированную на основании ее ID, переведенного в 62-ричную систему счисления. Если такая ссылка уже есть в базе, то новая запись не добавляется, а берется ID ранее добавленной записи. Для проверки уникальности проще всего использовать какой-нибудь хэш типа MD5 (поле link_hash в таблице).

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

В приложении мой скрипт Re:Director 1.0, который представляет собой готовый сервис коротких ссылок. Исходник прокомментирован, можете использовать его совершенно бесплатно при условии сохранения ссылки на сайт и информации об авторе.
Теги:
ссылка, редиректор
Добавлено: 16 Сентября 2013 03:36:24 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...