Blog. Just Blog

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

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
С ростом популярности социальных сетей типа 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-ричную и обратно:
  1. // Функция получения кода ссылки из индекса
  2. function dec2link($id) {
  3.     $digits='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  4.     $link='';
  5.     do {
  6.         $dig=$id%62;
  7.         $link=$digits[$dig].$link;
  8.         $id=floor($id/62);
  9.     } while($id!=0);
  10.     return $link;
  11. }
  1. // Функция получения индекса из кода ссылки
  2. function link2dec($link) {
  3.     $digits=Array('0'=>0,  '1'=>1,  '2'=>2,  '3'=>3,  '4'=>4,  '5'=>5,  '6'=>6,
  4.                   '7'=>7,  '8'=>8,  '9'=>9,  'a'=>10'b'=>11'c'=>12'd'=>13,
  5.                   'e'=>14'f'=>15'g'=>16'h'=>17'i'=>18'j'=>19'k'=>20,
  6.                   'l'=>21'm'=>22'n'=>23'o'=>24'p'=>25'q'=>26'r'=>27,
  7.                   's'=>28't'=>29'u'=>30'v'=>31'w'=>32'x'=>33'y'=>34,
  8.                   'z'=>35'A'=>36'B'=>37'C'=>38'D'=>39'E'=>40'F'=>41,
  9.                   'G'=>42'H'=>43'I'=>44'J'=>45'K'=>46'L'=>47'M'=>48,
  10.                   'N'=>49'O'=>50'P'=>51'Q'=>52'R'=>53'S'=>54'T'=>55,
  11.                   'U'=>56'V'=>57'W'=>58'X'=>59'Y'=>60'Z'=>61);
  12.     $id=0;
  13.     for ($i=0$i<strlen($link); $i++) {
  14.         $id+=$digits[$link[(strlen($link)-$i-1)]]*pow(62,$i);
  15.     }
  16.     return $id;
  17. }
Что нам это дает? Ну, например, семизначное десятичное число 2906248 преобразуется в четырехзначное число "cc2Y", экономия в три символа налицо. Можно подумать, что это "экономия на спичках", но мы же пишем сервис КОРОТКИХ ссылок. Теперь нам надо настроить сервер, чтобы он мог обрабатывать переходы по коротким ссылкам. Это делается через файл .htaccess примерно следующим образом:

DirectoryIndex index.php

RewriteEngine on
Options +FollowSymlinks
RewriteBase /

RewriteRule ^([0-9a-zA-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'; и для совсем уже клинических случаев выводится обычная ссылка вида "нажмите сюда, чтобы перейти". Такое решение позволит выполнить переход в любом браузере, независимо от того, поддерживает ли он скрипты, обрабатывает ли заголовки и т.п. Получается что-то вроде такого:
  1. // Ссылка для перехода
  2. $link='http://www.manhunter.ru';
  3.  
  4. // Переадресация заголовками
  5. Header('Status: 301 Moved Permanently');
  6. Header('Location: '.$link);
  7.  
  8. // Переадресация HTML
  9. echo '<meta http-equiv="Refresh" content="0; url='.htmlspecialchars($link).'">';
  10.  
  11. // Переадресация JavaScript
  12. echo '<script type="text/javascript">';
  13. echo 'document.location.href=unescape("'.rawurlencode($link).'");';
  14. echo '</script>';
  15.  
  16. // Ручной переход
  17. echo '<a href="'.htmlspecialchars($link).'">';
  18. echo 'Нажмите сюда для перехода по запрошенной ссылке</a>';
Переходим к добавлению ссылок в базу. Здесь алгоритм следующий: пользователь вводит длинную ссылку, сервис заносит ее в базу и возвращает короткую ссылку вида http://site/id, сформированную на основании ее ID, переведенного в 62-ричную систему счисления. Если такая ссылка уже есть в базе, то новая запись не добавляется, а берется ID ранее добавленной записи. Для проверки уникальности проще всего использовать какой-нибудь хэш типа MD5 (поле link_hash в таблице).

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

В приложении мой скрипт Re:Director 1.1, который представляет собой готовый сервис коротких ссылок. Исходник прокомментирован, можете использовать его совершенно бесплатно при условии сохранения ссылки на сайт и информации об авторе.

Re:Director 1.1Re:Director 1.1

Re.Director.1.1-PCL.zip (3,942 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 30612 | Комментариев: 24

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (16.11.2018 в 14:05):
Да там не только это надо было чинить. Версия 1.1, поправил все что можно.
Артём (16.11.2018 в 14:00):
Вроде починил. Заменил mysql на mysqli везде и добавил в параметры $con,

Добавил в //настройки подключения к базе
$con = mysqli_connect('localhost','USER','PASS') or die(mysqli_connect_error());
    mysqli_select_db($con, 'DBNAME') or die("Cannot select DB");
Артём (16.11.2018 в 13:26):
Обращения к базе данных.

Fatal error: Uncaught Error: Call to undefined function mysql_query()

Warning: mysqli_select_db() expects exactly 2 parameters, 1 given in - это когда заменил  mysql на mysqli
ManHunter (16.11.2018 в 08:53):
И что в скрипте такого, чего не заработает на 7.2?
Артём (16.11.2018 в 07:01):
Привет!!
Версию для PHP 7.2 сделаем?
Вася (26.04.2018 в 20:45):
Куда поставить автору большой плюс ?
ManHunter (01.02.2018 в 16:26):
Еще при переадресации можно добавить заголовок Referrer-Policy: no-referrer
Вот тут описание: http://docs.w3cub.com/http/hea...rrer-policy/
Алекстандр (15.03.2017 в 20:00):
Вот еще подобный сервис [spam]
ManHunter (04.11.2016 в 22:13):
Через кассу. Платишь деньги и твои желания сбываются.
Сергей (04.11.2016 в 16:57):
Скажите а как Api приделать к этому сайту?
ManHunter (04.06.2016 в 09:00):
Добавить путь в html-форму и скрипт, где эти пути используются.
Андрей (04.06.2016 в 08:51):
А как сделать, что бы скрипт был не в корне сайта, а в папке, например в click?
ManHunter (07.01.2016 в 22:14):
Заменить везде в исходнике и .htaccess все "index.php" на "link.php", в <form action="/" заменить на "/link.php", при необходимости заменить Header('Location: /'); на /link.php

И незачем дублировать в чате, я и так все прекрасно вижу.
Vladimir (07.01.2016 в 20:43):
у меня файл называется не index.php, а link.php. и при генерации ссылки на link.php он перебрасывает на index.php. как исправить? спасибо)
AndHacker (29.12.2014 в 11:32):
Спасибо, но сайт AndHacker.ru и andhacker.ru - изменяя регистр записывает как два разных сайта
Alex (21.10.2014 в 06:02):
Я год назад искал себе скрипт для коротких ссылок, чего-то пропустил Ваш, надо будет попробовать. Спасибо.
ManHunter (20.07.2014 в 19:05):
Да, поправил. Спасибо!
maltsev (20.07.2014 в 18:49):
ЦитатаRewriteRule ^([0-9a-z]+)$ /index.php?link=$1 [NE]

правильно так:
RewriteRule ^([0-9a-zA-Z]+)$ /index.php?link=$1 [NE]
ManHunter (14.06.2013 в 19:56):
Никак. В этом скрипте таких функций не предусмотрено. Нужны доработки - бабло в кассу.
user (14.06.2013 в 18:40):
Как сделать чтобы пользователь сам мог выбирать себе короткий вариант, т.е. не автоматически писался id а самому? Напр.: www.site.ru/reklama
Олег (17.02.2013 в 07:41):
Добрый день!!! Я в php полный 0 но может быть кто то поможет???
1. А как можно добавить время перехода по ссылке что бы при переходе по ссылке переход был не сразу, а через 5сек
2. или что бы перехода вообще не было. Например: на сайт1 подгружаю видео с сайта2, а ссылку на видео маскирую через сервис коротких ссылок. Тоесть что бы никто не видел от куда и скакого сайта грузиться видео.
Igor (04.01.2013 в 10:30):
Полезная статья спасибо большое. А сколько будет стоит зделать автоматизированный сервис сокращения ссылок в котором за каждым зарегистрированным пользователем будет закреплятся "пространство" типа:
1 зарег. пользователь www.ooo.bz/1/a где 1-первый пользователь, а-первая сокращенная ссылка первого зарег. пользователя. и т.д.
ManHunter (02.06.2011 в 08:11):
Я надеюсь, что до сплойтов дело не дойдет :)
AyTkACT (02.06.2011 в 02:40):
>>>>>> а всякие мудаки могут даже показывать принудительную рекламу на странице переадресации.

А конченые мудаки могут добавить вредоносные элементы (скрипты, эксплоит-паки, etc.)...


з.ы. Простенько. Со вкусом. Занимательно!

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0069 сек.) / Память: 4.5 Mb
Наверх