Как спрятать ссылки
Индекс материала |
---|
Как спрятать ссылки |
Как спрятать ссылки стр.2 |
Как спрятать ссылки стр.3 |
Все страницы |
Иногда на страницах сайта требуется спрятать от роботов некоторые ссылки. Нет - речь пойдёт не о клоакинге или чёрном сео, а о нормальной оптимизации сайта. Как известно некоторые движки грешат избыточностью ссылок в своих компонентах и модулях, Взять к примеру ту же Joomla с её индексом материала, прибавьте к нему постраничную навигацию - в итоге получаем дублированные ссылки на странице - оно вам надо?
Кстати, если вам лень читать статью, или попросту нет времени вникать во всё это, то здесь Я разместил этот скрипт ввиде онлайн инструмента.
Так вот. Роботы пока не научились интерпретировать JavaScript, но по слухам вполне ничего себе так заглядывают в его код. Поэтому конструкции типа:
document.write('<a href="/somedomain.net">ля-ля-тополя...</a>');
похоже прокатывают уже через раз. Народ придумал шифровать ссылки в формат кодовых точек unicode, ну типа того: \u003c\u0061\u0020\u0063 есть онлайн сервисы для подобных операций, но что делать если выводимые ссылки формируются движком динамически? Что - что... читать-понимать принцип кодирования многобайтных кодировок в unicode. Что такое unicode и ASCII спросите у google он должен знатьЕсли у вас сайт в модной нынче кодировке UTF-8 а расширения типа mb_string и iconv вам не доступны (бывает и такое) или просто интересно, как это можно сделать самому, то читайте дальше.
Итак. В unicode существуют так называемые "кодовые точки", которые имеют вид: U+007F или U+0400. После префикса U+ следует шестнадцатиричное число ( предварённое нулями ). Фактически это порядковое шестнадцатиричное число позиции символа: U+006B это 6B в шестнадцатиричной, или 107 в десятичной системе или маленькая латинская буква "k" в соответствии с ASCII.
В диапазоне от U+0000 до U+007F ( это интервал от 0 до 127 в десятичном представлении) число после "U+" совпадает с шестнадцатиричным кодом символа в ASCII. Это диапазон латиницы и других печатных/не печатных символов (типа пробела и пр.) то есть символов для хранения и обработки которых требуется 1 байт. После U+007F - кодовые точки unicode следуют далее по порядку, а вот нормальное их шестнадцатиричное представление символов там уже требует 2 байта, т.е. 4 - шестнадцатиричных цыфры: U+0080 соответствует С2 80 (какой то непечатный символ).
Принцип кодирования многобайтных символов следующий:
Unicode (шестнадцатиричный) | Unicode ( двоичный ) |
---|---|
0x0000 – 0x007F | 0xxxxxxx |
0x0080 – 0x07FF | 110xxxxx 10xxxxxx |
0x0800 – 0xFFFF | 1110xxxx 10xxxxxx 10xxxxxx |
Вы всё еще здесь? Теперь интересное. В таблице видно что для однобайтного символа двоичное представление начинается с 0, а вот для многобайтного с 1. Причем количество единичек в первом байте (ещё его называют стартовым байтом многобайтовой последовательности ) прямо указывает на количество байт нужных для кодировки данного символа. Далее идут серийные байты которые начинаются с 10, и количество которых определено в стартовом байте. Ну а биты символа unicode упаковываются в "транспортные" биты стартового и серийных байтов, обозначенных выше как "xxxx"
В принципе, поняв весь этот двоично-шестнадцатирично-десятичный коматоз, можно понять как нам кодировать символы средствами PHP. Javascript "понимает" литералы юникода в таком виде: \u0410 т.е. префикс у него свой. Наша задача заключается в том, что нам будет нужно перегнать строку, которая содержит, как кирилицу, латиницу и спец. символы в шестнадцатиричное их представление. Причём каждый символ в отдельности.
Здесь мы постараемся обойтись без всякого рода расширений типа mb_string и iconv (мы же не ищем лёгких путей) а только фунуцией PHP bin2hex() - она вернет шестнадцатиричное представление строки-символа например 'a'. По строке пройдёмся циклом, как по массиву. И будем работать с каждым символом по отдельности.
Кстати если у вас не прописано в php.ini mbstring.func_overload=1 и впринципе недоступна mb_string. И если ваш сайт в UTF-8 То код:
echo strlen('один');
Выведет число 8! - Почему? Правильно: потому что каждый кирилический символ в юникоде кодируется двумя байтами, вот такие приколы люди и имеют ввиду, когда говорят о сложности работы в PHP с unicode. Фактически функция strlen() - возвращает нам не длину слова в буквах, а длину слова в байтах! И вкоде ниже, в цикле мы фактически будем шагать не по символам слова, а по его байтам! В данном случае нам это как раз на руку. По сути нам интересен интервал от U+0410 до U+044F - интервал кириллицы в юникоде символы здесь представлены двумя байтами. Если взятый ( идём циклом по строке ) байт символов (первый из двух) умещается в диапазоне от D0 до D1 (можете посмотреть таблицу символов unicode), то это значит, что к нему нужно прибавить (здесь я имею ввиду операцию конкатенации ) следующий за ним байт, точнее его шестнадцатиричное представление.
Иначе если взятый байт меньше или равен 7Е то значит нам попался однобайтный символ, к нему просто конкатенируем спереди "\u00" (с дополнительными нулями потому что так Javascript работает)
А совсем в ином случае (если байт не в диапазоне D0-D1 и он больше 7Е) тупо пропускаем то что попалось через PHP функцию htmlentities() .
Ура мы получили корректное шестнадцатиричное представление символов подопытной строки, но однобайтные символы у нас уже готовы к выводу через JavaScript, а вот то что у нас представляет кирилицу находится пока только в шестнадцатиричном представлении, и правильно работать не будет.
Теперь шестнадцатиричные коды кирилицы нужно перевести в кодовые точки unicode. Для этого смотрим в таблицу unicode и тупо копируем значения в два массива паралельно. В одном будут кодовые точки, а в другом шестнадцатиричные числа, соответсвующие этим точкам. Смотрите не напутайте :)
Осталось только прогнать всё это через функцию str_replace() и вернуть из нашей функции. Ниже приведён полный код функции с массивами сопоставления кодировки и подробными комментариями:
<?php // На всякий случай проверка: if(!function_exists('conv')) { function conv($str) { // Переменная для "накопления" результирующей строки: $uot = ''; // Здесь хранятся кодовые точки unicode // в формате удобном JavaScript: $unicodePoints = array( '\u0410','\u0411','\u0412','\u0413', '\u0414','\u0415','\u0416','\u0417', '\u0418','\u0419','\u041A','\u041B', '\u041C','\u041D','\u041E','\u041F', '\u0420','\u0421','\u0422','\u0423', '\u0424','\u0425','\u0426','\u0427', '\u0428','\u0429','\u042A','\u042B', '\u042C','\u042D','\u042E','\u042F', '\u0430','\u0431','\u0432','\u0433', '\u0434','\u0435','\u0436','\u0437', '\u0438','\u0439','\u043A','\u043B', '\u043C','\u043D','\u043E','\u043F', '\u0440','\u0441','\u0442','\u0443', '\u0444','\u0445','\u0446','\u0447', '\u0448','\u0449','\u044A','\u044B', '\u044C','\u044D','\u044E','\u044F'); // Здесь хранятся шестнадцатиричные представления чисел // этот массив сопоставим с массивом сверху по таблице // юникод $hexView = array( 'd090','d091','d092','d093', 'd094','d095','d096','d097', 'd098','d099','d09a','d09b', 'd09c','d09d','d09e','d09f', 'd0a0','d0a1','d0a2','d0a3', 'd0a4','d0a5','d0a6','d0a7', 'd0a8','d0a9','d0aa','d0ab', 'd0ac','d0ad','d0ae','d0af', 'd0b0','d0b1','d0b2','d0b3', 'd0b4','d0b5','d0b6','d0b7', 'd0b8','d0b9','d0ba','d0bb', 'd0bc','d0bd','d0be','d0bf', 'd180','d181','d182','d183', 'd184','d185','d186','d187', 'd188','d189','d18a','d18b', 'd18c','d18d','d18e','d18f' ); // Идём по строке как по массиву: for($i=0; $i < strlen( $str ); $i++) { // Если байт начинается с 11xx, то это стартовый // байт многобайтной последовательности // Здесь у нас идёт сравнение с шестнадцатиричным // числом: 'd0', в двоичном представлении // это будет как раз число 11010000, если это так... if(bin2hex($str{$i}) >= 'd0' && bin2hex($str{$i}) <= 'd1') { // то записываем в результирующую стоку этот // байт в шестнадцатиричном представлении // и следующий за ним, так как это будут два // байта одного кирилического символа: $uot .= bin2hex($str{$i}).bin2hex($str{$i+1}); // увеличиваем счётчик, что бы проскочить на //следующий итерации уже взятый нами следующий байт: $i++; } // Иначе если шестнадцатиричное представление // байта меньше 7Е, то перед нами однобайтный символ: elseif(bin2hex($str{$i}) <= '7e') { $uot .= '\u00'.bin2hex($str{$i}); } // Иначе перед нами иной символ который просто обрабатываем: else $uot .= htmlentities($str{$i},ENT_QUOTES,'UTF-8'); } // Здесь замещаем шестнадцатиричные представления кирилических символов // кодовыми точками unicode и возвращаем результат: return str_replace($hexView,$unicodePoints, $uot); } } ?>
В итоге получаем кодированную строку примерно такого вида:
\u003c\u0061\u0020\u0063\u006c\u0061\u0073\u0073\u003d\u0022\u0068\u006f
Котую выводим в PHP - скрипте следующей конструкцией:
echo '<script type="text/javascript"> document.write("'.conv('<a href="/xxxx">ссылка</a>').'"); </script>';
Она скроет от роботов лишние ссылки, которые в принципе нужно оставить на странице для удобства пользователей. Что вы кстати можете наблюдать у меня на сайте, если просмотрите исходный код страницы. Уф.. Фсё!
Свое дело - эффективные методы создания бизнеса
Свое дело - эффективные методы создания бизнеса
gejzer.ru
Разработки СТУ
Стоимость разработки СТУ в Москве.
промэкоконсалтинг.рф
Добавить комментарий
Информация копипастерам
Внимание! Копирование контента с сайта, возможно только с разрешения администратора. Т.е. Меня! Я скорее всего разрешу Вам это сделать, в обмен на живую ссылку, на статью оригинал.