Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL]Łączenie dwóch tabel
Forum PHP.pl > Forum > Przedszkole
JamalBIG
Witam

Mam problem z połączeniem dwóch tabel których budowa przedstawia się następująco:

-- wpisy
id | user_id | tekst |
-----------------------
1 | 2 | xxxx |
2 | 22 | yyyy |

-- users

user_id | znajomy_user_id |
-----------------------
1 | 22 |
2 | 2 |

Chcę wyświetlić dane z tabeli wpisy gdzie user_id = np 2 oraz dane z tabeli wpisy gdzie user_id = znajomy_user_id (pisząc 'słownie' aby wyświetlone zostały dane z tabeli wpisy określonego użytkownika oraz jego znajomych... Stworzyłem poniższą komendę ale nie wyświetla tego czego chce....
  1. SELECT wpisy.* FROM users, wpisy WHERE users.user_id=2 AND wpisy.user_id=users.znajomy_user_id
tehaha
wydaję mi się, że coś pomieszałeś z tą logiką
Cytat
aby wyświetlone zostały dane z tabeli wpisy określonego użytkownika oraz jego znajomych


no bo jeżeli pobierasz rekordy gdzie user_id = znajomy_user_id = 2 to wychodzi na to, że użytkownik jest sam swoim znajomym, czyli coś nie tak, chyba chciałeś pobrać wszystkie wpisy gdzie users.user_id = 2 oraz dla wszystkich ID users.znajomy_user_id przypisanych do users.user_id = 2.

najprościej będzie zrobić to w 2 zapytaniach :
1. pobrać wszystkie ID znajomych oraz ID użytkownika
2. pobrać wszystkie wpisy dla nich

możesz też pokombinować z podzapytaniami
JamalBIG
Twoja propozycja jest interesująca ale w jaki sposób wykonać te dwa zapytania? (jak byś to kruciutko zobrazował to był bym wdzięczny bo trochę nie chwytam...)
tehaha
ciężko podać precyzyjną odpowiedź bo nie wiem co dokładnie chcesz uzyskać, jak wyświetlić itd, bo sytuacje mogą być różne

ale założę, że jesteś na podstronie użytkownika, jego ID pobieramy z url, i chcemy pobrać jego wpisy oraz wpisy użytkownika

UWAGA, to co Ci podałem to nie jest działający przykład, tylko takie mniej więcej zobrazowanie mechanizmu, musisz to przeanalizować i napisać skrypt na podstawie tego, pamiętaj też, że jak odbierasz zmienne z $_GET, $_POST itd, to zanim wstawisz do zapytania przepuszczasz przez mysql_real_escape_string();

  1. <?php
  2.  
  3. $user_id = $_GET['user_id'];
  4.  
  5. //pobieramy znajomych
  6. $friend_ids = array(); //do tej tablicy wrzucimy ID znajomych
  7. $friend_ids[] = $user_id; // do tablicy z ID znajomych dokładamy ID użytkownika głownego bo jego wpisy też chcemy dostać
  8. $sql = "SELECT znajomy_user_id FROM users WHERE user_id = '{$user_id}'";
  9.  
  10. while($row = mysql_fetch_assoc())
  11. {
  12. $friend_ids[] = $row['znajomy_user_id'];
  13. }
  14.  
  15. if(count($friend_ids))
  16. {
  17. $query_ids = implode(" , ", $friend_ids); // składamy wszystkie numery ID do postaci w, ktorej łatwo wstawimy do zapytania WHERE user_id IN(1,2,3,4)
  18.  
  19. // zakładam ze w tabeli user jest jeszcze pole user_name zawierajace nazwe uzytkownika, uzejemy tutja LEFT JOIN aby do kazdego wpisu pobrac od razu nazwe uzytkownika
  20.  
  21. $sql = "SELECT a.id, a.user_id, a.tekst, b.user_name FROM wpisy a LEFT JOIN users b ON a.user_id = b.user_id WHERE a.user_id IN($query_ids)";
  22. while($row = mysql_fetch_assoc())
  23. {
  24. //tutaj odbierasz wpisy
  25. }
  26. }
  27.  
  28.  
  29. ?>
modern-web
Dodam jeszcze, że dane przekazywane metodą $_GET lub $_POST powinno się przefiltrować (najlepiej określić max. długość (za pomocą PHP - nie HTML), wykluczyć znaki, które nie powinny się tam znaleźć itp... wszystko zależy od tego jaki efekt chcesz uzyskać).
Funkcja mysql_real_escape_string czasem nie wystarcza (jeśli chcesz mieć pewność, że skrypt jest bezpieczny)...

Pozdrawiam.
tehaha
Cytat(modern-web @ 22.12.2010, 13:25:06 ) *
Funkcja mysql_real_escape_string czasem nie wystarcza (jeśli chcesz mieć pewność, że skrypt jest bezpieczny)...


a mógłbyś podać przykład? albo wskazać źródło tej informacji?
modern-web
mysql_real_escape_string zaslashuje wszystkie znaki ' więc nie będzie można wprowadzić łańcuchów bezpośrednio do zapytania.
Za to można bez przeszkód wstawiać liczby i ciągi nie zawierające '.
np.
Dla zapytania typu:
  1. SELECT * FROM serwis.uzytkownicy WHERE id=$id

Można to obejść (przy zabezpieczeniach) takim sposobem:
w polu id:
  1. 0 OR 1=1

  1. x LIMIT 0 UNION SELECT 1, 2, ..., n FROM information_schema.TABLES

Można używać funkcji concat i char do wprowadzania ciągów do rekordów

Przed XSS także nie chroni w 100%, ponieważ np.
  1. <script>alert(document.cookie)</script>


Podsumowując: W przypadku PHP jeżeli wiemy, że argument to liczba to stosujemy intval() jeżeli nie to addslashes. Jeżeli mamy coś wyrafinowanego to stosujemy ereg i wyrażenia regularne.
Wniosek: FILTRUJEMY DANE.
tehaha
z Xss się zgodzę, ale zagrożenie przed Xss nie grozi w przypadku, który tu omawiamy, a wiadomo, że w przypadku treści otrzymywanych od użytkownika, dane trzeba odpowiednio obrobić przed wprowadzaniem do bazy, obcinamy cały kod html zostawiamy tylko bbcode, tutaj wystarczy proste sprawdzenie np. is_int() albo $user_id = (int) $_GET['id'];.

Co do tego injection, to testowałeś to? czy podałeś taki teoretyczny przykład? bo zauważ, że zapytanie wygląda tak ( z apostrofami)

  1. SELECT * FROM serwis.uzytkownicy WHERE id='$id'


więc samo wstawienie 0 OR 1=1, spowoduje taki wynik:

  1. SELECT * FROM serwis.uzytkownicy WHERE id='0 OR 1=1'


więc nic się nie stanie

//ale oczywiście z myślą przewodnią masz racje, nigdy nie można ufać użytkownikowi i trzeba każdą zmienną przefiltrować
JamalBIG
wszystko ładnie wyświetla ale nieraz musi być jakieś ale winksmiley.jpg zapytanie do bazy dubluje mi wpis głównego użytkownika tyle razy ile ma znajomych (nie wiem jak takie cudo się zrobiło...) czyli mam np. id 1 z bazy wpisy wyświetlony 3x jeżeli użytkownik ma 3 znajomych...
modern-web
Są i tacy, którzy o ' ' zapominają, a ponieważ nie wyświetla się to jako błąd uważają, że wszystko jest ok.
Tak jak powiedziałem; jeśli nie byłoby ' ' to SQL Injection byłby jak najbardziej możliwy do wykonania... smile.gif

Fakt, nie tyczy się to omawianego przykładu ale warto wspomnieć ^^

Pozdrawiam. winksmiley.jpg
tehaha
Cytat(JamalBIG @ 22.12.2010, 13:52:09 ) *
zapytanie do bazy dubluje mi wpis głównego użytkownika tyle razy ile ma znajomych


za pierwszą petlą while() wstaw
  1. $friend_ids = array_unique($friend_ids);
to usunie zdublowane wartości z tablicy

Cytat
Są i tacy, którzy o ' ' zapominają, a ponieważ nie wyświetla się to jako błąd uważają, że wszystko jest ok.
no to prawda, są i tacy, którzy w ogóle nie wiedzą, że coś trzeba filtrować, no ale to niestety efekt tego, że w wielu kursach nie pisze się o bezpieczeństwie, a nawet w książkach dla początkujących nie wiele jest o zabezpieczeniach albo i wcale nie ma
JamalBIG
tablica była w porządku, zapytanie do bazy danych skróciłem do:
  1. SELECT * FROM wpisy WHERE user_id IN($query_ids)

Ale mimo to wielkie dzięki tehaha - mam kolejne polecenie do mojego słownika mysql - IN winksmiley.jpg
modern-web
Cytat
no to prawda, są i tacy, którzy w ogóle nie wiedzą, że coś trzeba filtrować, no ale to niestety efekt tego, że w wielu kursach nie pisze się o bezpieczeństwie, a nawet w książkach dla początkujących nie wiele jest o zabezpieczeniach albo i wcale nie ma

Trochę beznadziejnie, ponieważ taki początkujący od pierwszej strony uczy się złych (najczęściej przestarzałych) nawyków. Tak właściwie, to książki są dobre ale tylko pod tym względem, że łatwo można odszukać definicję jakiejś funkcji. Mówię jakiejś, ponieważ często początkujący nie pamiętają ich nazw przez co znalezienie w manualu przysparza nie lada problemów biggrin.gif Książka to takie `zgromadzenie` tych instrukcji/funkcji, które zawiera definicję, prototyp i krótki, wybrakowany przykład haha.gif

Można brać z nich przykład na samym początku, lecz nie korzystać z zamieszczonych tam gotowców smile.gif
Wszystko wystarczy zrozumieć, a w razie jakichkolwiek wątpliwości można poprosić kolegów z forum.php.pl o niewielką pomoc ^^

EDIT:
@JamalBIG Może Cię to zaciekawi winksmiley.jpg http://www.eioba.pl/a2190/podstawy_tworzen...apyta_sql_mysql
JamalBIG
dzięki @modern-web - na pewno się przyda, choćby dla kilku mniej mi znanych poleceń winksmiley.jpg
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.