Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Kirjautuminen PDO

Sivun loppuun

manninen [09.08.2011 13:30:30]

#

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;
      }
    }
  }
}
?>

TeNDoLLA [09.08.2011 14:03:12]

#

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ä.

manninen [09.08.2011 14:18:05]

#

Tuosta sen pieraisen!

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;

The Alchemist [09.08.2011 14:31:56]

#

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ä.

manninen [09.08.2011 22:32:56]

#

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;
}

manninen [11.08.2011 14:59:07]

#

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.

Metabolix [11.08.2011 15:15:39]

#

Olisiko ihan mahdoton ajatus noudattaa ilmoituksessa olevaa ohjetta eli laittaa puskurointi käyttöön?

manninen [11.08.2011 15:19:50]

#

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());
      }

manninen [11.08.2011 15:54:46]

#

Vastaus ongelmaani löytyi!

<?php
$con = new PDO("mysql:dbname=dbname;host=some.ip", "user", "pass", array(
      PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
   ));
?>

manninen [23.08.2011 12:35:52]

#

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;
      }
    }
  }
}
?>

Metabolix [23.08.2011 13:24:08]

#

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.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta