Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Sprawdzenie zawartości.
Forum PHP.pl > Forum > Przedszkole
castagir
Witam

Potrzebuję pomocy w odczytaniu wyniku zapytania. Napisałem dwie strony z zawartością logiczną. Jedna to wyświetlenie formularza, a druga wykonuje test z danymi wpisanymi w formularzu, a nastepnie zwraca wynik.
Funkcja z którą mam problem to ta:
  1. function sprawdzenie_nazwy($nazwa) {
  2. global $polaczenie_bd;
  3. global $przedrostek;
  4. $pytanie = "SELECT nazwa, haslo FROM ".$przedrostek."uzytkownicy LIKE '".$nazwa."'";
  5. $wynik = mysqli_query($polaczenie_bd, $pytanie);
  6. if (mysql_num_rows($wynik) > 0) {
  7. $wynik = mysqli_fetch_assoc($wynik); }
  8. elseif (mysql_num_rows($wynik) = 0) { // błąd odnosi się do tego wersu.
  9. return 'Użytkownik o takiej nazwnie nie istnieje'; }
  10. else {
  11. return 'Nie udało się połączyć z bazą danych.<br />Spróbuj jeszcze raz lub zgłoś problem do pomocy technicznej.'; }
  12. if ($wynik['nazwa'] === $nazwa) {
  13. return 'dobrze'; }
  14. }


Dodatkowo wyświetla taki błąd:
  1. Fatal error: Can't use function return value in write context in /var/www/html/inicjacja.php on line 157


Ową funkcję wywołuje ten fragment kodu:
  1. if ($spr_nazwa === 'dobrze') {
  2. echo $spr_nazwa = sprawdzenie_nazwy($nazwa); }
  3. if ($spr_haslo === 'dobrze') {
  4. $spr_haslo = sprawdzenie_hasla($spr_nazwa, $haslo); }

Nie wiem czy w czymś pomoże, bo ten kod dopiero wtedy jest interpetowany, gdy formularz zostanie wyświetlony, wypełniony i zaakceptowany.

Z góry dziękuję za pomoc.
Pozdrawiam!
Rysh
Hasła w PHP się nie sprawdza. Wysyłasz zapytanie czy istnieje użytkownik o takim loginie i haśle, jeśli tak to pobierasz jego ID i umieszczasz w sesji.
castagir
Czy tak powinna wyglądać prawidłowa funkcja?
  1. function sprawdzenie_nazwy($nazwa, $haslo) {
  2. global $polaczenie_bd;
  3. global $przedrostek;
  4. $pytanie = "SELECT * FROM ".$przedrostek."uzytkownicy LIKE '".$nazwa."', '".$haslo."'";
  5. $wynik = mysqli_query($polaczenie_bd, $pytanie);
  6. if (mysql_num_rows($wynik) > 0) {
  7. $wynik = mysqli_fetch_assoc($wynik); }
  8. elseif (mysql_num_rows($wynik) = 0) {
  9. return 'Użytkownik o takiej nazwnie nie istnieje'; }
  10. else {
  11. return 'Nie udało się połączyć z bazą danych.<br />Spróbuj jeszcze raz lub zgłoś problem do pomocy technicznej.'; }
  12. if ($wynik['nazwa'] === $nazwa) {
  13. return 'dobrze'; }
  14. }



Nie wiem czy to jest prawidłowo czy nie, ale chodzi mi teraz przede wszystkim o roziwazanie problemu, ktory wczesniej opisalem.
Turson
Ale żadne LIKE, a zwykłe równa się.
elseif (mysql_num_rows($wynik) = 0) {
tutaj masz = a operator równości w PHP wygląda inaczej

Poza tym binduj dane bo teraz masz niebezpieczne zapytanie
castagir
W jaki sposob mam zbindowac dane? Poza tym nawet jak wprowadzilem zmiany to i tak wyswietla mi takie bledy:

  1. Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in /var/www/html/inicjacja.php on line 155
  2.  
  3. Warning: mysql_num_rows() expects parameter 1 to be resource, null given in /var/www/html/inicjacja.php on line 156

fastlone
Cytat(castagir @ 13.12.2014, 17:17:36 ) *
W jaki sposob mam zbindowac dane? Poza tym nawet jak wprowadzilem zmiany to i tak wyswietla mi takie bledy:

  1. Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in /var/www/html/inicjacja.php on line 155
  2.  
  3. Warning: mysql_num_rows() expects parameter 1 to be resource, null given in /var/www/html/inicjacja.php on line 156


  1. elseif (mysql_num_rows($wynik) = 0)

zamień na
  1. elseif (mysql_num_rows($wynik) == 0)
Turson
Bindować możesz używając PDO
Rysh
Cytat(castagir @ 13.12.2014, 16:11:56 ) *
Czy tak powinna wyglądać prawidłowa funkcja?
  1. function sprawdzenie_nazwy($nazwa, $haslo) {
  2. global $polaczenie_bd;
  3. global $przedrostek;
  4. $pytanie = "SELECT * FROM ".$przedrostek."uzytkownicy LIKE '".$nazwa."', '".$haslo."'";
  5. $wynik = mysqli_query($polaczenie_bd, $pytanie);
  6. if (mysql_num_rows($wynik) > 0) {
  7. $wynik = mysqli_fetch_assoc($wynik); }
  8. elseif (mysql_num_rows($wynik) = 0) {
  9. return 'Użytkownik o takiej nazwnie nie istnieje'; }
  10. else {
  11. return 'Nie udało się połączyć z bazą danych.<br />Spróbuj jeszcze raz lub zgłoś problem do pomocy technicznej.'; }
  12. if ($wynik['nazwa'] === $nazwa) {
  13. return 'dobrze'; }
  14. }



Nie wiem czy to jest prawidłowo czy nie, ale chodzi mi teraz przede wszystkim o roziwazanie problemu, ktory wczesniej opisalem.

Nie, tak nie powinno wyglądać zapytanie. Jedyne o co pytasz to czy istnieje użytkownik o podanym loginie i haśle, jeśli tak to pobierasz jego ID - jeśli nie to nie podajesz żadnych danych (np. dla osób które chcą się włamać), tylko dajesz komunikat że błąd.
Kod
SELECT id_user FROM przedrostek.uzytkownicy WHERE login='zmienna' AND haslo='hash_hasla' LIMIT 1

Powinno załatwić sprawę.
castagir
Dzięki Falstone i Rysh biggrin.gif Udało się.

Co do PDO to duzo troche jest o tym. Możesz powiedzieć jak to robić? Byłbym również bardzo wdzieczny gdybyś pokazał mi jakąś instrukcje w jezyku polskim, bo to co jest na php.net to magia. Nie wiadomo za co się złapać i co robić.
Turson
Łączysz się z bazą danych
  1. $db = new PDO('mysql:host=localhost;dbname=baza danych', 'uzytkownik', 'haslo',
  2. array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'")) or die('Nie można się połączyć z bazą danych.');

przygotowujesz zapytanie
  1. $stmt = $db->prepare("SELECT id_user FROM przedrostek.uzytkownicy WHERE login=:login AND haslo=:haslo LIMIT 1");

bindujesz dane w zapytaniu: :login i :haslo
  1. $stmt->bindValue(':login', $login, PDO::PARAM_STR);
  2. $stmt->bindValue(':haslo', $haslo, PDO::PARAM_STR);

wykonujesz zapytanie
  1. $stmt->execute();

pobierasz dane
  1. $row = $stmt->fetch(PDO:FETCH_ASSOC);

tym sposobem w $row masz pobraną kolumnę. Sprawdzisz to przez
  1. var_dump($row);
castagir
Takie cos mi wywala.
  1. Warning: PDO::__construct() expects parameter 2 to be string, array given in /var/www/html/inicjacja.php on line 10
  2. Nie można połączyć się z bazą danych.

Natomiast, gdy zrezygnuję z drugiej części i pzostawię tylko:
  1. $pdo_bd = new PDO('mysql:host='.NAZWA_SERWERA_BD.';dbname='.NAZWA_BD.', '.NAZWA_UZYT_BD.', '.HASLO_UZYT_BD.'');

Wywala mi błąd:
  1. Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[28000] [1045] Access denied for user 'www-data'@'localhost' (using password: NO)' in /var/www/html/inicjacja.php:9 Stack trace: #0 /var/www/html/inicjacja.php(9): PDO->__construct('mysql:host=loca...') #1 /var/www/html/loguj.php(9): require('/var/www/html/i...') #2 {main} thrown in /var/www/html/inicjacja.php on line 9


Ten cały PDO jest do niczego. Nie potrafi odczytać stałych, w porównaniu do zwykłej procedury mysqli_connect.
Manual jest tak nieczytelny, ze szkoda słów. Jest jakaś książka albo instrukcja w języku polskim?
Rysh
Nie dawaj tam stałych tylko wpisz dane do logowania.
Cytat
'SQLSTATE[28000] [1045] Access denied for user 'www-data'@'localhost' (using password: NO)'

Nie może połączyć się z bazą, błędny login i/lub hasło.
viking
Przecież jest użytkownik tylko nie ma dostępu, jest bez hasła. Zrób sobie echo tego ciągu >>'mysql:host='.NAZWA_SERWERA_BD.';dbname='.NAZWA_BD.', '.NAZWA_UZYT_BD.', '.HASLO_UZYT_BD i zobacz czy wszystko jest poprawnie. Poza tym to nie w PDO problem tylko w programiście wink.gif Ja kiedyś pisałem o tym. Masz w mojej stopce artykuł.
castagir
Wkurzony byłem i tak napisałem. Chwilę po zamieszczeniu ostatniego postu udało mi się wreszcie właściwie połączyć.

Problem teraz jest inny.
Dalej poszeðłem według rad Tursona i ostatecznie mam zmienną z zbindowanymi danymi($wynik):
Chciałbym teraz te dane wyciągnąć na zewnątrz. Niestety teraz gdy próbuje wyciągnąć wynik tej zmiennej za pomocą "return" na zewnątrz funkcji, jedyne co mi pokazuje to NULL.

Co znowu źle zrobiłem?
  1. function inicjacja_logowania($nazwa, $haslo) {
  2. global $pdo_bd;
  3. global $przedrostek;
  4. $pytanie = $pdo_bd->prepare("SELECT id FROM ".$przedroste_bd."uzytkownicy WHERE login='".$nazwa."' AND haslo='".$haslo."' LIMIT 1");
  5. $pytanie->bindValue(':login', $nazwa, PDO::PARAM_STR);
  6. $pytanie->bindValue(':haslo', $haslo, PDO::PARAM_STR);
  7. $pytanie->execute();
  8.  
  9. return $wynik = $pytanie->fetch(PDO::FETCH_ASSOC);


PS Rysh: Robię intuicyjną platformę, którą może sobie sam skonfigurować administrator toteż nie mogą być tam wpisane po prostu dane, tylko muszę one zostać tam umieszczane za pośrednictwem stałych, które sa implementowane z innego pliku.
viking
W samym zapytaniu nie bindujesz tych parametrów tylko podstawiasz zmienne. Przeczytaj naprawdę choć jeden przykład zamiast działać na ślepo.
castagir
Teraz prawie wszystko rozumiem. Umiem juz odpowiednio ulozyc metoda PDO zapytanie, takze polaczyc sie i zbindowac dane. Nie potrafie jeszcze uzywac tych drivers, ale z czasem sie naucze o co w nich kaman.
Niestety wciaz nie wiem w jaki sposob wyciagnac wyniki i jak je wyciagac ze zmiennej. Ten sam problem mialem przy normalnych procedurowach w php mysqli_. Ciagle nie potrafie wywolac danych ze zmiennej chociazby po to aby wyswietlic ja przy pomocy echo, nie mowiac juz o tym aby zastosowac ja w jakiejs funkcji lub obliczeniu.
Turson
  1. $wynik = $pytanie->fetch(PDO::FETCH_ASSOC);

zwraca tablicę asocjacyjną. Wyprintuj zawartośc:
  1. echo '<pre>';
  2. print_r($wynik);
  3. echo '</pre>';

tu masz ładną tablicę klucz=>wartość
castagir
Może inaczej.

Chciałbym osiągnąć coś takiego:

Załóżmy, że mam w tabeli takie kolumny z wartościami(zapisze je id/1):

id(integer)/1 nazwa(varchar)/uzytkownik haslo(varchar)/12345 data(varchar)/20.12.2014

Chciałbym zrobić coś takiego. Logowanie jest wykonane za posrednictwem jednej funckji. W logowaniu uzytkownik wpisuje swoja nazwe. Nazwa jest zaakceptowana, bo istnieje taki uzytkownik w bazie - sprawdzone dzieki wynik zapytania > 0. Pytanie bylo sformulowane tak, zeby pobrac wszystkie dane z calej tablicy "SELECT * ...". Dane sa zapisane w $pytanie. Chce dane z $pytanie wyciagnac poza funkcje, bo beda mi potrzebne jeszcze do kilku innych operacji. Jak to zrobic?

Moglibyscie mi napisac przykladowa funkcje, ktora by objela to wszystko i wyciagnela to o co mi chodzi - czyli dane z zapytania, poza nia? Chodzi mi o to jakbyscie Wy to zrobili, bo poki co, kazdy napisal troche, proboje to jakos polaczyc i nic mi nie wychodzi. W przegladarce wciaz nic nie widac, bo dane wciaz sa uwiezione w funkcji.
nospor
W ostatnim poscie Tursona dostałes odpowiedź....
castagir
Robię właśnie to iwciąż nic nie otrzymuję.

Podaje kilka kombinacji jakie robiłem, aby otrzymac wynik:

  1. try {
  2. $polaczenie = new PDO('mysql:host=localhost;dbname=baza', 'uzytkownik', 'haslo');
  3. echo 'Połączono z bazą danych!'; }
  4. catch (PDOException $e) {
  5. echo ($e->getMessage()); }
  6.  
  7. $nazwa = 'uzytkownik';
  8. $haslo = sha1('123456789');
  9. $przedrostek_bd = 'baza_';
  10. $pytanie = $polaczenie->prepare("SELECT id FROM '".$przedrostek_bd."uzytkownicy' WHERE nazwa=:nazwa haslo=:haslo LIMIT 1");
  11. $pytanie->bindValue(':nazwa', $nazwa, PDO::PARAM_STR);
  12. $pytanie->bindValue(':haslo', $haslo, PDO::PARAM_STR);
  13.  
  14. $pytanie->execute();
  15. while ($row = $pytanie->fetch(PDO::FETCH_ASSOC)) {
  16. echo 'ID użytkownika '.$row['id']; }


  1. try {
  2. $polaczenie = new PDO('mysql:host=localhost;dbname=baza_endo', 'Baza-ENDO', 'AM1dilb4');
  3. echo 'Połączono z bazą danych!'; }
  4. catch (PDOException $e) {
  5. echo ($e->getMessage()); }
  6.  
  7. function pobranie_danych($polaczenie) {
  8. $nazwa = 'uzytkownik';
  9. $haslo = sha1('123456789');
  10. $przedrostek_bd = 'endo_';
  11. $pytanie = $polaczenie->prepare("SELECT id FROM '".$przedrostek_bd."uzytkownicy' WHERE nazwa=:nazwa haslo=:haslo LIMIT 1");
  12. $pytanie->bindValue(':nazwa', $nazwa, PDO::PARAM_STR);
  13. $pytanie->bindValue(':haslo', $haslo, PDO::PARAM_STR);
  14.  
  15. $pytanie->execute();
  16. return $pytanie;
  17. }
  18.  
  19. $wynik = pobranie_danych($polaczenie);
  20. while ($wiersz = $wynik->fetch(PDO::FETCH_ASSOC)) {
  21. echo '<pre>ID użytkownika: ';
  22. print_r($wiersz);
  23. echo '</pre>'; }


  1. try {
  2. $polaczenie = new PDO('mysql:host=localhost;dbname=baza_endo', 'Baza-ENDO', 'AM1dilb4');
  3. echo 'Połączono z bazą danych!'; }
  4. catch (PDOException $e) {
  5. echo ($e->getMessage()); }
  6.  
  7. function pobranie_danych($polaczenie) {
  8. $nazwa = 'uzytkownik';
  9. $haslo = sha1('123456789');
  10. $przedrostek_bd = 'endo_';
  11. $pytanie = $polaczenie->prepare("SELECT id FROM '".$przedrostek_bd."uzytkownicy' WHERE nazwa=:nazwa haslo=:haslo LIMIT 1");
  12. $pytanie->bindValue(':nazwa', $nazwa, PDO::PARAM_STR);
  13. $pytanie->bindValue(':haslo', $haslo, PDO::PARAM_STR);
  14.  
  15. $pytanie->execute();
  16. return $wynik = $pytanie->fetch(PDO::FETCH_ASSOC);
  17. }
  18.  
  19. $wynik = pobranie_danych($polaczenie);
  20. echo '<pre>ID użytkownika: ';
  21. print_r($wynik);
  22. echo '</pre>';


Nic nie działa. Nic nie pokazuje.
nospor
Bo albo nie ma danych spelaniajacych Twoje warunki albo masz błąd zapytania.
castagir
Możliwe. To w takim razie jak prawidłowo powinna wyglądać taka funkcja? Bo to co mi napisałeś wiele nie mówi.
viking
Daj jeszcze
  1. $polaczenie->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

Najbardziej logiczny po nazwie funkcji jest 3 przykład z tym że bez sensu robisz return $wynik = ... Po co jeszcze przypisanie przed return?
castagir
Biorę przez return, bo wydawało mi się, że tak właśnie powinno się zwracać wynik obliczenia wewnątrz funkcji. Tak jest przecież w funkcjach, które robią zadania na wartościach wprowadzonych ręcznie.
viking
Tak, ale czy wykorzystujesz gdzieś $wynik? Zapychasz tylko pamięć. Zwracaj bezpośrednio. return ...fetch.
Czy ustawienie rzucania wyjątku pomogło na brak wyników?
castagir
Ustawienie rzucania wyjątków też nic nie dąło. Ciagle pusty ekran, nawet żadnego komunikatu.
Wstawiłem go w takim miejscu:
  1. try {
  2. $polaczenie = new PDO('mysql:host=localhost;dbname=bazao', 'uzytkownik', 'haslo');
  3. $polaczenie->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
  4. echo 'Połączono z bazą danych!'; }
  5. catch (PDOException $e) {
  6. echo ($e->getMessage()); }


Zmieniłem także sposób return tak jak proponowałeś i także nic.
Sprółbuje może pokombinować coś z funkcjami RedBean, może w tej platformię coś znajdę.
viking
  1. ini_set('display_errors', 'on');


Ewentualnie sprawdź w logach serwera co się dzieje.
Jak to nie pomoże to pewnie, jak pisał nospor, nie masz danych w bazie.
castagir
Tez nic nie pomaga.
Co do danych, to mam na bank i pytanie również jest dobrze skonstrułowane, bo w terminalu wyszukuje poprawnie. Problemem jest pewnie składnia. W tym tkwi problem.
Dlatego proszę, aby ktoś napisał właśnie jak według niego powinna wyglądać ta funkcja. To co znajduję w internecie to zaledwie strzępy, które próbuję złączyć w jedno.


EDIT:
Znalazłem bardzo fajny poradnik na YT, w którym jest właśnie wszystko ładnie pokazane jak trzeba zwracać wynik po zapytaniu. Dzisiaj już nie mam do tego głowy i sił, więc jutro rano do tego jeszcze zajrzę i sprawdzę jak będzie mi szło.

Póki co dziękuję wszystkim za poświecony czas. Oporny ze mnie uczeń, bo nie mam do tego talenu, ani umiejętności, więc idzie to jak koń pod górkę.
Pozdrawiam

Wreszcie się udało biggrin.gif
Dziękuję wszystki za pomoc. biggrin.gif
viking
I jaki miałeś ostatecznie błąd?
castagir
Po zapytaniu napisałem pętlę, w której interesujący wynik mnie zapytania zapisałem w pętli. Myślę, że ten sposób się sprawdzi w przyszłości jeśli będę potrzebował zwrócenie jednej konkretnej rzeczy z bazy danych.
Zrobiłem taką końcówkę bloku:
  1. $pytanie->execute();
  2. if ($pytanie->rowCount() > 0)
  3. {
  4. while ($w = $pytanie->fetch(PDO::FETCH_ASSOC))
  5. {
  6. $wynik = 'ID uzytkownika: '.$w['id'];
  7. }
  8. } else {
  9. echo 'Nie udało się pobrac danych';
  10. }


Jeszcze nie wiem jak będę wyciągał dane, jeśli w wyniku będzie kilka wierszy.
Myślałem nad takim sposobem, aby tak jak na tym bloku wszystko zapisywało się w $wynik, tylko zeby zrobić coś takiego, że np $wynik[1] - [1] by się zwiększało z każdą kolejną wykonaną pętlą. W ten sposób bym miał piękny i czysty dostęp do każdego rekordu z bazy danych.

Ogólnie jeszcze raz dzięki za czas, lecz jeszcze to nie koniec moich problemów. biggrin.gif
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.