Vinnaren i pepparkakshustävlingen!
  • 3
  • 4
2020-11-22, 22:03
  #37
Medlem
Ontogeness avatar
Citat:
Ursprungligen postat av xpqr12345
Med en switch-sats kommer bara en av vägarna att exekveras, men om du vill kunna rapportera flera fel på en gång duger det inte med en switch. Möjligen kan du använda en rad if-satser, med en sats per fel du vill rapportera.

Edit:
på din andra och alla efterföljande case-sats avslutar du raden med ett semikolon istället för ett kolon.

Nu exekveras koden för tomma inmatningsfält direkt när man laddar webbplatsen och det är det första problemet. Jag ska göra om alla semikolon till vanliga kolon och sen testa att enbart köra mitt switch-statement om användaren har klickat på registreringsknappen för att se om det löser problemet.

Ja alltså jag tänker som så att om man har skrivit in användarnamnet "abc" med lösenordet "123" så är det helt okej att man endast får felmeddelandet "du har ett för kort användarnamn", och skriver man sen in användarnamnet "abcdefgh" med lösenordet "123" så får man nu felmeddelandet "du har ett för kort lösenord", i efterhand så att säga, det är lite så "allvarlighetsgraderna" i felmeddelandena är utplacerade, det vill säga i en viss ordning.
Citera
2020-11-22, 22:14
  #38
Medlem
Ontogeness avatar
Jag fick för mig att ha mitt switch-statement i samma .php-dokument som det med resterande kod, och det ser ut såhär:

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

parse_str($_SERVER['QUERY_STRING'], $result);
print_r($result);

Längst ner så kör jag parse_str($_SERVER['QUERY_STRING'], $result) och försöker skriva ut den associativa array:en med print_r()-funktionen men det lyckas inte, är det någon som vet varför? Jag kan fortfarande få felmeddelanden i URL-rutan... Jag gissar på att koden bara är felplacerad?

EDIT: Det fungerande heller inte att inkludera koden i min isset()-funktion, placerad precis under min require.
Citera
2020-11-22, 22:48
  #39
Medlem
Kommer du åt din webservers felmeddelanden? Där kan det finnas en hel del bra att läsa. Om du inte kommer åt dem så försök köra din kod från kommandoprompten, men det lär kräva att du modifierar den lite, för att passa den annorlunda miljön.
Citera
2020-11-23, 11:36
  #40
Medlem
Ontogeness avatar
Citat:
Ursprungligen postat av xpqr12345
Kommer du åt din webservers felmeddelanden? Där kan det finnas en hel del bra att läsa. Om du inte kommer åt dem så försök köra din kod från kommandoprompten, men det lär kräva att du modifierar den lite, för att passa den annorlunda miljön.

Alltså det jag vill göra är basically att hämta de felmeddelanden som visas i URL-rutan och skriva ut HTML baserat på dessa felmeddelanden. I dokumentet register.php så har jag egentligen bara HTML och all PHP-kod finns i register.inc.php (jag har detta .php-dokument som action-attribut i HTML-formuläret i register.php). Det jag misstänker är att jag placerar min switch-sats på ett sådant sätt att koden överhuvudtaget inte exekveras då jag heller inte får några felmeddelanden (inbyggda PHP-felmeddelanden alltså), och det är detta jag skulle behöva hjälp med (tror jag...).

Här är koden för dokumentet 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();
}

Det som händer (i kronologisk ordning) är att om användaren skickar formuläret så är isset()-funktionen true vilket leder till att följande kod exekveras:

1. Uppkoppling mot databasen (require av databasehandler-dokument)
2. Inmatad data sparas i variabler
3. If-satser som kontrollerar om några fel upptäcks varpå felmeddelande i URL-rutan visas
4. Om inga error handlers triggas så matas inmatad data in i databasen genom prepared statements

Nu sitter jag och funderar över var min utskrivningskod för felmeddelanden ska placeras, och just nu lutar det mest åt att det bör finnas i register.php istället för inuti includes-dokumentet då det av någon anledning känns mest rätt.

Om jag skickar dokumentet utan att fylla i några inmatningsfält så ser mitt URL ut såhär:

Citat:
localhost/PHP Login System/register.php?error=empty_fields

Kod:
parse_str($_SERVER['QUERY_STRING'], $result);
print_r($result); 

Denna kod ger mig följande output: Array([error] => empty_fields)

Och om jag kör echo $result['error'] så är min output "empty_fields". Det känns ju som att detta skulle kunna implementeras i ett switch-statement. Den associativa array:en som genereras av parse_str()-funktionen kommer alltid bara ha ett värde, då koden är skriven på ett sådant sätt att flera felmeddelanden inte kan genereras samtidigt.

Okej vänta, allt detta tänkande verkar nu avlönas, jag är riktigt nära en lösning nu, brb ska testa en sak så återkommer jag strax
Citera
2020-11-23, 11:51
  #41
Medlem
Ontogeness avatar
Nästan en lösning!

