За последние 24 часа нас посетил 20341 программист и 1711 роботов. Сейчас ищут 1617 программистов ...

Парсер тегов (облако тегов)

Тема в разделе "Вопросы от блондинок", создана пользователем SkyKiller, 6 май 2008.

  1. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    Приветсвую всех!
    Есть пара вопросов для гуру:
    В MySQL-базе хранится текстовая строка с ключевиками (тэгами), которые используются в кулинарном рецепте. Например,
    Код (Text):
    1. кинза, курица, помидор, перец, морковь, масло растительное, баклажан, лук, чеснок
    Надо написать небольшой парсер для этой строки, чтобы он разбивал эту строку на отдельные слова (без запятой и последующего пробела) и делал их ссылками на search.php?q=кинза или на search.php?q=курица
    Вот как-то так... Может, у кого-то есть примеры такой разбивки или функции? Какими функциями это реализовать?

    И ещё вопрос как раз по поиску. Мне очень интересно, как PHP будет обрабатывать поисковый запрос (который приведён выше), если там в строке запроса встречается слово на русском языке? Или надо как-то преобразовывать это слово?
    Сайт и база в кодировке cp1251...

    Спасибо!

    P.S. Сорри за ламерские вопросы, но сегодня голова вообще не работает, а делать надо :(
     
  2. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
  3. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    Спасибо! Прочёл.
    Даже начинаю уже соображать что-то :)
     
  4. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    PHP:
    1. <?
    2. if (!empty($row["recipeTags"])) { // Если тэги в базе есть
    3. $tags = explode(", ", $row["recipeTags"]); // Разбиваем строку на отдельные слова
    4. $tagscount = count($tags); // Считаем количество элементов массива $tags
    5. $tagline = implode(", ", "<a href=#>".$tags."</a>"); // Собираем массив обратно, но уже с УРЛами
    6. ?>
    7.  
    Даёт ошибку в последней строке
    Код (Text):
    1. Warning: implode() [function.implode]: Invalid arguments passed in /home/site/www/view.php on line 42
    Ведь $tags - это же массив после разбивки? Что ей не нравится? :(
     
  5. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    ругается на <a href=#> внутри implode...
    Соответсвенно, сейчас встаёт вопрос о том, как сначала переделать каждый элемент массива $tags в ссылку, а потом собрать...
    Кто-нибудь решал такую задачу?
     
  6. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    С первым вопросом моего поста разобрался. При помощи вот такого кода:
    PHP:
    1. <?php
    2.         if (!empty($row["recipeTags"])) {                  // Если строка тэгов в базе не пустая, то:
    3.           $tags = explode(", ", $row["recipeTags"]);   // Разбиваем строку тэгов на слова
    4.           $tagscount = count($tags);                         // Считаем их количество
    5.  
    6.           for ($i = 0; $i < $tagscount; $i++) {           // Перебираем каждый элемент и присваиваем ему ссылку
    7.               $tags[$i] = "<a href=\"/search.php?searchquery=".$tags[$i]."\">".$tags[$i]."</a>";
    8.           }
    9.  
    10.           $tagline = implode(", ", $tags);                   // Собираем обратно, но уже со ссылками
    11.  
    12.           echo "<tr><td>";
    13.           echo $tagline;
    14.           echo "</td></tr>";
    15.  
    16.         }
    17. ?>
    18.  
    Тэги выводит, всё замечательно. При наведении на тэг ссылка выглядит так:
    http://mysite.com/search.php?searchquery=курица
    а при нажатии на неё идёт переход на
    http://mysite.com/search.php?searchquer ... 0%E8%F6%E0
    то есть, ссылка конвертируется и, соответственно, поиск не работает и ничего не ищет. :(
    В какую сторону копать?
    Не хотелось бы и сайт и базу в UTF переделывать только из-за этого... :(
     
  7. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
  8. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    Да, уже нарыл в гугле, читаю описалово. Спасибо!
     
  9. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Хе... а я себе представлял облако тегов немного по-другому: при добавлении статьи, ключевые слова добавляются в специальную таблицу. При просмотре облака - считается количество ссылок на слово и в соответствии с этим определяется размер шрифта.
    А если по каждому слову делать поиск в бд... А что если слов будет сотня?
     
  10. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    +1
     
  11. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    Насчёт "облака" - я, наверное, погорячился с определением. Просто есть кулинарный сайт, где у каждого рецепта - свои ключевые слова.
    Меня не интересует, например, сколько рецептов содержат слово "соль" (наверняка, в классическом облаке слово "соль" будет самым жирным). Это немного не то, как в Вордпрессе.
    Меня интересует, какие рецепты вообще содержат "соль".
    Например, редкий тэг - "васаби" (например!). Выводятся все рецепты, которые содержат в себе "васаби". И не имеет значения, как часто это слово встречается в рецептах и как жирно оно выделено в облаке.
    Извиняюсь, если запутал с определением.
     
  12. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    SkyKiller
    Я бы все же сделал ключевые слова в другой таблице с индексным столбцом и id-шником статьи.
    В форме поиска был бы какой-нибудь селект, в котором ингридиенты-ключевики (они отрисовывались бы по данным SELECT DISTINCT `key` FROM `keys`), потом производился бы запрос с поиском (LIKE) в таблицу с ключами и выдавались id-статей, а на их основе можно выбрать тела/названия самих статей ("краткое описание"). Мне кажется, что такой подход имеет следующие преимущества:
    1) Легко получить все ключевые слова
    2) Быстрее, чем поиск и выборка по всей базе со статьями

    Запрос будет где-то таким -
    SELECT `title` FROM `items` WHERE id = ANY (SELECT `item_id` FROM `keys` WHERE `key` LIKE "%'.$word.%")
     
  13. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    Заманчиво, но (опять же, повторюсь) мне не нужен вес тэгов. Мне просто надо знать, какие рецепты содержат ингредиент "васаби".
    :)
     
  14. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    А там и он не узнается (хоть его и можно получить). Правда я писал про структуру базы, а не про конкретный вопрос в начале топика.

    По поводу самого вопроса:
    Как я понимаю, в таблице, где хранятся статьи есть и ключевые слова к ним. И где-то в конце страницы они выводятся.
    Да, необходимо делать так:
    $keys = explode(", ", $row["keys"]); //при выводе из базы
    for ($i = 0; $i < sizeof($keys); $i++) {
    echo '<a href="search.php?q='.$keys[$i].'">'.$keys[$i].'</a>';
    }

    А в самом search.php - поставить urldecode при приемке строки запроса.
    Кодировка не должна быть bin, иначе будет регистрозависимой.

    Вариант из предыдущего поста это для общего поиска (допустим в разделе "поиск").

    Может я чего-то не понял. Вы бы написали примерный вид всего. Что есть и что требуется увидеть.
     
  15. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    PHP:
    1. <?
    2. ...
    3. for ($i = 0; $i < sizeof($keys); $i++) {
    4. echo '<a href="search.php?q='.$keys[$i].'">'.$keys[$i].'</a>';
    5. }
    6.  
    а мне кажется что foreach удобней ;-)
     
  16. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    foreach для ассоциативных массивов оптимален.
     
  17. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    Именно так всё и планировалось. Вы правильно всё поняли.
    Всё так и сделал. Разбиваю строку, присваиваю ссылки, собираю и вывожу на экран в конце статьи или рецепта.
    [sql]SELECT recipeTags FROM cooking_recipe WHERE recipeID='$recipe' AND recipeStatus='PUBLISHED'[/sql]
    PHP:
    1. <?php
    2.         if (!empty($row["recipeTags"])) { // Если строка тэгов в базе не пустая, то:
    3.                 $tags = explode(", ", $row["recipeTags"]); // Разбиваем строку тэгов на слова
    4.                 $tagscount = count($tags); // Считаем их количество
    5.                 for ($i = 0; $i < $tagscount; $i++) { // Перебираем каждый элемент и присваиваем ему ссылку
    6.                    $tags[$i] = "<a href="/search.php?searchquery=".$tags[$i]."">".$tags[$i]."</a>";
    7.                 }
    8.                 $tagline = implode(", ", $tags); // Собираем обратно, но уже со ссылками
    9.         echo "<tr><td>";
    10.         echo $tagline; // Выводим
    11.         echo "</td></tr>";
    12.         }
    13. ?>
    14.  
    В search.php проверяю методы GET и POST (поскольку оба используются для поиска) и декодирую:
    PHP:
    1. <?php
    2. if($_SERVER['REQUEST_METHOD']=='POST') {
    3.         if (isset($_POST ['searchquery'])) $searchquery=urldecode($_POST['searchquery']); else $searchquery='';
    4. }
    5. else
    6. if($_SERVER['REQUEST_METHOD']=='GET') {
    7.         if (isset($_GET ['searchquery'])) $searchquery=urldecode($_GET['searchquery']); else $searchquery='';
    8. }
    9. ?>
    10.