Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Problem z metoda prepare
Forum PHP.pl > Forum > Przedszkole
Mehis
Hej,
Uczę się tworzyć CMS i mam problem z jedną metodą.
Próbuję zrobić autoryzację podczas logowania, według kursu ze strefy kursów.
Wszystko jest ok, do momentu linijki z funkcją prepare().

  1. function validateLogin($user, $pass){
  2. global $Database;
  3.  
  4. if($stmt = $Database->prepare("SELECT * FROM users WHERE username = ? AND password = ?")){
  5.  
  6. $stmt->bind_param("ss", $user,md5($pass.$this->salt));
  7. $stmt->execute();
  8. $stmt->store_result();
  9.  
  10. if($stmt->num_rows >0){
  11. $stmt->close();
  12. return TRUE;
  13. }else{
  14. $stmt->close();
  15. return FALSE;
  16. }
  17. }else{
  18. die();
  19. }
  20. }


$Database było tworzone w innym pliku :
  1. $server = 'localhost';
  2. $user = 'root';
  3. $pass = '';
  4. $db = 'sk_login';
  5.  
  6. $Database = new mysqli($server,$user,$pass,$db);


Plik generuje błąd:
Warning: mysqli::prepare(): Couldn't fetch mysqli in ...

Function Location
prepare ( ) ..\m_auth.php:18


Szukałem odpowiedzi na stackoverflow itp. ale nic mi to nie pomogło.
Ktoś wie, gdzie jest błąd i jak się go pozbyć?
z góry wielkie dzięki:)
markuz
Po wklejeniu błędu w Google pierwsza odpowiedź na stackoverflow:
Cytat
Reason of the error is wrong initialization of the mysqli object.

U Ciebie jest pewnie taki sam powód - pokaż więcej kodu.

Mehis
database.php
  1. <?php
  2. $server = 'localhost';
  3. $user = 'root';
  4. $pass = '';
  5. $db = 'sk_login';
  6.  
  7. $Database = new mysqli($server,$user,$pass,$db);


m_auth.php
  1. class Auth {
  2. private $salt = 'e3Gde4';
  3.  
  4. function __construct(){
  5. }
  6.  
  7. function validateLogin($user, $pass){
  8. global $Database;
  9.  
  10. if($stmt = $Database->prepare("SELECT * FROM users WHERE username = ? AND password = ?")){
  11.  
  12. $stmt->bind_param("ss", $user,md5($pass.$this->salt));
  13. $stmt->execute();
  14. $stmt->store_result();
  15.  
  16. if($stmt->num_rows >0){
  17. $stmt->close();
  18. return TRUE;
  19. }else{
  20. $stmt->close();
  21. return FALSE;
  22. }
  23. }else{
  24. die();
  25. }
  26. }
  27.  
  28. function checkLoginStatus(){
  29. if(isset($_SESSION['loggedin'])){
  30. return true;
  31. }else{
  32. return false;
  33. }
  34. }
  35.  
  36. function logout(){
  37. }
  38. }

login.php
  1. <?php
  2. /**
  3.  * Created by IntelliJ IDEA.
  4.  * User: Dawid
  5.  * Date: 20.09.2015
  6.  * Time: 10:40
  7.  */
  8. @include("includes/database.php");
  9. @include("includes/init.php");
  10.  
  11. if(isset($_POST['submit'])){
  12.  
  13. $Template->setData('input_user',$_POST['username']);
  14. $Template->setData('input_pass',$_POST['password']);
  15.  
  16. if($_POST['username'] == '' || $_POST['password'] == ''){
  17. $Template->setAlert('Uzupełnij wymagane pola', 'error');
  18. $Template->load("views/v_login.php");
  19. }else if($Auth->validateLogin($Template->getData('input_user'), $Template->getData('input_pass')) == false){
  20. $Template->setAlert("Złe dane logowania", 'error');
  21. $Template->load("views/v_login.php");
  22. }else{
  23. $_SESSION['username'] = $Template->getData('input_user');
  24. $_SESSION['loggedin'] = true;
  25. $Template->setAlert('Witaj '. $Template->getData('input_user'));
  26. $Template->redirect('users.php');
  27. }
  28.  
  29. }else{
  30. $Template->load("views/v_login.php");
  31. }


v_login.php
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>login</title>
  5. <meta charset="UTF-8">
  6. <link rel="stylesheet" type="text/css" href="views/style.css"/>
  7. </head>
  8. <body>
  9. <h1>Logowanie</h1>
  10.  
  11. <form action="" method="post">
  12. <?php
  13. $alerts = $this->getAlerts();
  14. if($alerts!=''){
  15. echo '<ul class="alerts">' .$alerts .'</ul>';
  16. }
  17. ?>
  18. <p>
  19. <label for="username"> Użytkownik: </label>
  20. <input type="text" name="username" value="<?php echo $this->getData('input_user');?>"/>
  21. </p>
  22. <p>
  23. <label for="password"> Hasło: </label>
  24. <input type="password" name="password" value="<?php echo $this->getData('input_pass');?>"/>
  25. </p>
  26. <p>
  27. <input type="submit" name="submit" class="submit" value="Wyślij"/>
  28. </p>
  29. </form>
  30. </body>
  31. </html>
  32.  


Edytowałem tylko te 4 pliki. Tworzenie obiektu Auth jest w init.php: $Auth = new Auth();

W phpMyAdmin mam bazę danych sk_login z tablicą users i jednym rekordem admina.
KsaR
1. Bledów się nie wycisza tylko naprawia.
  1. /*
  2. @include("includes/database.php");
  3. @include("includes/init.php");
  4. */
  5. # tak powinno być:
  6.  
  7. include 'includes/database.php';
  8. include 'includes/init.php';

I w tym byc moze blad...... Jak cos wyskoczy to popraw sciezke.
--

Przy okazji:

  1. /* if(isset($_SESSION['loggedin'])){
  2. return true;
  3. }else{
  4. return false;
  5. }
  6. */
  7. # to samo ale krocej:
  8. return isset($_SESSION['loggedin']);
  9. #...
  10. /* if($stmt->num_rows >0){
  11. $stmt->close();
  12. return TRUE;
  13. }else{
  14. $stmt->close();
  15. return FALSE;
  16. }*/
  17. # tu tez to samo ale krocej:
  18. return ($stmt->num_rows>0);
  19. // $stmt->close pominiete bo zbedne i tak chyba, ewentualnie mozesz jesli potrzebujesz...
  20. $numRows=$stmt->num_rows;
  21. $stmt->close();
  22. return ($numRows>0);
  23. #...
  24. /**
  25. * if($_POST['username'] == '' || $_POST['password'] == ''){
  26. */
  27. // powinno byc:
  28. if(!isset($_POST['username'][0], $_POST['password'][0])){
  29. #...
  30. /**
  31. * <?php echo 'coś' ?>
  32. * mozna jako: <?='coś'?>, od php 5.4 domyslnie wlaczone. ;)
  33. */

I to tylko przyklady bo podobne rzeczy robisz w kilku miejscach tongue.gif
Pyton_000
Cytat(KsaR @ 30.09.2015, 09:27:41 ) *
1. Bledów się nie wycisza tylko naprawia.
  1. /**
  2. * if($_POST['username'] == '' || $_POST['password'] == ''){
  3. */
  4. // powinno byc:
  5. if(!isset($_POST['username'][0], $_POST['password'][0])){


Jak już to

  1. if(empty($_POST['username']) || empty($_POST['password'])){
KsaR
Cytat(Pyton_000 @ 30.09.2015, 09:48:04 ) *
Jak już to

  1. if(empty($_POST['username']) || empty($_POST['password'])){

To jest to samo tongue.gif ja mam inne podejscie niz inni.
(mb_)strlen(); itp to uzywam tylko gdy potrzebuje pokazac ilosc, a nie sprawdzic dlugosc.
empty uzywam na nieznanej zawartosci, np. Tablicy.
Bo jak znam to uzywam isset() np. czy nie pusta isset($tablica['x'][0]); - czyli pierwszy znak jest ;p
Pyton_000
To masz złe podejście. Masz tuta wiele niepotrzebnych operacji.
Cytat
Bo jak znam to uzywam isset($tablica['x']); (czy klucz jest)

Z tym też radzę uważać, bo jesli klucz jest a ma wartość null to wywali false, a powinno true bo klucz jest i ma wartość null, więc trzeba użyć array_key_exists.

Powiem jeszcze raz, nie kombinuj tak bo to się zemści na Tobie bardzo boleśnie.
KsaR
Cytat(Pyton_000 @ 30.09.2015, 09:59:52 ) *
To masz złe podejście. Masz tuta wiele niepotrzebnych operacji.

Z tym też radzę uważać, bo jesli klucz jest a ma wartość null to wywali false, a powinno true bo klucz jest i ma wartość null, więc trzeba użyć array_key_exists.

Powiem jeszcze raz, nie kombinuj tak bo to się zemści na Tobie bardzo boleśnie.

Zly przyklad dalem i skasowalem 4 minuty temu juz. wink.gif, to nie kombinowanie tylko poprawne programowanie. Dla mnie tak logiczniej wiele. Logiczne uzywanie tego co trzeba itp(tak jak w cytacie w sygnaturze).
"Tylko dlatego że możesz coś, nie oznacza że musisz"
...
Wbrew pozora jak tak dluzej sie pouzywa takie tricki' to juz sie nomalnie wylapuje takie zastosowania, bynajmniej mi tak przychodzi to. Gdy czegos potrzebuje to tego uzywam, gdy nie to nie..
Mehis
Ok dzięki KsaR i Pyton_000 smile.gif
Teraz wszystko działa, ale musiałem dodać jeszcze jedną zmienną.
  1. $temp = md5($pass.$this->salt);
  2. $stmt->bind_param("ss", $user, $temp);

Bez tego tempa wyskakiwał błąd 'Strict standards: Only variables should be passed by reference in'.
Z ciekawości sprawdziłem w plikach kursu i tam niby wszystko działało, także nie bardzo rozumiem co zmienia fakt, czy wrzucę wynik do zmiennej, czy wywołam metodę w parametrze funkcji.
KsaR
Cytat(Mehis @ 30.09.2015, 10:28:56 ) *
Ok dzięki KsaR i Pyton_000 smile.gif
Teraz wszystko działa, ale musiałem dodać jeszcze jedną zmienną.
  1. $temp = md5($pass.$this->salt);
  2. $stmt->bind_param("ss", $user, $temp);

Bez tego tempa wyskakiwał błąd 'Strict standards: Only variables should be passed by reference in'.
Z ciekawości sprawdziłem w plikach kursu i tam niby wszystko działało, także nie bardzo rozumiem co zmienia fakt, czy wrzucę wynik do zmiennej, czy wywołam metodę w parametrze funkcji.

Metoda bind_param przyjmuje argumenty (poza pierwszym) przez referencje.
Referencja wskazuje co jest tym samym a nie kopia.

Np.

$zmienna&=$zmienna2; # $zmienna jest referencja do $zmienna2, a nie kopia. Czyli jak zmienisz jedno zmieni sie tez drugie.

$zmienna=$zmienna2; # $zmienna jest kopia $zmienna2, jak zmienisz 1dno to tylko to a nie oba.

Czyli generalnie referencji nie zrobisz do zadnego typu (string, array etc) musisz miec zmienna.
A czemu tak zrobili to nwm, glupi pomysl w tym wypadku, w PDO to samo tongue.gif
Pyton_000
Cytat(KsaR @ 30.09.2015, 10:38:21 ) *
$zmienna&=$zmienna2; # $zmienna jest referencja do $zmienna2, a nie kopia. Czyli jak zmienisz jedno zmieni sie tez drugie.

Weź to wywal i nie pisz takich głupot...

Referencje ustala się tak:

  1. $zmienna = &$zmienna2;
KsaR
Cytat(Pyton_000 @ 30.09.2015, 11:08:49) *
  1. $zmienna = &$zmienna2;

+1 zamuła, wstałem o 22 i od 4tej nie mysle ;p
com
Cytat(KsaR @ 30.09.2015, 10:02:25 ) *
Zly przyklad dalem i skasowalem 4 minuty temu juz. wink.gif, to nie kombinowanie tylko poprawne programowanie. Dla mnie tak logiczniej wiele. Logiczne uzywanie tego co trzeba itp(tak jak w cytacie w sygnaturze).
"Tylko dlatego że możesz coś, nie oznacza że musisz"
...
Wbrew pozora jak tak dluzej sie pouzywa takie tricki' to juz sie nomalnie wylapuje takie zastosowania, bynajmniej mi tak przychodzi to. Gdy czegos potrzebuje to tego uzywam, gdy nie to nie..


KsaR Jak już bardzo chcesz tak pisać, to pisz w własnym kodzie którego nikt nie widzi, ale nie ucz takich hacków innych, bo ten sposób nie jest dobry. Bo prędzej czy później przyjdzie komuś ten kod albo debugować, albo refaktorować i wtedy trzeba będzie albo całe wywalić, albo zastanawiać się pół godziny co to ma robić.
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.