Nu fungerar alla felmeddelanden (jag har dock ännu inte testat register=success) med följande kod:

Kod:
<?php

parse_str
($_SERVER['QUERY_STRING'], $result);

switch(
$result['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>That username is already taken.</p></div>';
    break;

}

?>

Problemet är bara det att om man besöker sidan för första gången så finns där givetvis inga felmeddelanden än då använder ännu inte har skickat formuläret, men trots detta så körs ju mitt switch-statement varpå jag får följande felmeddelande:

Notice: Undefined index: error in C:\xampp\htdocs\PHP Login System\register.php on line 27


Rad 27 är alltså den rad där jag initierar min switch-sats och jag antar att felmeddelandet dyker upp för att index "error" i array:en $result ännu inte är definierad. Några tips på hur jag löser detta? Jag tänker att jag kanske kan ha en if-sats innan mitt switch-statement definieras som har i uppgift att kontrollera om den associativa array:en $result innehåller data eller inte. Om den inte innehåller någon data så finns där inget felmeddelande (till exempel när man öppnar register.php för första gången) och om den innehåller data så finns där antingen ett felmeddelande eller "register=success". Jag ska laborera lite, kom gärna med input om ni känner för det
Citera
2020-11-23, 12:59
  #42
Medlem
Citat:
Ursprungligen postat av Ontogenes
[i][b]Problemet är bara det att om man besöker sidan för första gången så finns där givetvis inga felmeddelanden än då använder ännu inte har skickat formuläret....

Vad händer om du bakar in din switch-sats i en ifset($_SERVER['QUERY_STRING']) ? Om det inte heter ifset så något liknande, som kollar om det du frågar efter finns eller inte.
Citera
2020-11-23, 13:22
  #43
Medlem
Ontogeness avatar
Citat:
Ursprungligen postat av xpqr12345
Vad händer om du bakar in din switch-sats i en ifset($_SERVER['QUERY_STRING']) ? Om det inte heter ifset så något liknande, som kollar om det du frågar efter finns eller inte.

Där sa du något. Du tänker nog på en isset()-funktion men oavsett så tror jag att jag fattar vad du menar, ska kika på det, tack för svar
Citera
2020-11-23, 13:28
  #44
Medlem
Sen är där två saker jag tycket du bör göra:
- till att börja med bör du rapportera alla fel på en gång, så som jag skrev om tidigare i tråden. Det är grymt irriterande att inte få alla fel rapporterade på en gång.
- sen bör du skicka med den info som användaren fyllt i första gången han/hon fyllde i formuläret, så han/hon inte behöver börja om från början.
Citera
2020-11-23, 13:46
  #45
Medlem
Citat:
Ursprungligen postat av Ontogenes
Rad 27 är alltså den rad där jag initierar min switch-sats och jag antar att felmeddelandet dyker upp för att index "error" i array:en $result ännu inte är definierad. Några tips på hur jag löser detta? Jag tänker att jag kanske kan ha en if-sats innan mitt switch-statement definieras som har i uppgift att kontrollera om den associativa array:en $result innehåller data eller inte.
Nåt i stil med detta?
Kod:
if (isset($_GET['success'])) {
    
// Processa ett lyckat anrop...
}
else if (isset(
$_GET['error'])) {
    switch(
$_GET['error']) {
        case 
'empty_fields':
            ...
    }
}
else {
    
// ...?


Det var onödigt av mig att blanda in parse_str(). Det är en användbar och intressant funktion, men i det här fallet så tror jag inte att den behövs.

Som andra sagt så går en switch-sats igenom ett av fallen. Å andra sidan så gör det väl antagligen ingenting här, eftersom $_GET['error'] är en string om den finns. Om $_GET['error'] var en array så skulle foreach() antagligen passa bäst, som också sagts tidigare.
Citera
2020-11-23, 14:43
  #46
Medlem
Ontogeness avatar
Citat:
Ursprungligen postat av Koenigsegg
Nåt i stil med detta?
Kod:
if (isset($_GET['success'])) {
    
// Processa ett lyckat anrop...
}
else if (isset(
$_GET['error'])) {
    switch(
$_GET['error']) {
        case 
'empty_fields':
            ...
    }
}
else {
    
// ...?


Det var onödigt av mig att blanda in parse_str(). Det är en användbar och intressant funktion, men i det här fallet så tror jag inte att den behövs.

Som andra sagt så går en switch-sats igenom ett av fallen. Å andra sidan så gör det väl antagligen ingenting här, eftersom $_GET['error'] är en string om den finns. Om $_GET['error'] var en array så skulle foreach() antagligen passa bäst, som också sagts tidigare.

Äh, nu kan jag ytterligare en funktion tack vare dig så det är ju inte helt i onödan

Tack så hemskt mycket, nu fungerar det som smort! Nu är hela registreringsförloppet komplett, så nu är det dags att koda inloggningsscriptet!
Citera
  • 3
  • 4

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