Vinnaren i pepparkakshustävlingen!
  • 1
  • 2
2021-08-29, 00:13
  #1
Medlem
ididntdrowns avatar
Hej! Jag håller på att koda ett simpelt inloggningssystem i PHP där man kan registrera sig med ett användarnamn + lösenord, och sedan logga in förutsatt att den inmatade datan följer vissa riktlinjer (t.ex. att användarnamnet enbart får innehålla siffror och bokstäver, samt att man inte kan registrera sig med ett användarnamn som redan är taget).

Jag har hittills bara kodat registreringsdelen och har stött på några problem. Jag har ett .php-dokument med error handlers som exekverar diverse funktioner, och funktionerna återfinns i ett separat .php-dokument. Koden ser ut såhär:

Kod:
<?php

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

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

    require_once 
'dbh.inc.php';
    require_once 
'functions.inc.php';

    if(
emptyInputFields($username$password$rePassword)) {
        
header('location: ../register.php?error=empty_input');
        exit();
    }

    if(
username2short($username)) {
        
header('location: ../register.php?error=username2short');
        exit();
    }

    if(
username2long($username)) {
        
header('location: ../register.php?error=username2long');
        exit();
    }

    if(
invalidUsername($username)) {
        
header('location: ../register.php?error=invalid_username');
        exit();
    }

    if(
password2short($password)) {
        
header('location: ../register.php?error=password2short');
        exit();
    }

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

    if(
usernameTaken($conn$username)) {
        
header('location: ../register.php?error=username_taken');
        exit();
    }

    
createUser($conn$username$password);

}

else {
    
header('location: ../register.php');
    exit();
}

Kod:
<?php

