Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Wyszukiwarka z kilkoma polami
Forum PHP.pl > Forum > Przedszkole
chico2
Witam,
Chcę do mojego katalogu bibliotecznego dorobić wyszukiwanie po kilku polach tekstowych przy czym każde wypełnione pole zawęża zakres poszukiwań. Przy pomocy forum udało mi się skleić coś takiego:

  1. <?php
  2. require ('db.php');
  3.  
  4. $wh = array(); //inicjalizujemy tablicę z warunkami
  5. if (!empty($_POST['tytul'])) //jeśli podano tytul
  6. $wh[] = "tytul = '$_POST[tytul]' ";
  7.  
  8. if (!empty($_POST['autor'])) //jeśli podano autora
  9. $wh[] = "autor = '$_POST[autor]' ";
  10.  
  11. if (!empty($_POST['rok'])) //jeśli podano rok wydania
  12. $wh[] = "rok = $_POST[rok]";
  13.  
  14. if (!empty($_POST['haslo'])) //jeśli podano haslo_przedmiotowe
  15. $wh[] = "haslo = $_POST[haslo]";
  16.  
  17. if (!empty($wh))
  18. $where = 'where '.implode(' and ', $wh);
  19. else
  20. $where = '';
  21.  
  22. //a teraz tworzymy nasze glowne zapytanie i łączymy je z naszymi warunkami
  23. $sql = 'select * from ksiazki '.$where;
  24.  
  25.  
  26. $wynik = mysql_query($sql);
  27.  
  28. echo "<table>";
  29. echo "<tr>";
  30. echo "<td> tytul </td>";
  31. echo "<td> autor </td>";
  32. echo "<td> rok </td>";
  33. echo "<td> haslo </td>";
  34. echo "<tr>";
  35. while ($row = mysql_fetch_array ($wynik) )
  36. {
  37. echo "<tr>";
  38. echo "<td>{$row['tytul']}</td>";
  39. echo "<td>{$row['autor']}</td>";
  40. echo "<td>{$row['rok']}</td>";
  41. echo "<td>{$row['haslo']}</td>";
  42. echo "<tr>";
  43. }
  44. echo "</table>";
  45.  
  46. ?>

Formularz to obsługujący jest taki:
  1. <form action="szukaj.php" method="POST">
  2.  
  3. Tytuł<br><input type="text" name="tytul" maxlenght="25" size="25"><br>
  4. Autor<br> <input type="text" name="autor" maxlenght="25" size="25"><br>
  5. Rok wydania<br><input type="text" name="rok" maxlenght="4" size="25"><br>
  6. Hasło przedmiotowe 1<br><input type="text" name="haslo" maxlenght="25" size="25"><br>
  7. Hasło przedmiotowe 2<br> <input type="text" name="haslo2" maxlenght="25" size="25"><br>
  8. <input type="submit" id="przycisk" value="Szukaj" name="send"><br>
  9. </form>


W bazie istnieje tabela 'ksiazki' z w/w kolumnami. Niestety zapytanie nie wyświetla żadnych znalezionych pozycji.. Ktoś pomoże?

Działa to nieco inaczej od zamierzonego celu. Tzn chciałbym aby po wpisaniu jednej litery w np tytule i rok wydania wyświetliło wszystkie pasujące rekordy.. Jak by dodać gdzieś LIKE % ?
darko
  1. $wh[] = "tytul = '$_POST[tytul]' ";

zamień na
  1. $wh[] = "tytul = '".$_POST["tytul"]."' ";


i dalsze pola w warunkach (autor, rok i hasło)

Co do like, to jaki problem dodać do warunku where: tytul like '$_POST["tytul"]%' ?
chico2
Kombinuje trochę przy tym i mam problem bo nie wiem gdzie do zapytania dołożyć tytul like '$_POST["tytul"]%' Podejrzewam, że coś źle robię z apostrofami i cudzysłowami.. Za każdym razem parse error ; /

A przy okazji zapytam jeszcze, jak rozwiązać sprawę rezerwacji książki po wyszukaniu? W tabeli ksiazki dołożyć jeszcze jedną kolumnę 'ilosc', która wskazywała by na to ile książek jest i za każdym kliknięciem przez usera "rezerwuj" 'ilosc' była by zmniejszana o 1. Jak się za to zabrać? Coś na zasadzie koszyka?
darko
1. To pokaż co wymodziłeś
2. rezerwację można np. tak: onclick(na rezerwuj) - ajax ----> leci request do skryptu w php, przekazuje dwie zmienne, id produktu i ilość, o jaką należy pomniejszyć stan magazynowy. Analogicznie w przypadku rezygnacji z rezerwacji.
chico2
1.
  1. <?php
  2. require ('db.php');
  3.  
  4. $wh = array(); //inicjalizujemy tablicę z warunkami
  5. if (!empty($_POST['tytul'])) //jeśli podano tytul
  6.  
  7. $wh[] = "tytul = '".$_POST["tytul"]."' ";
  8. if (!empty($_POST['autor'])) //jeśli podano autora
  9.  
  10. $wh[] = "autor = '".$_POST["autor"]."' ";
  11. if (!empty($_POST['rok'])) //jeśli podano rok wydania
  12.  
  13. $wh[] = "rok = '".$_POST["rok"]."' ";
  14. if (!empty($_POST['haslo'])) //jeśli podano haslo_przedmiotowe
  15.  
  16. $wh[] = "haslo = '".$_POST["haslo"]."' ";
  17.  
  18. if (!empty($wh))
  19. $where = 'where tytul like '$_POST["tytul"]%''.implode(' and ', $wh);
  20. else
  21. $where = '';
  22.  
  23. //a teraz tworzymy nasze glowne zapytanie i łączymy je z naszymi warunkami
  24. $sql = 'select * from ksiazki '.$where;
  25.  
  26.  
  27. $wynik = mysql_query($sql);
  28.  
  29. echo "<table cellpadding=\"4\" border=2>";
  30. echo "<tr>";
  31. echo "<td> tytul </td>";
  32. echo "<td> autor </td>";
  33. echo "<td> rok </td>";
  34. echo "<td> haslo </td>";
  35. echo "<tr>";
  36. while ($row = mysql_fetch_array ($wynik) )
  37. {
  38. echo "<tr>";
  39. echo "<td>{$row['tytul']}</td>";
  40. echo "<td>{$row['autor']}</td>";
  41. echo "<td>{$row['rok']}</td>";
  42. echo "<td>{$row['haslo']}</td>";
  43. echo "<tr>";
  44. }
  45. echo "</table>";
  46.  
  47.  
  48. ?>

Błąd: Parse error: parse error in C:\Program Files\EasyPHP5.3.0\www\test\szukaj.php on line 20
Zmiana
  1. if (!empty($wh))
  2. $where = 'where tytul like $_POST["tytul"]%'.implode(' and ', $wh);


Daje błąd Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in C:\Program Files\EasyPHP5.3.0\www\test\szukaj.php on line 37

2. A czy w tym sposobie będzie dało się zrobić coś takiego, że rezerwacja wygasa po np 3 dniach? Czuję, że to będzie najtrudniejsza część pracy..
darko
  1. $where = 'where tytul like $_POST["tytul"]%'.implode(' and ', $wh);

zamień na
  1. $where = "where tytul like '".$_POST["tytul"]."%' ".implode(' and ', $wh);


Cytat
2. A czy w tym sposobie będzie dało się zrobić coś takiego, że rezerwacja wygasa po np 3 dniach? Czuję, że to będzie najtrudniejsza część pracy..

W tym nie, ale np. cron raz dzienie + odpowiedni skrypt (wyciągnięcie wszystkich rezerwacji, których data_dodania >= 3 dni i usunięcie ich + przywrócenie odpowiednich stanów magazynowych) = tak. Są jeszcze inne sposoby, może ktoś inny coś lepszego doradzi?
chico2
Niestety jest jakiś problem z tablicą
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in C:\Program Files\EasyPHP5.3.0\www\test\szukaj.php on line 39

W manualu przeczytałem, że dotyczy to źle użytej funkcji mysql_fetch_array(). Dodawałem return $wynik; oraz mysql_free_result($wynik); ale nie było żadnego efektu.

