Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Bindowanie!
Forum PHP.pl > Forum > Przedszkole
woxala123
Witam!
Mam takie zapytanie czy w tym kodzie który jest poniżej muszę coś bindować?

  1.  
  2. $query = $pdo->prepare("SELECT * FROM users ORDER BY id");
  3. $query ->execute();
  4. $result = $query->setFetchMode(PDO::FETCH_ASSOC);
  5. $i = 0;
  6. echo '<table width="50%">';
  7. echo '<tr>';
  8. echo '<td>ID</td>';
  9. echo '<td>User</td>';
  10. echo '<td>Password</td>';
  11. echo '</tr>';
  12.  
  13. echo "<form name='form_update' method='post' action='upa2.php'>\n";
  14. while ($users = $query->fetch(PDO::FETCH_BOTH)) {
  15. echo '<tr>';
  16. echo "<td>{$users['id']}<input type='hidden' name='id[$i]' value='{$users['id']}' /></td>";
  17. echo "<td>{$users['username']}</td>";
  18. echo "<td><input type='text' size='40' name='password[$i]' value='{$users['password']}' /></td>";
  19. echo "<td><input type='text' size='40' name='username[$i]' value='{$users['username']}' /></td>";
  20.  
  21. echo '</tr>';
  22. ++$i;
  23. }
  24. echo '<tr>';
  25. echo "<td><input type='submit' value='submit' /></td>";
  26. echo '</tr>';
  27. echo "</form>";
  28. echo '</table>';
  29.  
  30.  

Dopiero bindowanie robie w drugim pliku upa2.php i pytanie czy dobrze jest zrobione bindowanie?
  1. $username= $_POST['username'][$i];
  2. $password= $_POST['password'][$i];
  3. $id = $_POST['id'][$i];
  4.  
  5. $sql = "UPDATE users SET password = '$password' , username = '$username' WHERE id = '$id' LIMIT 1";;
  6. $stmt = $pdo->prepare($sql);
  7. $stmt->bindParam(':username', $_POST['$username'], PDO::PARAM_STR);
  8. $stmt->bindParam(':password', $_POST['$password'], PDO::PARAM_STR);
  9. $stmt->bindParam(':id', $_POST['id'], PDO::PARAM_INT);
  10. $stmt->execute();
  11.  
viking
I gdzie masz niby to bindowanie w update?
woxala123
CZyli to powinno być tak?
  1. $stmt->bindValue(':username', $username, PDO::PARAM_STR);
  2. $stmt->bindValue(':password', $password, PDO::PARAM_STR);
  3. $stmt->bindValue(':id', $id, PDO::PARAM_INT);
  4.  
viking
Czyli najpierw ten placeholder musi się znajdować gdzieś w zapytaniu. Masz wszystko w dokumentacji opisane.
Niree
  1. while ($users = $query->fetch(PDO::FETCH_BOTH)) {
  2. echo '<tr>';
  3. echo "<td>{$users['id']}<input type='hidden' name='id[$i]' value='{$users['id']}' /></td>";
  4. echo "<td>{$users['username']}</td>";
  5. echo "<td><input type='text' size='40' name='password[$i]' value='{$users['password']}' /></td>";
  6. echo "<td><input type='text' size='40' name='username[$i]' value='{$users['username']}' /></td>";
  7.  
  8. echo '</tr>';
  9. ++$i;
  10. }


Przecież pętla while wyciąga każdy rekord z bazy i wykonuje się tyle razy, ile jest rekordów. Po co każdy jeszcze indeksujesz?
woxala123
Przecież tu jest to w zapytaniu
  1. $sql = "UPDATE users SET password = '$password' , username = '$username' WHERE id = '$id' LIMIT 1";;
  2. $stmt = $pdo->prepare($sql);


Niree dlatego tak to robię bo działa. Tylko jeszcze chce wiedzieć czy dobrze to zrobiłem bindowanie?

  1. $sql = "UPDATE users SET password = '$password' , username = '$username' WHERE id = '$id' LIMIT 1";;
  2. $stmt = $pdo->prepare($sql);
  3. $stmt->bindValue(':username', $username, PDO::PARAM_STR);
  4. $stmt->bindValue(':password',$password, PDO::PARAM_STR);
  5. $stmt->bindValue(':id', $id, PDO::PARAM_INT);
  6. $stmt->execute();
  7.  
  8.  

To jest moja wersja. Czy ona będzie okey?
viking
Obrazowo. Zabierasz się za malowanie pokoju. Przygotowałes farbę, umoczyles wałek a na ścianach obrazy, na podłodze dywan i meble rozłożone. Do tego drzwi do pokoju otwarte i każdy może wejść i wszystko wynieść. Tak wygląda twoje zapytanie.
woxala123
Viking to gdzie jest może błąd?
Na końcu kodu dodaje
  1. $stmt->closeCursor();
  2. unset($stmt);
  3. $pdo = null;
viking
Patrzyłeś w dokumentację czy jak zawsze ci się nie chce. Wklej tutaj przykładowe zapytanie które podają.
woxala123
Tutaj mam taki przykład

  1. if($_POST['action'] == 'update')
  2. {
  3. $id = $_POST['id'];
  4.  
  5. $password = $_POST['password'];
  6. $first_name = $_POST['first_name'];
  7. $last_name = $_POST['last_name'];
  8. $email = $_POST['email'];
  9. $country = $_POST['country '];
  10. $city = $_POST['city'];
  11. $post_code = $_POST['post_code'];
  12. $address = $_POST['address'];
  13. $phone = $_POST['phone'];
  14. $updated_at = time();
  15.  
  16. // przygotowanie szkieletu zapytania
  17. $stmt = $dbh->prepare('UPDATE customers SET
  18. password = :password,
  19. first_name = :first_name,
  20. last_name = :last_name,
  21. email = :email,
  22. country = :country,
  23. city = :city,
  24. post_code = :post_code,
  25. address = :address,
  26. phone = :phone,
  27. updated_at = :updated_at
  28. WHERE customer_id = :id
  29. ');
  30.  
  31. // przypisujemy zmienne do placeholderów
  32.  
  33. bindValue(':login', $login, PDO::PARAM_STR);
  34. bindValue(':password', $password, PDO::PARAM_STR);
  35. bindValue(':first_name', $first_name, PDO::PARAM_STR);
  36. bindValue(':last_name', $last_name, PDO::PARAM_STR);
  37. bindValue(':email', $email, PDO::PARAM_STR);
  38. bindValue(':country', $country , PDO::PARAM_STR);
  39. bindValue(':city', $city, PDO::PARAM_STR);
  40. bindValue(':post_code', $post_code, PDO::PARAM_STR);
  41. bindValue(':address', $address, PDO::PARAM_STR);
  42. bindValue(':phone', $phone, PDO::PARAM_STR);
  43. bindValue(':updated_at', $updated_at, PDO::PARAM_INT);
  44. bindValue(':id', $id, PDO::PARAM_INT);
  45.  
  46. // wykonujemy zapytanie
  47. $result = $stmt->execute();
  48.  
  49. if($result !== false)
  50. {
  51. echo 'Zaktualizowano użytkownika o ID = ' . $id;
  52. } else {
  53. echo 'Wystąpił błąd';
  54. }
  55.  
  56. $stmt->closeCursor();
  57. unset($stmt);
  58. $dbh = null;
  59. }
  60.  
viking
I naprawdę nie widzisz różnicy w kodzie prepare obu zapytań?
woxala123
no okey poprawie to i ocenisz
  1. $stmt = $pdo->prepare( "UPDATE users SET password = '$password' , username = '$username' WHERE id = '$id' LIMIT 1");
  2. $stmt->bindValue(':username', $username, PDO::PARAM_STR);
  3. $stmt->bindValue(':password',$password, PDO::PARAM_STR);
  4. $stmt->bindValue(':id', $id, PDO::PARAM_INT);
  5. $result = $stmt->execute();
  6.  
Tomplus
@woxala123

Viking próbuje Cię naprowadzić na rozwiązanie, ale chyba masz złe okulary na nosie i nie widzisz.

Jeżeli stosujesz bindValue to zgodnie z twoimi zmiennymi zapytanie do bazy powinno wyglądać tak:

Kod
UPDATE users SET password = :password , username = :username WHERE id = :id


Bez cudzysłowia, bez dolców. Jak się zagłębisz w zapytania PDO, to będziesz mógł tworzyć zapytania bez zmiennych bind podanych wyżej, a tylko:

Kod
UPDATE users SET password = ? , username = ? WHERE id = ?


LIMIT 1 - jeżeli kolumna ID jest unikatowa, jest nie potrzebne.
viking
I popsułeś zabawę smile.gif Zaraz pewnie pojawi się 100 innych podobnych pytań. Voxala musi się nauczyć sam dochodzić do rozwiązania bo dotychczasowe jego problemy wynikają z nieumiejętnego czytania dokumentacji i przykładów.
woxala123
Zabawa jest świetna. Ale skoro zastosowałem zmienne to je bindowałem.Twój przykład też jest godny zastosowania-też już czytałem na ten temat. To jest tylko kwestia przerobienia kodu.
teraz wygląda tak. Dostoswałem się jak jest wyżej.

  1. $stmt = $pdo->prepare( "UPDATE users SET password = :password , username = :username WHERE id = :id");
  2.  
  3. $stmt->bindParam(':username', $username, PDO::PARAM_STR);
  4. $stmt->bindParam(':password',$password, PDO::PARAM_STR);
  5. $stmt->bindParam(':id', $id, PDO::PARAM_INT);
  6. $stmt->execute();
  7.  
viking
Bindowałeś do zapytania które nie było przygotowane na to. Innymi słowy, podstawiałeś zmienne POST bezpośrednio do zapytania a niżej jakiś zbędny kod. Już nie pamietam - PDO nie rzucało tam wyjątku że liczba parametrów zbindowanych nie równa się liczbie placeholderów?
woxala123
Właśnie nic nie wyrzuca. Działa dobrze. Przecież wyżej były trzy zmienne
viking
Podstawione bezpośrednio do SQL. Jeśli tego nie potrafisz zrozumieć to nie wiem jak inaczej wytłumaczyć.
woxala123
Okey poddaje się. To proszę napisz przykład jak to powinno wyglądać.
viking
Poddaje się, powinno wyglądać jak w poście 15. W poście 12 bindujesz sobie w pustkę.
woxala123
Czyli teraz dobrze bindowałem w poscie 12 tak.
viking
Cudownie, podstaw tam sobie jako hasło
  1. $password = "'; drop table users;--";
Tomplus
W poście #12 stworzyłeś powiązania, ale do niczego.

Wyobraź sobie że zapytania i bindy to DWA zbiory powiązane identyfikatorem.

  1. $stmt = $pdo->prepare( "SELECT `name` FROM `table`WHERE id = :identyfikator");
  2. $stmt->bindParam(':identyfikator', $value);


Takich identyfikatorów może być mnóstwo, u Ciebie są 3 takie wiązania, dlatego w metodzie prepare musisz wskazać wszystkie powiązania inaczej zapytanie będzie działać wadliwie lub jak zaprezentowałeś na początku, będzie niebezpieczne.

Identyfikator, może być w formie string, ale także jako integer.

Wstrzykiwanie zmiennych PHP w kod zapytania możesz co najwyżej użyć w przypadku wskazywania konkretnych kolumn i tablic. Wartości "binduje" się.
woxala123
Jeśli dobrze rozumiem Ciebie że w tym wypadku moją wartościa będzie zmienna Post?
Tomplus
Graficznie te zapytania wyglądają tak:
Z #12


Z #15





Ja nie wiem jaką wartością będzie, po prostu nie dodaje się zmiennych HTML w kod PDO, szczególnie jeżeli pochodzą ze źródła zewnętrznego czyli $_POST i $_GET (także $_COOKIE, $_SESSION).

Inaczej może spotkać Cię kara taką jak pokazał Ci na przykładzie Viking.
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.