Vinnaren i pepparkakshustävlingen!
2020-10-08, 11:58
  #13
Medlem
Ontogeness avatar
Citat:
Ursprungligen postat av Koenigsegg
$_GET['error'] skickas till en annan fil i mappen ovanför:
Kod:
header('Location: ../register.php?error=username_2_short'); 

Så frågan är vad betyder. Om det betyder att den visade koden är från en fil så är det ju antagligen där felet ligger, $_GET['error'] skickas aldrig till den filen. (Och ja, att det görs för lite debugging) Om det som visas är kod från både den första filen och register.php så är det nån info som fattas..

JAHAAA, alltså menar du att jag borde skriva något i den här stilen:

Kod:
header('Location: register.inc.php?error=empty_fields'); 

Nej vänta nu fick jag verkligen ett eureka-moment!!!

Min header()-funktion skickar tillbaka användaren till register.php, medan mitt switch statement fanns inuti register.inc.php, vilket innebär att mitt switch statement uppenbarligen inte exekveras då koden i register.inc.php enbart körs när använder klickar på knappen för att registrera användaren. Lösningen borde i sådana fall vara att öppna upp ett par PHP-taggar inuti register.php och ha mitt switch statement där ?
Citera
2020-10-08, 12:47
  #14
Medlem
(Puh. Det där var mycket på en gång!)

Jag skulle säga att du kan ha din switch var som helst egentligen. *Men*, du måste ha riktig koll på vilken kod som faktiskt körs vid varje steg:
- När formuläret laddas
- När formuläret skickas in
- När koden som tog emot formuläret kanske skickar vidare(din header()-sats) nånstans med ett felmeddelande

Min känsla är att du inte riktigt fått ihop den biten. Designen av koden, om du vill kalla det så.

Om formuläret(action-attributet) pekar på samma fil som du surfade till när du laddade själva formuläret så visst, då kan du ha switch-satsen i den filen(för den är ju en del av processningen/valideringen av det inskickade formuläret). Om action-attributet pekar nån annanstans.. Då passar switch-satsen antagligen bäst där. Sen kan man ju blanda in includes och liknande, och kanske ha switchen i nån av de filerna. Då har man liksom ett "lager" till att leka med .

Men hoppas att poängen gick fram: Koden kan se ut ungefär hur som helst. Det viktiga är att du som skriver koden har koll på hur "vägarna" ska gå, vad den ska kunna göra, och därefter placerar all kod som behövs längs med varje "väg".
Citera
2020-10-08, 13:03
  #15
Medlem
Ontogeness avatar
Ontogenes har äntligen kommit fram till en lösning!

Jag öppnade upp ett par PHP-taggar i dokumentet register.php (där HTML-formuläret för användarregistreringen finns) och skrev ett switch statement där. Fy fan vad skönt att lösa detta bugg!

Nu ser det ut såhär:

https://gyazo.com/7d3745a6bc8747dd27f26bc7aee92a02

Och här är koden som nu äntligen fungerar:

https://gyazo.com/7d3745a6bc8747dd27f26bc7aee92a02

Nu återstår bara att lösa felmeddelandet jag får som ni ser på den första bilden. Jag ska ta till mig era råd och försöka debugga detta på egen hand, och kommer bara be om hjälp i tråden om jag verkligen inte kommer någonvart.

Tack allihopa för era svar

Och just det, varför det står "unkown error" är bara för att jag inte klickade på knappen för att skicka formuläret, således triggades min default inuti min switch. Detta är ju ytterligare ett bugg egentligen då $_GET['error'] inte har ett värde förräns jag klickar på knappen, men även detta ska jag försöka debugga på egen hand och skriver bara här om jag mot förmodan stöter på patrull!
Citera
2020-10-08, 13:22
  #16
Medlem
NaZdravis avatar
Citat:
Ursprungligen postat av Ontogenes
Ontogenes har äntligen kommit fram till en lösning!

Jag öppnade upp ett par PHP-taggar i dokumentet register.php (där HTML-formuläret för användarregistreringen finns) och skrev ett switch statement där. Fy fan vad skönt att lösa detta bugg!

Nu ser det ut såhär:

https://gyazo.com/7d3745a6bc8747dd27f26bc7aee92a02