Co do drugiej części skryptu czyli crona to będzie problem gdyż póki co cała aplikacja będzie odpalona na easyphp w Windowsie więc cron odpada. A jeśli by zrobić bez ograniczenia czasowego to będzie łatwiej to zaimplementować?
darko
wyprintuj zmienną $where doklej do $sql i zobacz jak wygląda całe zapytanie
chico2
  1. <?php
  2. require ('db.php');
  3.  
  4. $wh = array(); //inicjalizujemy tablicę z warunkami
  5. if (!empty($_POST['tytul'])) //jeśli podano tytul
  6.  
  7. $wh[] = "tytul = '".$_POST["tytul"]."' ";
  8. if (!empty($_POST['autor'])) //jeśli podano autora
  9.  
  10. $wh[] = "autor = '".$_POST["autor"]."' ";
  11. if (!empty($_POST['rok'])) //jeśli podano rok wydania
  12.  
  13. $wh[] = "rok = '".$_POST["rok"]."' ";
  14. if (!empty($_POST['haslo'])) //jeśli podano haslo_przedmiotowe
  15.  
  16. $wh[] = "haslo = '".$_POST["haslo"]."' ";
  17.  
  18. if (!empty($wh))
  19. //$where = 'where '.implode(' and ', $wh);
  20. //$where = "where tytul like '".$_POST["tytul"]."%' ".implode(' and ', $wh);
  21. $where = "where tytul like '".$_POST["tytul"]."%' ".implode(' and ', $wh);
  22. else
  23. $where = '';
  24.  
  25.  
  26. //a teraz tworzymy nasze glowne zapytanie i łączymy je z naszymi warunkami
  27. print_r($where);
  28. $sql = 'select * from ksiazki '.$where;
  29. print_r($sql);
  30.  
  31. $wynik = mysql_query($sql);
  32.  
  33. echo "<table cellpadding=\"4\" border=2>";
  34. echo "<tr>";
  35. echo "<td> tytul </td>";
  36. echo "<td> autor </td>";
  37. echo "<td> rok </td>";
  38. echo "<td> haslo </td>";
  39. echo "<tr>";
  40. while ($row = mysql_fetch_array ($wynik))
  41. {
  42. echo "<tr>";
  43. echo "<td>{$row['tytul']}</td>";
  44. echo "<td>{$row['autor']}</td>";
  45. echo "<td>{$row['rok']}</td>";
  46. echo "<td>{$row['haslo']}</td>";
  47. echo "<tr>";
  48. //return $wynik;
  49. }
  50. //mysql_free_result($wynik);
  51.  
  52. echo "</table>";
  53.  
  54.  
  55.  
  56. ?>

To wypluł print: where tytul like 'a%' tytul = 'a' select * from ksiazki where tytul like 'a%' tytul = 'a'
darko
No to teraz przeanalizuj swoje zapytanie, jak już będziesz wiedział, co jest źle, to się odezwij.
chico2
Zmodyfikowałem zmienną $where w taki sposób:
  1. $where = "where tytul like '%".$_POST["tytul"]."%' ";//.implode(' and ', $wh);


I zadziałało smile.gif Teraz tylko zastanawiam się jak zrobić, żeby uzupełnienie następnego pola dawało zawężone poszukiwania. Takie coś:
  1. $where = "where tytul like '%".$_POST["tytul"]."%' and '%".$_POST["rok"]."%' ";
wyświetla pusty rezultat. print_r wyświetla: where tytul like '%php%' and '%199%'

Czuję, że coś znów z apostrofami..
darko
where tytul like '%php%' and tytul like '%199%' ?
chico2
A dokładnie powinno być:
  1. $where = "where tytul like '%".$_POST["tytul"]."%' and rok like '%".$_POST["rok"]."%'";
właśnie do tego doszedłem. Głupi błąd.
Zapytanie jest takie:
  1. $where = "where tytul like '%".$_POST["tytul"]."%' and autor like '%".$_POST["autor"]."%'
  2. and rok like '%".$_POST["rok"]."%' and haslo like '%".$_POST["haslo"]."%' ";


Tylko teraz jak rozwiązać rezerwację książki jeśli jest dostępna. Bardzo dziękuję za powyższą pomoc. Przydała się : )
darko
Cytat(chico2 @ 21.12.2009, 20:02:41 ) *
Tylko teraz jak rozwiązać rezerwację książki jeśli jest dostępna.


Jeśli chodzi o handel, to utwórz tabelę np. magazyn, w której będziesz przechowywał następujące dane:

magazyn
id_magazyn int PK
id_ksiazka int FK
ilosc int
status tinyint(1)
data_dodania datetime
login_dodania varchar(55)
data_modyfikacji datetime
login_modyfikacji varchar(55)

oraz tabelę

zamówienie
id_zamowienie int PK
id_ksiazka int FK
id_user int FK
ilosc int
status tinyint(1)
data_dodania datetime
login_dodania varchar(55)
data_modyfikacji datetime
login_modyfikacji varchar(55)

No i pomyśl jak to teraz połączyć.

Jeśli masz na myśli rezerwację jak w bibliotece to można coś w tym stylu:

rezerwacje
id_rezerwacja int PK
id_ksiazka int FK
do_kiedy datetime
status tinyint(1)
data_dodania datetime
login_dodania varchar(55)
data_modyfikacji datetime
login_modyfikacji varchar(55)
Genek
Z góry przepraszam za odkopywanie starego tematu, ale robię podobny projekt i też chcę na podobnej zasadzie rozwiązać mechanizm wyszukiwania, tylko bazę danych mam rozwiązaną w inny sposób. Mam osobną tabelę na książki, osobną tabelę na autorów, tabelę łączącą(relacja wiele do wielu) itd.

Deklaracja tabel:

  1.  
  2. CREATE TABLE IF NOT EXISTS `ksiazki` (
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `tytul` varchar(200) COLLATE utf8_polish_ci NOT NULL,
  5. `wydanie` int(11) DEFAULT NULL,
  6. `miejsce_wydania` varchar(20) COLLATE utf8_polish_ci NOT NULL,
  7. `wydawnictwo` varchar(20) COLLATE utf8_polish_ci NOT NULL,
  8. `rok_wydania` int(11) NOT NULL,
  9. `haslo_przedmiotowe` varchar(20) COLLATE utf8_polish_ci NOT NULL,
  10. `ISBN` varchar(17) COLLATE utf8_polish_ci NOT NULL,
  11. `komentarz` varchar(500) COLLATE utf8_polish_ci NOT NULL,
  12. PRIMARY KEY (`id`),
  13. UNIQUE KEY `ISBN` (`ISBN`)
  14. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=12 ;
  15.  
  16. CREATE TABLE IF NOT EXISTS `autorzy` (
  17. `id` int(11) NOT NULL AUTO_INCREMENT,
  18. `imie` varchar(20) COLLATE utf8_polish_ci NOT NULL,
  19. `nazwisko` varchar(35) COLLATE utf8_polish_ci NOT NULL,
  20. PRIMARY KEY (`id`)
  21. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=23 ;
  22.  
  23. CREATE TABLE IF NOT EXISTS `autorzy_to_ksiazki` (
  24. `autor_id` int(11) NOT NULL,
  25. `ksiazka_id` int(11) NOT NULL,
  26. KEY `autor_id` (`autor_id`,`ksiazka_id`),
  27. KEY `ksiazka_id` (`ksiazka_id`)
  28. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;
  29.  
  30. CREATE TABLE IF NOT EXISTS `hasla_przedmiotowe` (
  31. `id` int(11) NOT NULL AUTO_INCREMENT,
  32. `haslo` varchar(20) COLLATE utf8_polish_ci NOT NULL,
  33. PRIMARY KEY (`id`)
  34. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=3 ;
  35.  
  36. CREATE TABLE IF NOT EXISTS `slowa_kluczowe` (
  37. `id` int(11) NOT NULL AUTO_INCREMENT,
  38. `slowo_klucz` varchar(20) COLLATE utf8_polish_ci NOT NULL,
  39. PRIMARY KEY (`id`),
  40. UNIQUE KEY `slowo_klucz` (`slowo_klucz`)
  41. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=2 ;
  42.  
  43. CREATE TABLE IF NOT EXISTS `slowa_to_ksiazki` (
  44. `slowo_id` int(11) NOT NULL,
  45. `ksiazka_id` int(11) NOT NULL
  46. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;
  47.  
  48. ALTER TABLE `autorzy_to_ksiazki`
  49. ADD CONSTRAINT `autorzy_to_ksiazki_ibfk_2` FOREIGN KEY (`ksiazka_id`) REFERENCES `ksiazki` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  50. ADD CONSTRAINT `autorzy_to_ksiazki_ibfk_3` FOREIGN KEY (`autor_id`) REFERENCES `autorzy` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;



Chciałbym wyszukiwać to w ten sposób, że każde dodatkowe wypełnione pole w formularzu dopełnia zapytanie, a pola będą takie: tytul, imie nazwisko, haslo_przedmiotowe, slowo_kluczowe, rok_wydania.

I zapytanie, które używam dotychczas wygląda tak:

  1. $where = "where k.tytul like '%".$_POST["tytul"]."%' and a.nazwisko like '%".$_POST["autor"]."%'
  2. and k.rok_wydania like '%".$_POST["rok_wydania"]."%' and k.haslo_przedmiotowe like '%".$_POST["haslo_przedmiotowe"]."%' ";
  3. $sql = 'select * from bibliografia.ksiazki as k, bibliografia.autorzy as a '.$where;


Ale to jest bez sensu, bo nie zwraca mi tego co bym chciał, a zwraca mi wszystko co jest w bibliografia.autorzy.

I moje pytanie jest takie, czy w ogóle da się to zrobić jednym zapytaniem, biorąc pod uwagę, że jedna książka może mieć wiele autorów i wiele słów kluczowych przypisanych do niej, a jeżeli tak, to jak mniej więcej schematycznie miało by wyglądać to zapytanie, bo wiem, że będzie dosyć złożone i sam nie wiem jak je wykombinować.
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.