Avatar billede langkiller Nybegynder
20. juli 2012 - 00:53 Der er 23 kommentarer og
1 løsning

num_rows fejl med prepared statements

Her er et udsnit af min kode som den er gal med:

function checkLogin($typedEmail, $typedPassword) {
    $returnMes = "";
   
    $mysqli = connect();
    $checkLogin = $mysqli->prepare('SELECT id,email,password,verify FROM users WHERE email=? AND password=?') or die ('could not find information');
    $checkLogin->bind_param('ss', $tryEmail, $tryPassword);
        $tryEmail = $typedEmail;
        $tryPassword = encryptPassword($typedPassword);
    $checkLogin->execute();
    $checkLogin->bind_result($loginId, $loginEmail, $loginPassword, $loginVerify);
    $checkLogin->fetch();

    print $checkLogin->num_rows;

Linjen:
print $checkLogin->num_rows;


udskriver hele tiden 0.. Er det noget af ovenstående den er gal med eller kan det skyldes noget helt andet?
Avatar billede olebole Juniormester
20. juli 2012 - 06:23 #1
<ole>

Prøv et flytte linjen op lige under execute

/mvh
</bole>
Avatar billede langkiller Nybegynder
20. juli 2012 - 10:32 #2
altså flytte denne linje: print $checkLogin->num_rows; derop?

det giver stadig 0... men jeg ved at den får fat i 1! for jeg kan sagtens udskrive det rigtige id osv.. :/
Avatar billede DeeDawg Nybegynder
20. juli 2012 - 13:14 #3
For at benytte num_rows, skal du først gemme udtrækket fra databasen. Tag et kig på følgende:

$checkLogin->execute();
$checkLogin->store_result();

print $checkLogin->num_rows;
Avatar billede olebole Juniormester
20. juli 2012 - 15:48 #4
#3: Sæ'føl'somt!  *o)
Avatar billede langkiller Nybegynder
07. august 2012 - 16:49 #5
undskyld jeg har været så langsom til at svare herinde.

#DeeDawg tak for hjælpen! det virkede perfekt, vil du have points?

Kan en af jer se hvad problemet ved dette stykke kode er?
Skal generere en sikkerhedskode, som skal opdateres hver gang man logger ind, men kan ikke rigtig få min update funktion til at virke...

    $newVerify = $mysqli->prepare('UPDATE users SET verify=? WHERE id=?') or die ('Could not updata verification num');
            $checkLogin->bind_param('si', $randomNum,$loginId);
            $randomNum = generateRandomNum();
            $checkLogin->execute();
           
            // den nye sikkerhedskode sættes i denne cookie
            setcookie("verifyCode", $randomNum, time() + 60 * 60 * 24 * 365);

prøvede for en sikkerheds skyld at udskrive sikkerhedskoden:
print $randomNum;
hvilket virkede! variabel $loginId virker også korrekt så det må vel være noget med rækkefølgen sætningerne eller selve sql statementen?
Avatar billede olebole Juniormester
07. august 2012 - 20:13 #6
Hvis $randomNum er et tal - og $loginId er en stren - så skal der stå:

$checkLogin->bind_param('is', $randomNum,$loginId);
Avatar billede langkiller Nybegynder
07. august 2012 - 20:28 #7
altså i databasen er de begge int.. men 'ii' virker heller ikker, så fejlen må vel ligge et andet sted
Avatar billede olebole Juniormester
07. august 2012 - 20:37 #8
skal det være 'ii'. Prøv at echo'e Statement- og/eller MySqli-fejl ud på passende steder. Henholdsvis:  $checkLogin->error og $mysqli->error
Avatar billede langkiller Nybegynder
07. august 2012 - 20:43 #9
har lige prøvet med
print $checkLogin->error;
og
print $mysqli->error;

forskellige steder uden held.. de udskriver intet.
Avatar billede olebole Juniormester
07. august 2012 - 21:22 #10
Jeg kan ikke se, du sætter variablen $loginId, efter du har bundet den til dit statement. Det skal du
Avatar billede langkiller Nybegynder
07. august 2012 - 21:36 #11
$loginId bliver sat længere oppe og indeholder det rigtige id...

ooooh sh*t!! har lige opdaget hvor problemet lå nu.

  $newVerify = $mysqli->prepare('UPDATE users SET verify=? WHERE id=?') or die ('Could not updata verification num');
            $checkLogin->bind_param('si', $randomNum,$loginId);
            $randomNum = generateRandomNum();
            $checkLogin->execute();

skal selvfølgelig ændres så der står $newVerify hele vejen ned i stedet for $checkLogin, som er et statement længere oppe.. så den har bare executet en gang til :S

men nu ser det ud til at virke :) langt om længe
Avatar billede langkiller Nybegynder
07. august 2012 - 21:38 #12
nogle gange kan man bare ikke se skoven for bare træer :b

