Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] wyszukiwarka .txt usunięcie powtórzeń
Forum PHP.pl > Forum > Przedszkole
wujekk13
Na podstawie znalezionych dotąd skryptów udało mi się ułożyć prostą wyszukiwarkę, niestety zauważyłem w niej dwa mankamenty. Po pierwsze dublują mi się wyniki wyszukiwania. Chciałbym prosić forumowiczów o pomoc w usunięciu powtarzających się wyników, tak by link, który odnosi się do konkretnych fragmentów zapytania (chodzi o zapytania składające się z więcej niż jednego słowa/fragmentu słów) wyświetlał się tylko raz, a nie kilka razy.

Podaję kod dla pliku wyszukiwarkatxt2.php:

  1. <?php header('Content-Type: text/html; charset=utf-8'); ?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4. <html xmlns="http://www.w3.org/1999/xhtml">
  5. <head>
  6. <meta http-equiv="content-type" content="text/html; charset=utf-8">
  7. <title>Wyszukiwarka oparta na plikach tekstowych - ITPorady.pl</title>
  8. </head>
  9. <body>
  10.  
  11. <form action="" method="post">
  12. <input type="text" name="wyszukiwarka"/>
  13. <input type="submit" value="Szukaj" />
  14. </form>
  15.  
  16. <?php
  17. function str2url( $str, $replace = "-" ){
  18.  
  19. // konwersja znaków utf do znaków podstawowych
  20. $str = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
  21.  
  22. // Niektóre francuskie i niemieckie litery pozostawiają po takiej konwersji (jak powyżej)
  23. // dodatkowe znaki. Poniższe dwie linijki te znaki wycinają
  24.  
  25. $charsArr = array( '^', "'", '"', '`', '~');
  26. $str = str_replace( $charsArr, '', $str );
  27.  
  28. $return = trim(preg_replace('# +#',' ',preg_replace('/[^a-zA-Z0-9\s]/','',strtolower($str))));
  29. return str_replace(' ', $replace, $return);
  30. }
  31. ?>
  32.  
  33. <?php
  34.  
  35.  
  36. $bl=false;
  37.  
  38. if(isset($_POST['wyszukiwarka']) && $_POST['wyszukiwarka']!=''){
  39. $wyszukiwarka = $_POST['wyszukiwarka'];
  40.  
  41. $dane = file('dane.txt');
  42. echo "<ul>\n";
  43. foreach($dane as $key){
  44. $g = explode(' | ', chop($key));
  45. $gie = explode(' ', $wyszukiwarka);
  46. $ile = count($gie);
  47. for ($fi=0; $fi <$ile; $fi++){
  48. if(stripos(str2url($key), str2url($gie[$fi]))){
  49. echo '<a href="'.$g[0].'" title="'.$g[2].'">'.$g[1]."</a>\n<br>"; //strtolower() - zmienia na małe litery cły tekst/ strtoupper()- zmienia na duże cały tekst/ generują krzaczki zamiast polskich znaków
  50. $bl = true;
  51. }
  52. }
  53. }
  54. //echo '</ul>';
  55. if(!$bl) echo 'nie znaleziono podanej frazy: ' .$wyszukiwarka;
  56. }
  57.  
  58. ?>
  59.  
  60.  
  61. </body>
  62. </html>


oraz kod pliku z danymi dane.txt:
  1. firma.html | f zobacz co proponujemy | hasło nowe inne 0
  2. inne.html | i Mapa dojazdu - zobacz jak do nas dojechać | słowa kluczowe
  3. rura.html | r Witam Witam Witam Witam | bla bla
  4. kontakt.html | kontakt - jeżeli masz jakieś pytania - pisz śmiało! | coś tam innego


Drugi problem jest związany z samym wyszukiwaniem, gdy za pierwszym znakiem "|" mam nazwę taką jak w linku np. "kontakt" to do zapytania "kont" otrzymuję wynik: "nie znaleziono podanej frazy: kont" ale jeśli zapytam o "onta" to otrzymuję link do szukanej strony, czyli do kontakt.html
Ma ktoś może jakiś pomysł dlaczego się tak dzieje i jak można to rozwiązać?

Na wstępie powiem, że nie wiem jak to edytować, żeby dodać poprawki.
Udało mi się zmusić skrypt do generowania wyników wyszukiwania bez powtórzeń oto kod:

  1.  
  2. <?php header('Content-Type: text/html; charset=utf-8'); ?>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  4. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  5. <html xmlns="http://www.w3.org/1999/xhtml">
  6. <head>
  7. <meta http-equiv="content-type" content="text/html; charset=utf-8">
  8. <title>Wyszukiwarka oparta na plikach tekstowych - ITPorady.pl</title>
  9. </head>
  10. <body>
  11.  
  12. <form action="" method="post">
  13. <input type="text" name="wyszukiwarka"/>
  14. <input type="submit" value="Szukaj" />
  15. </form>
  16.  
  17. <?php
  18. function str2url( $str, $replace = "-" ){
  19.  
  20. // konwersja znaków utf do znaków podstawowych
  21. $str = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
  22.  
  23. // Niektóre francuskie i niemieckie litery pozostawiają po takiej konwersji (jak powyżej)
  24. // dodatkowe znaki. Poniższe dwie linijki te znaki wycinają
  25.  
  26. $charsArr = array( '^', "'", '"', '`', '~');
  27. $str = str_replace( $charsArr, '', $str );
  28.  
  29. $return = trim(preg_replace('# +#',' ',preg_replace('/[^a-zA-Z0-9\s]/','',strtolower($str))));
  30. return str_replace(' ', $replace, $return);
  31. }
  32. ?>
  33.  
  34. <?php
  35.  
  36.  
  37. $bl=false;
  38.  
  39. if(isset($_POST['wyszukiwarka']) && $_POST['wyszukiwarka']!=''){
  40. $wyszukiwarka = $_POST['wyszukiwarka'];
  41.  
  42. $dane = file('dane.txt');
  43. echo "<ul>\n";
  44. foreach($dane as $key){
  45. $g = explode(' | ', chop($key));
  46. $gie = explode(' ', $wyszukiwarka);
  47. $ile = count($gie);
  48. for ($fi=0; $fi <$ile; $fi++){
  49. if(stripos(str2url($key), str2url($gie[$fi]))){
  50.  
  51. $wejscie[] = '<a href="'.$g[0].'" title="'.$g[2].'">'.$g[1]."</a>\n<br>";
  52. $tab = array_unique(array_merge ($wejscie));
  53. $bl = true;
  54. }
  55. }
  56. }
  57. if(!$bl) {echo 'nie znaleziono podanej frazy: ' .$wyszukiwarka;}
  58. else
  59. {
  60. $nowe = array_unique(array_merge ($tab));
  61. $n1 = count($nowe);
  62. for ($i=0;$i<$n1; $i++) {
  63.  
  64. echo ''.$nowe[$i].' ';
  65.  
  66. }
  67. }
  68. }
  69.  
  70. ?>
  71.  
  72.  
  73. </body>
  74. </html>


jednak nadal nie mogę sobie poradzić z drugą częścią mojego pytania.
Jeśli miałby ktoś pomysł jak sprawić by przedstawiony kod był czytelniejszy to proszę o poprawienie.
b4rt3kk
Powielone wpisy w tablicy usuniesz funkcją array_unique($array), która zwróci nową tablicę z unikatowymi wartościami.

Natomiast funkcję:

  1. if(stripos(str2url($key), str2url($gie[$fi])))


proponowałbym zastąpić preg_match:

  1. $global_matches = array();
  2.  
  3. foreach($dane as $key){
  4.  
  5. $subject = trim($key);
  6. $search = explode(' ', $wyszukiwarka);
  7.  
  8. foreach ($search as $value) {
  9. $pattern = '/\|[^|]*'.$value.'[^|]*\|/';
  10. preg_match ($pattern , $subject, $matches);
  11. foreach ($matches as $key1 => $value1) $matches[$key1] = str_replace('|', '', $matches[$key1]);
  12. $global_matches[] = $matches;
  13. }
  14. }


i w tablicy $global_matches masz wszystkie zgodne wyniki.
wujekk13
@b4rt3kk wybacz, że ponownie zawracam głowę, ale próbuję od dwóch dni ten kod, który mi podałeś zintegrować ze swoimi wypocinami, jednak każda kombinacja kończy się jakimś błędem lub niewyświetleniem wyniku. Mógłbym Cię prosić o jakąś podpowiedź, jak to podmienić? Mam jeszcze pytanie, czy dobrze rozumuję, że powinienem tam dorzucić jeszcze funkcję if, tak by w razie braku dopasowania wyświetlało się, że nie zaleziono poszukiwanej frazy?
b4rt3kk
  1. $bl=false;
  2.  
  3. if(isset($_POST['wyszukiwarka']) && $_POST['wyszukiwarka']!=''){
  4.  
  5. $wyszukiwarka = $_POST['wyszukiwarka'];
  6. $dane = file('dane.txt');
  7. $global_matches = array();
  8.  
  9. foreach($dane as $key){
  10.  
  11. $subject = trim($key);
  12. $search = explode(' ', $wyszukiwarka);
  13.  
  14. foreach ($search as $value) {
  15. $pattern = '/\|[^|]*'.$value.'[^|]*\|/';
  16. preg_match ($pattern , $subject, $matches);
  17. foreach ($matches as $key1 => $value1) $matches[$key1] = str_replace('|', '', $matches[$key1]);
  18. $global_matches[] = $matches;
  19. }
  20. }
  21.  
  22. // tutaj wydrukowanie wyników (roboczo print_r)
  23.  
  24. print_r($global_matches); // jeszcze należałoby się pozbyć powtórzeń, ale to już wiesz jak
  25.  
  26. // natomiast jeśli tablica pusta to wtedy wyświetlasz, że nie znaleziono wyników
  27.  
  28. }
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.