En meinaa itse löytää mistään virhettä, mutta tiedän sen jossain olevan :)
Vikahan on siis siinä, että kaikki halukkaat pääsee läpi jos vain täyttävät molemmat kentät. :)
Kiitos TeNDoNLa vastauksestasi, mutta vika ei ole siinä. Se on kuitenkin poistettu. Nyt mennään sisään enää vain jos tiedetään käyttäjätunnus, mutta salasanaa ei tarvitse tietää. Luulen vian olevan update komennossa, mutta missä siinä :)
<?php /** * Kirjautuminen versio 1.0 * Luotu : 09.08.2011 * Muokattu : */ /******************************************************************************/ class Kirjautuminen { private $salasana, $kayttaja, $istuntotunnus; public function __construct($salasana, $kayttaja) { $this->Salasana = empty($salasana) ? NULL : mysql_real_escape_string($salasana); $this->Kayttaja = empty($kayttaja) ? NULL : mysql_real_escape_string($kayttaja); $this->uusiSuola = uniqid('', true); $this->Istunto = uniqid(rand(), true); $this->Tiiviste = sha1($this->Salasana.$this->uusiSuola); } public function Kirjaudu($conn){ /** * Haetaan tietokannasta salasanalle suola, joka vaihtuu joka kirjautumiskerralla. */ if(isset($this->Kayttaja, $this->Salasana)){ try{ $sql = $conn->prepare("SELECT suola FROM kayttajat WHERE kayttaja = ?"); $sql->execute(array($this->Kayttaja)); }catch(PDOException $e){ die("ERROR: " . $e->getMessage()); } $r = $sql->fetch(); if(!$r) return; echo '<pre>'. print_r($r).'</pre>'; /** * Luodaan tiiviste tietokannasta saadusta suolasta ja verrataan sitä seuraavassa kyselyssä! **/ $this->UusiTiiviste = sha1($this->Salasana.$r['suola']); try{ $q = $conn->prepare("UPDATE kayttajat SET istuntotunnus = :session , suola = :salt, tiiviste = :seal WHERE kayttaja = $this->Kayttaja AND tiiviste = $this->UusiTiiviste"); $q->bindParam(':session' , $this->Istunto); $q->bindParam(':salt' , $this->uusiSuola); $q->bindParam(':seal', $this->Tiiviste); }catch(PDOException $e){ die("ERROR: " . $e->getMessage()); } $res = $q->fetch(); //if(!$res) return; echo '<pre>'. print_r($res).'</pre>'; if(count($q->fetch() == 1)){ echo 'asdasd'; $_SESSION['login_key'] = $this->Istunto; //header("location:oho.php"); exit; } else{ return; } } } } ?>
Sulla ei ole ainakaan tuommosta Tarkiste muuttujaa määritetty koko luokassa mitä käytät tuossa
if(isset($this->Kayttaja, $this->Salasana) && !(isset($this->Tarkiste))){
Lisäksi mistä pieraset tän $r['suola'] muuttujan? Näyttää niinkuin tuolta puuttuisi tavaraa välistä.
Tuosta sen pieraisen!
manninen kirjoitti:
/** * Luodaan tiiviste tietokannasta saadusta suolasta ja verrataan sitä seuraavassa kyselyssä! **/ $this->UusiTiiviste = sha1($this->Salasana.$r['suola']); try{ $q = $conn->prepare("UPDATE kayttajat SET istuntotunnus = :session , suola = :salt, tiiviste = :seal WHERE kayttaja = $this->Kayttaja AND tiiviste = $this->UusiTiiviste"); $q->bindParam(':session' , $this->Istunto); $q->bindParam(':salt' , $this->uusiSuola); $q->bindParam(':seal', $this->Tiiviste); }catch(PDOException $e){ die("ERROR: " . $e->getMessage()); } $res = $q->fetch(); echo '<pre>'. print_r($res).'</pre>'; if(count($q->fetch() == 1)){ echo 'asdasd'; $_SESSION['login_key'] = $this->Istunto; //header("location:oho.php"); exit; } ?>
Olisikohan vika siinä, ettei UPDATE-kysely palauta yhtään mitään. Dokkareista ei ihan käy ilmi, mitä PDOStatement::fetch() silloin palauttaa, mutta veikkaisin sieltä tulevan (bool)false tai jotain muuta, mikä evaluoituu ykköseksi count():ssa.
Korvaa siis count($q->fetch()) kutsulla $q->rowCount().
...tai sitten vika on siinä, että kutsut funktiota fetch() kaksi kertaa, eikä jälkimmäinen enää palauta mitään hyödyllistä.
Fetch() sitä paitsi palauttaa aina yhden rivin kerrallaan, joten tuossa countin käytössä ei muutenkaan ole mitään järkeä.
Vika oli siinä, että update ei palauttanut yhtään mitään! Kiitoksia!
Muodostettu loppu pää uusiksi ja homma toimii!
try{ $q = $conn->prepare("UPDATE kayttajat SET istuntotunnus = ? , suola = ?, tiiviste = ? WHERE kayttaja = ? AND tiiviste = ?"); $q->execute(array($this->Istunto, $this->uusiSuola, $this->Tiiviste, $this->Kayttaja, $this->UusiTiiviste)); }catch(PDOException $e){ die("ERROR: " . $e->getMessage()); } if($q->rowCount() == 1){ $_SESSION['login_key'] = $this->Istunto; header("admistrator.php"); exit; }
Hei!
Saan seuraavanlaisen virheilmoituksen palvelimellani. Paikallisella koneella toimii moitteettomasti. Ongelma ilmenee vain kirjautumisvaiheessa.
ERROR: SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
Olisiko ihan mahdoton ajatus noudattaa ilmoituksessa olevaa ohjetta eli laittaa puskurointi käyttöön?
Ei ole mahdoton ajatus, mutta miten toteutan tämän oikeaoppisesti
Kokeillessani sitä näin, ei muutosta tapahtunut.
try{ if($conn->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') { $q = $conn->prepare("UPDATE kayttajat SET istuntotunnus = ? , suola = ?, tiiviste = ? WHERE kayttaja = ? AND tiiviste = ?", array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true)); } else{ echo("Error!"); } $q->execute(array($this->Istunto, $this->uusiSuola, $this->Tiiviste, $this->Kayttaja, $this->UusiTiiviste)); }catch(PDOException $e){ die("ERROR: " . $e->getMessage()); }
Vastaus ongelmaani löytyi!
Heti kun vaihdoin palvelinta niin tuli uusi ongelma.
Warning: Cannot modify header information - headers already sent by (output started at /home//public_html/login.php:25) in /home//public_html/class/kirjautuminen.class.php on line 68
<?php class Kirjautuminen { private $salasana, $kayttaja, $istuntotunnus; public function __construct($salasana, $kayttaja) { $this->Salasana = empty($salasana) ? NULL : $salasana; $this->Kayttaja = empty($kayttaja) ? NULL : $kayttaja; $this->uusiSuola = uniqid('', true); $this->Istunto = uniqid(rand(), true); $this->Tiiviste = sha1($this->Salasana.$this->uusiSuola); } public function Kirjaudu($conn){ if(isset($this->Kayttaja, $this->Salasana)){ try{ if($conn->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') { $sql = $conn->prepare("SELECT suola FROM kayttajat WHERE kayttaja = ?", array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true)); } else { echo("Error!"); } $sql->execute(array($this->Kayttaja)); }catch(PDOException $e){ die("ERROR: " . $e->getMessage()); } $r = $sql->fetch(); if(!$r){ return; } $salt = isset($r['suola']) ? $r['suola'] : ''; $this->UusiTiiviste = sha1($this->Salasana.$salt); try{ if($conn->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') { $q = $conn->prepare("UPDATE kayttajat SET istuntotunnus = ? , suola = ?, tiiviste = ? WHERE kayttaja = ? AND tiiviste = ?", array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true)); } else{ echo("Error!"); } $q->execute(array($this->Istunto, $this->uusiSuola, $this->Tiiviste, $this->Kayttaja, $this->UusiTiiviste)); }catch(PDOException $e){ die("ERROR: " . $e->getMessage()); } if($q->rowCount() == 1){ $_SESSION['login_key'] = $this->Istunto; header("location:admistrator.php"); exit; } else{ return; } } } } ?>
Vähän oma-aloitteisuuttakin saisi koodarilla olla. Mitä jos vaikka lukisit ja suomentaisit tuon virheilmoituksen? Sitten voisit hetken miettiä, mitä siinä sanotaan, ja jos jostain syystä ongelman syy ei vieläkään tule selväksi, voisit esimerkiksi hakea netistä tietoa virheilmoituksen olennaisilla sanoilla – löytyy miljoonia hakutuloksia.
Aihe on jo aika vanha, joten et voi enää vastata siihen.