function emptyInputFields($username$password$rePassword) {

    
$result;

    if(empty(
$username) || empty($password) || empty($rePassword)) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
username2short($username) {

    
$result;

    if(
strlen($username) < 6) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
username2long($username) {

    
$result;

    if(
strlen($username 12)) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
invalidUsername($username) {

    
$result;

    if(!
preg_match("/^[a-zA-Z0-9]*$/"), $username) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
password2short($password) {

    
$result;

    if(
strlen($password) < 8) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
passwordsNotMatching($password$rePassword) {

    
$result;

    if(
$password !== $rePassword) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
usernameTaken($conn$username) {

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

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

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

    
$resultData mysqli_stmt_get_result($stmt);

    if(
$row mysqli_fetch_assoc($resultData)) {
        return 
$row;
    }

    else {
        
$result false;
        return 
$result;
    }

    
mysqli_stmt_close($stmt);

}

function 
createUser($conn$username$password) {

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

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

    
$hashedPassword password_hash($passwordPASSWORD_DEFAULT);

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

}

Det första problemet jag stöter på är ett felmeddelande (när jag klickar på "registrera") som hänvisar till ett ","-tecken som finns på rad 55, där det tydligen inte ska finnas. Detta ","-tecken återfinns alltså i funktionen invalidUsername() där kommatecknet separerar preg_match-funktionen och variabeln $username, och jag förstår inte riktigt varför jag får ett parse error för detta då ju kommatecknet visst ska finnas där för att separera funktionens parametrar, så om någon kan hjälpa mig lista ut vad detta beror på så vore det nice.

Jag har kommenterat ut funktionen invalidUsername() för att testa de resterande error handlers som finns, men resultatet blir att enbart den första error handlern exekveras oavsett resultat, dvs även om alla inmatningsfält är ifyllda så returnerar funktionen emptyInputFields() true. Jag har testat samtliga kombinationer av ifylld data som skulle kunnat trigga samtliga error handlers men emptyInputFields() är det enda som körs, även när den inte skall göra det.

Om någon har några tips på hur jag kan ta mig vidare samt även tips på hur man debuggar (för jag har ingen riktig strategi för det) så tas detta tacksamt emot
Citera
2021-08-29, 00:38
  #2
Medlem
Du ska nog ha $username i preg_match-parentesen.

preg_match($pattern, $str);
Citera
2021-08-29, 00:41
  #3
Medlem
Citat:
Ursprungligen postat av ididntdrown
Hej! Jag håller på att koda ett simpelt inloggningssystem i PHP där man kan registrera sig med ett användarnamn + lösenord, och sedan logga in förutsatt att den inmatade datan följer vissa riktlinjer (t.ex. att användarnamnet enbart får innehålla siffror och bokstäver, samt att man inte kan registrera sig med ett användarnamn som redan är taget).

Jag har hittills bara kodat registreringsdelen och har stött på några problem. Jag har ett .php-dokument med error handlers som exekverar diverse funktioner, och funktionerna återfinns i ett separat .php-dokument. Koden ser ut såhär:

Kod:
<?php

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

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

    require_once 
'dbh.inc.php';
    require_once 
'functions.inc.php';

    if(
emptyInputFields($username$password$rePassword)) {
        
header('location: ../register.php?error=empty_input');
        exit();
    }

    if(
username2short($username)) {
        
header('location: ../register.php?error=username2short');
        exit();
    }

    if(
username2long($username)) {
        
header('location: ../register.php?error=username2long');
        exit();
    }

    if(
invalidUsername($username)) {
        
header('location: ../register.php?error=invalid_username');
        exit();
    }

    if(
password2short($password)) {
        
header('location: ../register.php?error=password2short');
        exit();
    }

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

    if(
usernameTaken($conn$username)) {
        
header('location: ../register.php?error=username_taken');
        exit();
    }

    
createUser($conn$username$password);

}

else {
    
header('location: ../register.php');
    exit();
}

Kod:
<?php

function emptyInputFields($username$password$rePassword) {

    
$result;

    if(empty(
$username) || empty($password) || empty($rePassword)) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
username2short($username) {

    
$result;

    if(
strlen($username) < 6) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
username2long($username) {

    
$result;

    if(
strlen($username 12)) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
invalidUsername($username) {

    
$result;

    if(!
preg_match("/^[a-zA-Z0-9]*$/"), $username) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
password2short($password) {

    
$result;

    if(
strlen($password) < 8) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
passwordsNotMatching($password$rePassword) {

    
$result;

    if(
$password !== $rePassword) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;

}

function 
usernameTaken($conn$username) {

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

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

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

    
$resultData mysqli_stmt_get_result($stmt);

    if(
$row mysqli_fetch_assoc($resultData)) {
        return 
$row;
    }

    else {
        
$result false;
        return 
$result;
    }

    
mysqli_stmt_close($stmt);

}

function 
createUser($conn$username$password) {

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

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

    
$hashedPassword password_hash($passwordPASSWORD_DEFAULT);

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

}

Det första problemet jag stöter på är ett felmeddelande (när jag klickar på "registrera") som hänvisar till ett ","-tecken som finns på rad 55, där det tydligen inte ska finnas. Detta ","-tecken återfinns alltså i funktionen invalidUsername() där kommatecknet separerar preg_match-funktionen och variabeln $username, och jag förstår inte riktigt varför jag får ett parse error för detta då ju kommatecknet visst ska finnas där för att separera funktionens parametrar, så om någon kan hjälpa mig lista ut vad detta beror på så vore det nice.

Jag har kommenterat ut funktionen invalidUsername() för att testa de resterande error handlers som finns, men resultatet blir att enbart den första error handlern exekveras oavsett resultat, dvs även om alla inmatningsfält är ifyllda så returnerar funktionen emptyInputFields() true. Jag har testat samtliga kombinationer av ifylld data som skulle kunnat trigga samtliga error handlers men emptyInputFields() är det enda som körs, även när den inte skall göra det.

Om någon har några tips på hur jag kan ta mig vidare samt även tips på hur man debuggar (för jag har ingen riktig strategi för det) så tas detta tacksamt emot

Du ska inte ha en slutparantes innan kommat.
Citera
2021-08-29, 01:10
  #4
Medlem
ididntdrowns avatar
Citat:
Ursprungligen postat av do-ob
Du ska nog ha $username i preg_match-parentesen.

preg_match($pattern, $str);

Citat:
Ursprungligen postat av Disputator
Du ska inte ha en slutparantes innan kommat.

Oj, är lite trött verkar det som hehe. Tack!
Citera
2021-08-29, 10:30
  #5
Medlem
ididntdrowns avatar
Är det någon som vet varför emptyInputFields() är den enda error handlern som triggas, samt varför den gör det även när inmatingsfälten inte är tomma?
Citera
2021-08-29, 20:34
  #6
Medlem
Enterprises avatar
Citat:
Ursprungligen postat av ididntdrown
Är det någon som vet varför emptyInputFields() är den enda error handlern som triggas, samt varför den gör det även när inmatingsfälten inte är tomma?
Har du dubbelkollat att $_post-variablerna som du kör in som argument i funktionen inte är tomma?
Alltså att HTML-formuläret har rätt namn på input-fälten som ska rendera $_post-variablerna.

Jag kontrollkörde din funktion emptyInputFields() genom https://sandbox.onlinephpfunctions.com/ och funktionen returnerar som förväntat false när argumenten inte är tomma. Den returnerar true när minst ett av argumenten är tomma, så det är inte funktionen det är fel på.

Edit:
Att debugga i PHP är ofta lite knepigare än i andra språk, men ett tips är att sätta på alla varningar och felkoder (så att du förhoppningsvis inte bara får en blank skärm).

Tips 1 - kör koden i PHP syntax checker (https://phpcodechecker.com/)
Tips 2 - om du får en felkod med radnummer är det bara att utgå från den raden och kolla vad som går fel. Använd gärna var_dump() på alla variabler som används i sammanhanget.
Tips 3 - om du inte får en felkod eller av annan orsak inte vet var felet inträffar i koden så kan du sätta in echo/var_dump vid strategiska ställen (numrera gärna så är det enkelt att hitta) för att upptäcka var koden kraschar. Ibland sätter jag också in exit efter var_dump för att inte koden ska köra vidare "okontrollerat". Sedan när man märker att var_dump/echo ger förväntad output så tar man bort exit och kör en gång till. Man får leta sig fram.
__________________
Senast redigerad av Enterprise 2021-08-29 kl. 20:47.
Citera
2021-08-30, 11:16
  #7
Medlem
Citat:
Ursprungligen postat av Enterprise
Att debugga i PHP är ofta lite knepigare än i andra språk,

Varför skulle det vara knepigare?

Citat:
Ursprungligen postat av Enterprise
Tips 1 - kör koden i PHP syntax checker (https://phpcodechecker.com/)
Eller så installerar man en kod-editor värd namnet som markerar syntax-fel medan man skriver koden.

Citat:
Ursprungligen postat av Enterprise
Tips 2 - om du får en felkod med radnummer är det bara att utgå från den raden och kolla vad som går fel. Använd gärna var_dump() på alla variabler som används i sammanhanget.
Tips 3 - om du inte får en felkod eller av annan orsak inte vet var felet inträffar i koden så kan du sätta in echo/var_dump vid strategiska ställen (numrera gärna så är det enkelt att hitta) för att upptäcka var koden kraschar. Ibland sätter jag också in exit efter var_dump för att inte koden ska köra vidare "okontrollerat". Sedan när man märker att var_dump/echo ger förväntad output så tar man bort exit och kör en gång till. Man får leta sig fram.
Debug-utskrifter går att använda, men de är en sista utväg. Jag skulle alla gånger rekommendera att installera en utvecklingsmiljö så att du kan debugga på riktigt istället.
Citera
2021-08-30, 12:28
  #8
Medlem
Citat:
Ursprungligen postat av ididntdrown
Kod:
function emptyInputFields($username$password$rePassword) {

    
$result;

    if(empty(
$username) || empty($password) || empty($rePassword)) {
        
$result true;
    }

    else {
        
$result false;
    }

    return 
$result;


Du får ganska mycket överflödig kod när du skriver funktioner sådär, deklarera variabler, en if-sats där du bestämmer vad funktionen ska returnera och spara det värdet i en variabel och sen returnera den variabeln. Om du tittar på funktionen så inser du att det boolska värdet som den returnerar helt enkelt är
Kod:
empty($username) || empty($password) || empty($rePassword

..så din funktion skulle helt enkelt kunna vara
Kod:
function emptyInputFields($username$password$rePassword) : bool {
    return empty(
$username) || empty($password) || empty($rePassword);

..skrivet med lite mera modern PHP-syntax och definierad return-typ.

Alltid najs med mindre kod att skriva :-)=..
Citera
2021-08-30, 12:42
  #9
Medlem
Enterprises avatar
Citat:
Ursprungligen postat av Koenigsegg
Varför skulle det vara knepigare?

Debug-utskrifter går att använda, men de är en sista utväg. Jag skulle alla gånger rekommendera att installera en utvecklingsmiljö så att du kan debugga på riktigt istället.

Eftersom, det precis som du skriver, krävs en särskild utvecklingsmiljö för att debugga på riktigt (jämför med JS där det går utmärkt att debugga direkt i browsern).
Om man kör direkt mot servern och särskilt om man sitter på någon form av hosting-server (där du kanske inte ens kommer åt SSH) så är det givetvis knepigare att debugga.

Bra tips om att köra IDE med syntax checker/linter.
__________________
Senast redigerad av Enterprise 2021-08-30 kl. 12:44.
Citera
2021-08-30, 14:08
  #10
Medlem
Citat:
Ursprungligen postat av Enterprise
Eftersom, det precis som du skriver, krävs en särskild utvecklingsmiljö för att debugga på riktigt (jämför med JS där det går utmärkt att debugga direkt i browsern).
Det är ju inga jättesaker det handlar om. Installera ett tillägg - man kan kanske tycka spontant att det borde vara en del av PHP, men å andra sidan behöver man ju sällan debug-möjligheter i live-miljö så jag kan köpa att det är ett tillägg - till PHP, konfa debuggern för det.. Done .

Och tillägg är ju knappast en stor grej *host*vs code*hrm*.

Sen har man möjlighet att stega igenom koden, se variablernas innehåll steg för steg... Tröskeln för att få igång det är väl att få inställningarna rätt. Så visst, om man kodar lite på fritiden så kan det kännas närmare till hands med debug-utskrifter för TS.
Citera
2021-08-31, 10:24
  #11
Medlem
Pluginet som det handlar om är alltså xdebug, om nån undrade. Med det konfat och igång så skickar PHP på servern data om vad som händer till en konfad IP-adress/port. Data kan gå åt andra hållet också, så att man kan få PHP på servern att inte köra igenom all kod på en gång utan stega rad för rad. Det finns massor av tutorials om det här förstås, eftersom det är en rätt central del av PHP-utveckling.
Citera
2021-08-31, 19:08
  #12
Medlem
Enterprises avatar
Citat:
Ursprungligen postat av Koenigsegg
Pluginet som det handlar om är alltså xdebug, om nån undrade. Med det konfat och igång så skickar PHP på servern data om vad som händer till en konfad IP-adress/port. Data kan gå åt andra hållet också, så att man kan få PHP på servern att inte köra igenom all kod på en gång utan stega rad för rad. Det finns massor av tutorials om det här förstås, eftersom det är en rätt central del av PHP-utveckling.
Tack, jag ska kolla. Kör egen två egna LAMP-servrar där detta inte ska vara något problem alls, men också några "snik-hostade" servrar genom bl.a. one.com där jag tror det inte blir så lätt. Man har bara begränsad tillgång till SSH bl.a.
Citera
  • 1
  • 2

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