Och här är koden som nu äntligen fungerar:

https://gyazo.com/7d3745a6bc8747dd27f26bc7aee92a02

Nu återstår bara att lösa felmeddelandet jag får som ni ser på den första bilden. Jag ska ta till mig era råd och försöka debugga detta på egen hand, och kommer bara be om hjälp i tråden om jag verkligen inte kommer någonvart.

Tack allihopa för era svar

Och just det, varför det står "unkown error" är bara för att jag inte klickade på knappen för att skicka formuläret, således triggades min default inuti min switch. Detta är ju ytterligare ett bugg egentligen då $_GET['error'] inte har ett värde förräns jag klickar på knappen, men även detta ska jag försöka debugga på egen hand och skriver bara här om jag mot förmodan stöter på patrull!
Är ju bara att kolla ifall error "isset".
Citera
2020-10-08, 22:07
  #17
Medlem
Var en massa år sen jag programmerade php så är inte riktigt rätt person att uttala mig. Men du ska kunna debugga på så vis att du kör rad för rad med möjlighet att inspektera variablerna för varje steg.

Rekommenderar att du googlar "debug php".

Alternativt kan man komma långt med att bara logga till konsollen för att få en bild av vad som händer.

Orkar tyvärr inte analysera din kod något djupare, men att kunna köra debug är mer eller mindre ett måste, så tycker verkligen du ska kolla upp det närmare!
Citera
2020-10-10, 17:17
  #18
Medlem
Googla på "xdebug php", even. Det är en extension i PHP som nog kan kallas standardmetod för debugging. Den kan även göra annat väldigt intressant, som profilering.

Om du sen har ett IDE med bra funktionalitet för debugging, så att du kan utnyttja xdebug fullt ut(xdebug pratar med ditt IDE under debuggingen), då är du hemma .
Citera
2020-10-12, 00:12
  #19
Medlem
Ontogeness avatar
Tack för allas era svar! Jag har läst dem men jag orkar inte citera och svara på samtliga inlägg separat. Jag har även suttit och försökt lista ut saker på egen hand och med hjälp av Google, och för tillfället så har jag mitt switch statement inuti register.php (där HTML-formuläret finnes). För nuvarande så fungerar enbart min första error handler, det vill säga "error=empty_fields", vilket visar korrekt felmeddelande precis som sig bör.

Nu till ett alldeles nytt problem istället...

Förvisso fungerar min första error handler till 100%, men vid alla de övriga error handlers så visas alltid felmeddelandet "Please fill in all input fields." trots att det istället för "error=empty_fields" står t.ex. "error=passwords_not_matching". Att registrera en användare utan att trigga något felmeddelande fungerar dock korrekt.

register.php

Kod:
<!DOCTYPE html>

<html lang="en">

<head>
    <title>Register an account</title>
    <meta charset="UTF-8">
    <link rel="stylesheet" type="text/css" href="registerstyle.css">
</head>

<body>
    <div class="container">
        <h2>Register an account</h2>
        <form action="includes/register.inc.php" method="post">
            <input type="text" placeholder="Enter desired username..." name="username"><br>
            <input type="password" placeholder="Enter desired password..." name="password"><br>
            <input type="password" placeholder="Repeat desired password..." name="rePassword">
            <div class="container2"><button type="submit" name="registerButton">Register</button></div>
        </form>
    </div>

    <?php

    
switch(isset($_GET['error'])) {

        case 
'empty_fields':
        echo 
'<div class="error"><p>Please fill in all input fields.</p></div>';
        break;

        case 
'username_2_short':
        echo 
'<div class="error"><p>Your username is too short (minimum username length - 6 characters).</p></div>';
        break;

        case 
'username_2_long':
        echo 
'<div class="error"><p>Your username is too long (maximum username length - 15 characters).</p></div>';
        break;

        case 
'password_2_short':
        echo 
'<div class="error"><p>Your password is too short (minimum password length - 9 characters).</p></div>';
        break;

        case 
'passwords_not_matching':
        echo 
'<div class="error"><p>Your passwords does not match.</p></div>';
        break;

        case 
'username_taken':
        echo 
'<div class="error"><p>The username ' $username ' is already taken.</p></div>';
        break;

    }

    
?>

</body>

</html>

register.inc.php

Kod:
<?php

if(isset($_POST['registerButton'])) {

    require 
'dbh.inc.php';

    
$username $_POST['username'];
    
$password $_POST['password'];
    
$rePassword $_POST['rePassword'];

    if(empty(
$username) || empty($password) || empty($rePassword)) {
        
header('Location: ../register.php?error=empty_fields');
        exit();
    }

    else if(
strlen($username) < 6) {
        
header('Location: ../register.php?error=username_2_short');
        exit();
    }

    else if(
strlen($username) > 15) {
        
header('Location: ../register.php?error=username_2_long');
        exit();
    }

    else if(
strlen($password) < 9) {
        
header('Location: ../register.php?error=password_2_short');
        exit();
    }

    else if(
$password !== $rePassword) {
        
header('Location: ../register.php?error=passwords_not_matching');
        exit();
    }

    else {

        
$sql "SELECT username FROM users WHERE username=?";
        
$stmt mysqli_stmt_init($conn);

        if(!
mysqli_stmt_prepare($stmt$sql)) {
            
header('Location: ../register.php?error=sql_error');
            exit();
        }

        else {

            
mysqli_stmt_bind_param($stmt's'$username);
            
mysqli_stmt_execute($stmt);
            
mysqli_stmt_store_result($stmt);

            
$resultCheck mysqli_stmt_num_rows($stmt);

            if(
$resultCheck 0) {
                
header('Location: ../register.php?error=username_taken');
                exit();
            }

            else {

                
$sql "INSERT INTO users (username, password) VALUES (?, ?)";
                
$stmt mysqli_stmt_init($conn);

                if(!
mysqli_stmt_prepare($stmt$sql)) {
                    
header('Location: ../register.php?error=sql_error');
                    exit();
                }

                else {

                    
$hashedPassword password_hash($passwordPASSWORD_DEFAULT);

                    
mysqli_stmt_bind_param($stmt'ss'$username$hashedPassword);
                    
mysqli_stmt_execute($stmt);
                    
                    
header('Location: ../register.php?register=success');
                    exit();

                }

            }

        }

    }

    
mysqli_stmt_close($stmt);
    
mysqli_close($conn);

}

else {
    
header('Location: ../index.php');
    exit();
}

Jag vet inte riktigt hur jag ska debugga detta och enligt mig så ser allting ut som det ska i koden. Någon som har koll på vad det kan vara som ställer till det för mig?
Citera
2020-10-12, 00:21
  #20
Medlem
Citat:
Ursprungligen postat av Ontogenes
Tack för allas era svar! Jag har läst dem men jag orkar inte citera och svara på samtliga inlägg separat. Jag har även suttit och försökt lista ut saker på egen hand och med hjälp av Google, och för tillfället så har jag mitt switch statement inuti register.php (där HTML-formuläret finnes). För nuvarande så fungerar enbart min första error handler, det vill säga "error=empty_fields", vilket visar korrekt felmeddelande precis som sig bör.

Nu till ett alldeles nytt problem istället...

Förvisso fungerar min första error handler till 100%, men vid alla de övriga error handlers så visas alltid felmeddelandet "Please fill in all input fields." trots att det istället för "error=empty_fields" står t.ex. "error=passwords_not_matching". Att registrera en användare utan att trigga något felmeddelande fungerar dock korrekt.

register.php

Kod:
<!DOCTYPE html>

<html lang="en">

<head>
    <title>Register an account</title>
    <meta charset="UTF-8">
    <link rel="stylesheet" type="text/css" href="registerstyle.css">
</head>

<body>
    <div class="container">
        <h2>Register an account</h2>
        <form action="includes/register.inc.php" method="post">
            <input type="text" placeholder="Enter desired username..." name="username"><br>
            <input type="password" placeholder="Enter desired password..." name="password"><br>
            <input type="password" placeholder="Repeat desired password..." name="rePassword">
            <div class="container2"><button type="submit" name="registerButton">Register</button></div>
        </form>
    </div>

    <?php

    