men tak for hjælpen endnu en gang olebole :)

- Hvis DeeDawg stadig er med på tråden kan du jo smider et svar for det oprindelige spørgsmål hvis du vil have points
Avatar billede olebole Juniormester
07. august 2012 - 21:46 #13
Dooohhhh ... hvor blind kan en ældre mand med et par rimeligt nye briller dog være?  :D
Avatar billede langkiller Nybegynder
07. august 2012 - 22:57 #14
ja det er et godt spørgsmål :)

eehh er stødt på endnu et "underligt" problem nu i forbindelse med den sikkerhedskode der sættes ud fra et random tal. Den blev sat ligesom i ovenstående kode og derefter i en cookie sådan her:
setcookie("verifyCode", $randomNum, time() + 60 * 60 * 24 * 365);

men af en eller anden grund vil det random tal i databasen gerne være: 2147483647 hver gang.. og det random tal i min cookie bliver et nyt når man logger ind. har prøvet at slette al browser data for at få cookies væk.. så prøvede jeg igen, men stadig samme tal i databasen og et helt andet i min cookie.. synes det er MEGET underligt da dette tal kommer fra den samme variabel (og funktion) altså: $randomNum = generateRandomNum();
hvordan kan det blive 2 forskellige tal??? og hvordan kan den lave det samme tal til databasen igen??
Avatar billede langkiller Nybegynder
07. august 2012 - 22:59 #15
*slettede også feltet med tallet i databasen, men det dukkede det bare op igen efter login funktionen blev kørt igen
Avatar billede olebole Juniormester
07. august 2012 - 23:08 #16
Udover at 2147483647 er et 'magisk' tal - et af ganske få kendte, dobbelte Mersenne primtal - så er det den største værdi en 32bit integer kan have. Større tal kan PHP ikke arbejde med  =)
Avatar billede olebole Juniormester
07. august 2012 - 23:13 #17
"og hvordan kan den lave det samme tal til databasen igen??" >> Det kan under alle omstændigheder sagtens lade sig gøre. Der findes ingen PHP-funktioner, som genererer et ægte tilfældigt tal - og selvom der gjorde, betyder 'tilfældig' ikke det samme som 'unik'.

To (ægte eller uægte) tilfældige tal kan sagtens komme lige efter hinanden. Statisktisk går der så bare længere, før det kommer op igen  =)
Avatar billede langkiller Nybegynder
07. august 2012 - 23:17 #18
hmm okay nu har jeg så prøvet en del gange.. så det kan vel ikke være et tilfælde.

men du siger det er den største værdi en 32bit integer kan have.
og min funktion der generere dette tal ser sådan her ud

function generateRandomNum() {
$ranNum = "".rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9);

return $ranNum;
}


er det så fordi php ikke kan sætte sådan et stort tal ind i en database at det sker eller?
Avatar billede langkiller Nybegynder
07. august 2012 - 23:18 #19
men det er måske også en lidt dum måde at lave sådan et tal på..
Avatar billede olebole Juniormester
07. august 2012 - 23:19 #20
Skal tallet være unikt, må du teste mod en cache af allerede brute tal:

$arrTest = array();
$random = [GENERATE];
while ($arrTest[$random]) {
    $random = [GENERATE];
}
$arrTest[$random] = 1;

// Udskriv et (for dette dokument) unikt tal
echo $random;

- og skal værdien være unik over tid og for hele app'en, gemmer du de brugte værdier i en tabel i stedet  =)
Avatar billede olebole Juniormester
07. august 2012 - 23:24 #21
#18: Sorry, men det er en meget skidt konstruktion. Prøv i stedet:

$random = mt_rand(0, 2000000000);

Det er langt simplere - mere tilfældigt - dramatisk meget hurtigere - og tallet bliver altid under grænsen ... det bliver max. 2.000.000.000
Avatar billede langkiller Nybegynder
09. august 2012 - 00:59 #22
Ja ved godt det var en dum måde at gøre det på.. det er ændret nu. Har også tilføjet random bogstaver ind i den genererede sikkerhedskode og det hele funger nu.

Det lader ikke til at DeeDawg ville have points så jeg lukker bare tråden. Tak for hjælpen
Avatar billede olebole Juniormester
09. august 2012 - 02:02 #23
Hvis du også har bogstaver med, kan du evt. bruge denne:

$loginID = md5(microtime(true));
Avatar billede langkiller Nybegynder
09. august 2012 - 02:17 #24
nåå ja kunne jeg selvfølgelig også.. microtime er vel så tidspunktet i microsekunder ?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester