Функция транслит, автоматические имена ЧПУ

 

Доброго времени суток, спасибо, что заглянули на мой блог! Сегодня мы продолжаем разработку чпу на нашем блоге, если быть точнее то мы продолжаем цикл "Создать блог с нуля". Нам предстоит написать функцию транслит, для того чтобы движок умел автоматически создавать имена ЧПУ из заголовков статьи. Функция не сложная, так что сегодняшний пост будет не очень сложным, и это просто замечательно =)

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

 

 

На этом собственно все что нам сегодня предстоит сделать, как уже и говорил - пост будет не сложным!

 

Для новоприбывших

 

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

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

Если Вы планируете задержаться на моем блоге, то обязательно подпишитесь на RSS ленту блога через ридер, или же по почте, так Вы не пропустите новые заметки касающиеся нашего проекта, то бишь цикла =)

 

Функция транслит - Теория

 

Из чего будет состоять наша функция? Из двух массивов.

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

Обработка заголовка поста будет происходите по следующий схеме:

  • Заголовок режется на символы
  • Каждый символ отыскивается в первом массиве
  • После нахождения символа, в переменную с именем ЧПУ сохранится аналог из второго массива

Таким образом мы из строки

Добро пожаловать!

Получим

dobro-pozhalovat.html

 

Функция транслит - Практика

 

Создаем новый файл в админской папке модулей. Называем этот файл translit.php и пишем в этом файле следующую функцию:

function translit ($title)//функция позволяющая переводить заголовок из русских букв в англо аналог
{
$russimvol = array("а","А","б","Б","в","В","г","Г","д","Д","е","Е","ё","Ё","ж","Ж","з","З",
"и","И","й","Й","к","К","л","Л","м","М","н","Н","о","О","п","П","р","Р",
"с","С","т","Т","у","У","ф","Ф","х","Х","ц","Ц","ч","Ч","ш","Ш","щ","Щ",
"ы","Ы","э","Э","ю","Ю","я","Я","a","A","b","B","c","C","d","D","e","E",
"f","F","g","G","h","H","i","I","j","J","k","K","l","L","m","M","n","N",
"o","O","p","P","q","Q","r","R","s","S","t","T","u","U","v","V","w","W",
"x","X","y","Y","z","Z","1","2","3","4","5","6","7","8","9","0","-"," ");//Массив с русcкими и английскими символами
$anglsimvol = array("a","a","b","b","v","v","g","g","d","d","e","e","yo","yo","zh","zh",
"z","z","i","i","j","j","k","k","l","l","m","m","n","n","o","o","p","p",
"r","r","s","s","t","t","u","u","ph","ph","h","h","c","c","ch","ch",
"sh","sh","shh","shh","y","y","e","e","yu","yu","ya","ya","a","a",
"b","b","c","c","d","d","e","e","f","f","g","g","h","h","i","i",
"j","j","k","k","l","l","m","m","n","n","o","o","p","p","q","q",
"r","r","s","s","t","t","u","u","v","v","w","w","x","x","y","y",
"z","z","1","2","3","4","5","6","7","8","9","0","-","-");//массив с аналогом русских и английских символов
for($i=0;isset($title[$i]);$i++)//листаем цикл пока есть буквы в заголовке поста
{
for($sim=0;$sim<=126;$sim++)//максимальное кол-во циклов равна 126. зависит от кол-ва символов в массиве
{
if($title[$i] == $russimvol[$sim])//если нашли совпадение символа в заголовке с символом в массиве
{
$result .= $anglsimvol[$sim];//сохраняем аналог найденного символа в отдельной переменной
break;//завершаем цикл (второй for)
}
}
}
return $result;//выводим результат
}

Как видите для каждого элемента первого массива имеется свой аналог в во втором массиве. Например буква "ю" из первого массива, во втором массиве представлена как "yu".

Максимальное вращение цикла для каждого символа будет равна 126. Но конструкция break помогает значительно сократить цикл, тем самым этот скрипт не грузит сервер. Да и как мне кажется, даже если убрать break то скрипт все равно не будет пагубно влиять на сервер, ибо информация в массивах ничтожна

Что касается самого разбиение заголовка на символы. Я прибег к следующему приему. Например у нас есть переменная text, которая содержит слово "Текст". Как вытащить первую букву из слова "Текст"? Вот так:

echo $text[0];

Как вытащить букву "к" из слова "Текст", вот так:

echo $text[2];

Надеюсь понятно.. Погуглил, нашел некую информацию о том, что могут возникнуть проблемы если с кодировкой не порядок (у нас вроде с ней порядок), но такой способ поиска символов у меня работает как на локальном сервере, так и на этом блоге.

 

Прикручиваем функцию транслит к модулям админ панели

 

Полный код модулей я писать не буду, только обработчики, так что будьте внимательны при исправление кода модулей!

 

Модуль добавление контента - addcontent.php

 

Вот как выглядит обработчик модуля:

//Объявляем переменные, если форма была заполнена и отправлена
if($_POST['name_post'])$name_post = $_POST['name_post'];
if($_POST['txt_post'])$txt_post = $_POST['txt_post'];
if($_POST['author_post'])$author_post = $_POST['author_post'];
if($_POST['menu_post'])$menu_post = $_POST['menu_post'];
if($_POST['metad_post'])$metad_post = $_POST['metad_post'];
if($_POST['metak_post'])$metak_post = $_POST['metak_post'];
//Объявляем переменные, если форма была заполнена и отправлена

if($name_post & $txt_post & $author_post)
{
$metad_post = htmlspecialchars($metad_post);
$metak_post = htmlspecialchars($metak_post);

$date_day = date("d");//Определяем день
$date_month = date("m");//Определяем месяц
$date_year = date("Y");//Определяем год
$date_time = date("H:i");//Определяем часы и минуты
$date_cont = $date_day."/".$date_month."/".$date_year." ".$date_time;//Склеим все переменные в одну
//получим дату для записи в формате день/месяц/год часы:минуты

//Избавляемся от кавычки
$name_post = str_replace("'","&#039",$name_post);
$txt_post = str_replace("'","&#039",$txt_post);
$author_post = str_replace("'","&#039",$author_post);
$metak_post = str_replace("'","&#039",$metak_post);
$metad_post = str_replace("'","&#039",$metad_post);

include("moduls/translit.php");
$nameurl = translit($name_post).".html";

//ДОБАВЛЯЕМ ПОСТ В БАЗУ ДАННЫХ
$result_add_cont = mysql_query ("INSERT INTO blog (nameurl,text,title,author,date_b,cat,meta_d,meta_k,viewindex,viewcomm,sm,xmlsm,rss)
VALUES ('$nameurl','$txt_post','$name_post','$author_post','$date_cont','$menu_post','$metad_post','$metak_post','0','1','0','monthly|0.2','0')");
//ДОБАВЛЯЕМ ПОСТ В БАЗУ ДАННЫХ

header("location: index.php");//Перенаправление
exit;//на главную страницу
}

Изменения минимальные, подключение функции траслит, запуск ее. И на по следок прописана переменная ($nameurl) в запросе базы данных

 

Модуль редактора контента - allcontent.php

 

Вот код обработчика

//ОБРАБОТЧИК
//Объявляем переменные, если форма была отправленна
if($_POST['edd_name_post'])$edd_name_post = $_POST['edd_name_post'];
if($_POST['edd_txt_post'])$edd_txt_post = $_POST['edd_txt_post'];
if($_POST['edd_author_post'])$edd_author_post = $_POST['edd_author_post'];
if($_POST['edd_id_post'])$edd_id_post = $_POST['edd_id_post'];
if($_POST['edd_metad_post'])$edd_metad_post = $_POST['edd_metad_post'];
if($_POST['edd_metak_post'])$edd_metak_post = $_POST['edd_metak_post'];
//Объявляем переменные, если форма была отправленна

if($edd_name_post & $edd_txt_post & $edd_author_post)
{
$edd_metad_post = htmlspecialchars($edd_metad_post);
$edd_metak_post = htmlspecialchars($edd_metak_post);

//Избавляемся от кавычки
$edd_name_post = str_replace("'","&#039",$edd_name_post);
$edd_txt_post = str_replace("'","&#039",$edd_txt_post);
$edd_author_post = str_replace("'","&#039",$edd_author_post);
$edd_metak_post = str_replace("'","&#039",$edd_metak_post);
$edd_metad_post = str_replace("'","&#039",$edd_metad_post);

include("moduls/translit.php");
$eddnameurl = translit($edd_name_post).".html";

//ОБНОВЛЯЕМ ПОСТ В БАЗЕ ДАННЫХ
$edd_blog = mysql_query ("UPDATE blog SET nameurl='$eddnameurl', text='$edd_txt_post', title='$edd_name_post', author='$edd_author_post', meta_d = '$edd_metad_post', meta_k = '$edd_metak_post' WHERE id='$edd_id_post'");
//ОБНОВЛЯЕМ ПОСТ В БАЗЕ ДАННЫХ

header("location: index.php?page=all_content");//Перенаправление
exit;//на главную страницу
}
//ОБРАБОТЧИК

Изменения теже самые что и в предыдущем пункте!

 

Модуль добавление пункта меню - addmenu.php

 

//ДОБАВЛЯЕМ ПУНКТ МЕНЮ
if(isset($_POST['addname_p']))$addname_p = $_POST['addname_p'];
if(isset($_POST['addhref_p']))$addhref_p = $_POST['addhref_p'];
if(isset($addname_p) AND isset($addhref_p))
{
$result_index = mysql_query("SELECT COUNT(*) FROM menu");//Выводим из базы данных пункты меню
$myrow_index = mysql_fetch_array($result_index);

$col = $myrow_index[0];//Узнаем общее количество пунктов в базе данных
$col++;

include("moduls/translit.php");
$addnameurl_p = translit($addname_p).".html";

$result_add_menu = mysql_query ("INSERT INTO menu (nameurl,name,href,position,podmenu)
VALUES ('$addnameurl_p','$addname_p','$addhref_p','$col','0')");

header("location: index.php?page=all_menu");//Перенаправление
exit;//на страницу пунктов меню
}
//ДОБАВЛЯЕМ ПУНКТ МЕНЮ

Без комментариев =)

 

Модуль редактирование пункта меню - eddmenu.php

 

//РЕДАКТИРУЕМ ПУНКТ МЕНЮ
if(isset($_POST['name_p']))$name_p = $_POST['name_p'];
if(isset($_POST['href_p']))$href_p = $_POST['href_p'];
if($_GET['edd_menu'])$edd_menu = $_GET['edd_menu'];
if(isset($name_p) AND isset($href_p))
{
include("moduls/translit.php");
$nameurl_p = translit($name_p).".html";

$edd_punct = mysql_query ("UPDATE menu SET nameurl='$nameurl_p',name='$name_p',href='$href_p' WHERE id='$edd_menu'");

header("location: index.php?page=all_menu");//Перенаправление
exit;//на страницу пунктов меню
}
//РЕДАКТИРУЕМ ПУНКТ МЕНЮ

Я думаю у Вас не должно возникнуть проблем, прикрутка функции траслит это ведь пару пустяков =)

 

Заключение

 

На по следок приведу скриншот работы нашей прикрученной функции траслит в редакторе поста

 

функция транслит - пример

 

Если у Вас есть какие либо вопросы, то пользуйтесь формой ниже! Если Вам понравился мой проект, то обязательно подпишитесь на RSS ленту блога через ридер, или же по почте

Всего Вам наилучшего! У меня все!

Исходник
 

Возможно Вам будут интересны следующие заметки

Комментарии (10)

Ваше имя *
Сайт
Ваш E-mail *
Ваше сообщение *
 
Вы не подтвердили условия политики конфиденциальности.
Lector, 29 Апреля 2012 г. 10:42 пишет:
Читатель
Вот спасибо! Как я сам не додумался? А то каждый символ replace делал!))) Спасибо!
Роман, 07 Августа 2012 г. 16:17 пишет:
Гость
//ДОБАВЛЯЕМ ПОСТ В БАЗУ ДАННЫХ
$result_add_cont = mysql_query ("INSERT INTO blog (nameurl, text, title, author, date_b, cat, meta_d, meta_k, viewindex, viewcomm, sm, xmlsm, rss)
VALUES ('$nameurl', $txt_post', '$name_post', '$author_post', '$date_cont', '$menu_post', '$metad_post', '$metak_post', '0', '1', '0', 'monthly|0.2', '0')");
//ДОБАВЛЯЕМ ПОСТ В БАЗУ ДАННЫХ


Перед $txt_post апостроф пропущен! В исходниках тоже
Rio-Shaman, 07 Августа 2012 г. 19:11 пишет:
Автор
В коде исправил, исходник перезалил.. Спасибо за наблюдательность =)
Ответ для пользователя: Роман
CoopeR, 12 Июня 2013 г. 14:37 пишет:
Читатель
Проблема с кодировкой действительно есть((
никаких крякообразов нет, но вот автоматический перевод русского на транслит не работает((
В базе всё на utf8, все файлы с расширением *.html сохранены в utf8, файлы с расширением *.php сохранены в utf8 без bom, в файле "index.php" есть строка mysql_query("SET NAMES 'utf8'"); , в файле "index.html" стоит charset= utf-8
Что только не пытался сделать, заметил интересную вещь: если translit.php в разных кодировках сохранять, при utf8 из "тестовая статья" в базе сохраняется "-.html" похоже только пробел меж словами превратился в "-", а вот если ALSI кодировка то в базе "rrrrrrrryor-ssrssryo.html" появляется(((
не смог разобраться и просто прикрутил возможность вручную вводить стоку url, как во многих cms-ках, там они называют "Алиас" кажется
Алексей, 13 Июня 2013 г. 10:35 пишет:
Автор
Проблема в том, что русские буквы в UTF-8 представлены немного иначе чем в windows-1251. Я не помню как это правильно называется, но обращаясь к строке как к массиву в кодировке windows-1251 все проходит на ура, а вот с UTF-8 нет.
Я решал данную проблему кривым костылем =) Перекодировал строку из UTF-8 в windows-1251, а когда нужно было проверить символ перекодировал обратно в UTF-8
Вот цикл который должен работать нормально:

$title = iconv('UTF-8','windows-1251',$title);

for($i=0;isset($title[$i]);$i++)
{

for($sim=0;$sim<=126;$sim++)
{

if (iconv('windows-1251', 'UTF-8', $title[$i]) == $russimvol[$sim])
{

$result .= $anglsimvol[$sim];
break;

}

}

}
Ответ для пользователя: CoopeR
CoopeR, 13 Июня 2013 г. 12:43 пишет:
Читатель
и в правду в файл translit.php вставил цикл перед массивом с русcкими и английскими символами и всё получилось)) сенкс
Виктор, 12 Февраля 2014 г. 23:10 пишет:
Гость
Вставил эту функцию, но не к чему не привело, пишет
Warning: Cannot modify header information - headers already sent by (output started at Z:\home\test1.ru\www\admin\moduls\translit.php:1) in Z:\home\test1.ru\www\admin\moduls\addcontent.php on line 38
подскажите снова в чем у меня проблема?( вот исходник translit.php
<?php

function translit ($title)//функция позволяющая переводить заголовок из русских букв в англо аналог
{
$title = iconv('UTF-8','windows-1251',$title);

for($i=0;isset($title[$i]);$i++) {
for($sim=0;$sim<=126;$sim++) {
if (iconv('windows-1251', 'UTF-8', $title[$i]) == $russimvol[$sim]) {
$result .= $anglsimvol[$sim];
break; }
}
}

$russimvol = array ("а","А","б","Б","в","В","г","Г","д","Д","е","Е","ё","Ё","ж","Ж","з","З",
                   "и","И","й","Й","к","К","л","Л","м","М","н","Н","о","О","п","П","р","Р",
                   "с","С","т","Т","у","У","ф","Ф","х","Х","ц","Ц","ч","Ч","ш","Ш","щ","Щ",
                   "ы","Ы","э","Э","ю","Ю","я","Я","a","A","b","B","c","C","d","D","e","E",
                   "f","F","g","G","h","H","i","I","j","J","k","K","l","L","m","M","n","N",
                   "o","O","p","P","q","Q","r","R","s","S","t","T","u","U","v","V","w","W",
                   "x","X","y","Y","z","Z","1","2","3","4","5","6","7","8","9","0","-"," ");//Массив с русcкими и английскими символами
$anglsimvol = array("a","a","b","b","v","v","g","g","d","d","e","e","yo","yo","zh","zh",
                    "z","z","i","i","j","j","k","k","l","l","m","m","n","n","o","o","p","p",
                    "r","r","s","s","t","t","u","u","ph","ph","h","h","c","c","ch","ch",
                    "sh","sh","shh","shh","y","y","e","e","yu","yu","ya","ya","a","a",
                    "b","b","c","c","d","d","e","e","f","f","g","g","h","h","i","i",
                    "j","j","k","k","l","l","m","m","n","n","o","o","p","p","q","q",
                    "r","r","s","s","t","t","u","u","v","v","w","w","x","x","y","y",
                    "z","z","1","2","3","4","5","6","7","8","9","0","-","-");//массив с аналогом русских и английских символов
for($i=0;isset($title[$i]);$i++)//листаем цикл пока есть буквы в заголовке поста
{
    for($sim=0;$sim<=126;$sim++)//максимальное кол-во циклов равна 126. зависит от кол-ва символов в массиве
    {
        if($title[$i] == $russimvol[$sim])//если нашли совпадение символа в заголовке с символом в массиве
        {
            $result .= $anglsimvol[$sim];//сохраняем аналог найденного символа в отдельной переменной
            break;//завершаем цикл (второй for)
        }
    }
}
return $result;//выводим результат
}
?>
Ответ для пользователя: Алексей
Виктор, 12 Февраля 2014 г. 23:13 пишет:
Гость
а, нет, в базе данных меняет на нормальный код, а ошибку выводит
Warning: Cannot modify header information - headers already sent by (output started at Z:\home\test1.ru\www\admin\moduls\translit.php:1) in Z:\home\test1.ru\www\admin\moduls\addcontent.php on line 38
Виктор, 12 Февраля 2014 г. 23:17 пишет:
Гость
и на конце добавляется пробел
kak-uvelichit-skorost-zagruzki-stranicy----.html
privet-polzovatel-.html
Ответ для пользователя: Виктор
Алексей, 13 Февраля 2014 г. 10:01 пишет:
Автор
Проверьте файл translit.php на наличие правильно кодировки. У Вас где-то в коде что-то посылается в браузер.
Ответ для пользователя: Виктор