switch(isset($_GET['error'])) {

        case 
'empty_fields':
        echo 
'<div class="error"><p>Please fill in all input fields.</p></div>';
        break;

        case 
'username_2_short':
        echo 
'<div class="error"><p>Your username is too short (minimum username length - 6 characters).</p></div>';
        break;

        case 
'username_2_long':
        echo 
'<div class="error"><p>Your username is too long (maximum username length - 15 characters).</p></div>';
        break;

        case 
'password_2_short':
        echo 
'<div class="error"><p>Your password is too short (minimum password length - 9 characters).</p></div>';
        break;

        case 
'passwords_not_matching':
        echo 
'<div class="error"><p>Your passwords does not match.</p></div>';
        break;

        case 
'username_taken':
        echo 
'<div class="error"><p>The username ' $username ' is already taken.</p></div>';
        break;

    }

    
?>

</body>

</html>

register.inc.php

Kod:
<?php

if(isset($_POST['registerButton'])) {

    require 
'dbh.inc.php';

    
$username $_POST['username'];
    
$password $_POST['password'];
    
$rePassword $_POST['rePassword'];

    if(empty(
$username) || empty($password) || empty($rePassword)) {
        
header('Location: ../register.php?error=empty_fields');
        exit();
    }

    else if(
strlen($username) < 6) {
        
header('Location: ../register.php?error=username_2_short');
        exit();
    }

    else if(
strlen($username) > 15) {
        
header('Location: ../register.php?error=username_2_long');
        exit();
    }

    else if(
strlen($password) < 9) {
        
header('Location: ../register.php?error=password_2_short');
        exit();
    }

    else if(
$password !== $rePassword) {
        
header('Location: ../register.php?error=passwords_not_matching');
        exit();
    }

    else {

        
$sql "SELECT username FROM users WHERE username=?";
        
$stmt mysqli_stmt_init($conn);

        if(!
mysqli_stmt_prepare($stmt$sql)) {
            
header('Location: ../register.php?error=sql_error');
            exit();
        }

        else {

            
mysqli_stmt_bind_param($stmt's'$username);
            
mysqli_stmt_execute($stmt);
            
mysqli_stmt_store_result($stmt);

            
$resultCheck mysqli_stmt_num_rows($stmt);

            if(
$resultCheck 0) {
                
header('Location: ../register.php?error=username_taken');
                exit();
            }

            else {

                
$sql "INSERT INTO users (username, password) VALUES (?, ?)";
                
$stmt mysqli_stmt_init($conn);

                if(!
mysqli_stmt_prepare($stmt$sql)) {
                    
header('Location: ../register.php?error=sql_error');
                    exit();
                }

                else {

                    
$hashedPassword password_hash($passwordPASSWORD_DEFAULT);

                    
mysqli_stmt_bind_param($stmt'ss'$username$hashedPassword);
                    
mysqli_stmt_execute($stmt);
                    
                    
header('Location: ../register.php?register=success');
                    exit();

                }

            }

        }

    }

    
mysqli_stmt_close($stmt);
    
mysqli_close($conn);

}

else {
    
header('Location: ../index.php');
    exit();
}

Jag vet inte riktigt hur jag ska debugga detta och enligt mig så ser allting ut som det ska i koden. Någon som har koll på vad det kan vara som ställer till det för mig?

Den här raden kommer alltid att ge samma resultat:

switch(isset($_GET['error'])

Funktionen isset berättar om det finns något där eller inte, och om du rapporterar något fel alls kommer detta alltid att ge samma effekt.
Citera
2020-10-12, 13:09
  #21
Medlem
Som sagts ovan:
Kod:
switch(isset(...)) 
"gör en switch" om huruvida variabeln är satt eller inte.

switch tittar på det mellan parenteserna, och i det här fallet så är det isset(). Isset() returnerar en bool, true om variabeln finns, false annars. $_GET['error'] finns i det här fallet, så koden blir
Kod:
switch(true) { 
. Det är strängar i case-satserna under, så det borde väl aldrig kunna matcha varann, eller hur? Fel. Men det kändes så rätt tidigt, eller hur ..

switch gör inte en strikt jämförelse(===) utan (==), så då omvandlar PHP värdena i case-satserna till samma typ som i switch(...). Och nu kan man kanske börja känna vad man får om man omvandlar en sträng(inte den tomma strängen) till en bool? Just det, true.
Kod:
php var_dump((bool) '');
bool(false)
php var_dump((bool) 'empty_fields');
bool(true
(Det blir samma för alla strängar i case-satserna, dvs true.)

Så switch-satsen får true att leta efter, av isset(). Och det blir träff direkt, på första "string-caset".
Citera
2020-10-12, 13:30
  #22
Medlem
Förresten, ett tips: det är ganska irriterande att fylla i ett formulär fel, och få veta om felen, ett fel i taget. Jag rekommenderar att du använder tex flaggor för att meddela användaren vilka fel som denne begått.

I detta sammanhang är flaggor en variabel som du använder för att kommunicera flera olika saker. Gemensamt för alla är att de kan vara antingen sanna eller falska, inget annat. I detta fall är det information om vilka fält som fyllts i som är det relevanta. Det kan se ut ungefär så här (jag gör inga anspråk på att koden är rätt, utan bara visar på principen):

I koden som tar hand om datan från formuläret:
- sätt flagga till noll
- kolla namnfältet, är det rätt ifyllt? Om ja, gå vidare, annars sätt flagga till flagga||1
- kolla emailfältet, är det rätt ifyllt? Om ja, gå vidare, annars sätt flagga till flagga||2
- kolla adressfältet, är det rätt ifyllt? Om ja, gå vidare, annars sätt flagga till flagga||4
- kolla telefonnummerfältet, är det rätt ifyllt? Om ja, gå vidare, annars sätt flagga till flagga||8
- och så vidare....
- när alla fält är kollade så kontrollera om flagga==0: om ja gå vidare med bearbetningen av formulärdatat, annars skicka tillbaka formuläret med flagga

Sedan i den kod som skriver ut formuläret:
- är flagga&&1!=0? Om ja (dvs något fel sedan tidigare försök att fylla i) skriv ut ett felmeddelande och skriv sedan ut formulärrutan
- är flagga&&2!=0? Om ja (dvs något fel sedan tidigare försök att fylla i) skriv ut ett felmeddelande och skriv sedan ut formulärrutan
- är flagga&&4!=0? Om ja (dvs något fel sedan tidigare försök att fylla i) skriv ut ett felmeddelande och skriv sedan ut formulärrutan
- är flagga&&8!=0? Om ja (dvs något fel sedan tidigare försök att fylla i) skriv ut ett felmeddelande och skriv sedan ut formulärrutan

Observera mönstret som återkommer i båda fallen: för varje nytt fält multipliceras en konstant (1, 2, 4, 8) med två. Detta medför att flaggan är en enda bit i binärtalet, och om den sätts till 1 skall det tolkas som ett fel.

Du kan på det viset gå igenom hela formuläret en enda gång, och upptäcka alla felen på en gång.
Citera
2020-10-12, 13:40
  #23
Medlem
Citat:
Ursprungligen postat av xpqr12345
Sedan i den kod som skriver ut formuläret:
- är flagga&&1!=0? Om ja (dvs något fel sedan tidigare försök att fylla i) skriv ut ett felmeddelande och skriv sedan ut formulärrutan
- är flagga&&2!=0? Om ja (dvs något fel sedan tidigare försök att fylla i) skriv ut ett felmeddelande och skriv sedan ut formulärrutan
- är flagga&&4!=0? Om ja (dvs något fel sedan tidigare försök att fylla i) skriv ut ett felmeddelande och skriv sedan ut formulärrutan
- är flagga&&8!=0? Om ja (dvs något fel sedan tidigare försök att fylla i) skriv ut ett felmeddelande och skriv sedan ut formulärrutan
(Jag vet att du skrev om principen, så det här är mest ett tillägg)
Det är nog bäst med bitvis AND istället för logisk(det är ett bitfält after all), & istället för &&. Annars så blir det fel .
Citera
2020-10-12, 13:42
  #24
Medlem
Citat:
Ursprungligen postat av Koenigsegg
(Jag vet att du skrev om principen, så det här är mest ett tillägg)
Det är nog bäst med bitvis AND istället för logisk(det är ett bitfält after all), & istället för &&. Annars så blir det fel .

Absolut, jag kan bara inte hålla isär & och &&, repektive | och ||.
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback