Powielony INSERT / INPUT

Powielony INSERT / INPUT
Filip Czeszka
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 4
0

Witam ponownie.

Przychodzę z kolejnym problemem, a mianowicie: wstawianie do bazy danych z formularza HTML przez PHP działa, jednak... gdy odświeżę stronę wstawia się jeszcze raz, czego nie chcę.

Oto kod:

Kopiuj
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title> Autoprezentacja | Filip Czeszka </title>
    <link rel="stylesheet" href="ap.css">
</head>
<body>

<?php

session_start();

?>

<header> 
    <div id="lewy"> 
        <h1> Filip Czeszka </h1>
    </div>

    <div id="prawy">
        <img src="zdjecie.JPG" alt="zdjęcie">
    </div>
</header>

<main id="opis"> 



</main>

<div id="pasek"> 

<div id="zaint">

    <h2> Zainteresowania </h2>
<ul>
    
<?php

    $_SESSION['select'] = 'true';

?>
<?php

if($_SESSION['select'] = 'true') {


$db = new mysqli('localhost', 'root', '', 'apf');
$query = $db->prepare("SELECT tekst FROM info");
$query->execute();
$result = $query->get_result();
while($row = $result->fetch_assoc()) {

    echo "<div id=\"pasek\">";
    $z1 = $row['tekst'];
    echo "<li><h3> $z1 </h3></li> <br \>";
  
}  
    
} 

?>

</ul>

</div> <br><br><br><br>

<div id="insert">

    <h2> Podaj zainteresowanie </h2>

    <form action="" method="get"> 
    <input type="text" name="z">
    <button type="submit" name="sub"> Dalej </button>
    <button type="reset"> Usuń </button>

    </form>

<?php

        $db = new mysqli('localhost', 'root', '', 'apf');
        $zt = $_GET['z'];
        $query = $db->prepare("INSERT INTO info VALUES('','$zt')");
        $query->execute();

?>

</div>

</div>
    
</body>
</html>

Natomiast tabela w bazie będzie w dołączonym obrazku.

Był bym wdzięczny za każdą pomoc. Miłego dnia!

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10227
2
  • Po pierwsze, Twój kod jest podatny na SQL injection w tym miejscu:
    Kopiuj
    $zt = $_GET['z'];
    $query = $db->prepare("INSERT INTO info VALUES('','$zt')");
    
    Co będzie jeśli ktoś przekaże w ?z= np. string '); DROP DATABASE apf;? 😀
    Skorzystaj z bindowania parametrów:
    Kopiuj
    $zt = $_GET['z'];
    $query = $db->prepare("INSERT INTO info VALUES('', ?)");
    $query->bind_param('s', $zt);
    
  • Po drugie, Twój kod jest podatny na XSS, dlatego że renderujesz dane jako goły string, tutaj:
    Kopiuj
    $z1 = $row['tekst'];
    echo "<li><h3> $z1 </h3></li> <br \>";
    
    Co jeśli Twój tekst będzie zawierał <script>alert("You have been hacked!");</script>? 😀
    Zastosuj poprawne enkodowanie HTML:
    Kopiuj
    $z1 = $row['tekst'];
    echo "<li><h3>" . \htmlSpecialChars($z1) . "</h3></li> <br \>";
    

A co do całokształtu tego programu, to raczej strzelasz sobie w stopę że mieszasz HTML i PHP. Lepiej byłoby wynieść możliwie dużo kodu PHP na górę, i HTML zostawić w miarę czysty, np tak:

Kopiuj
<?php
session_start();

$_SESSION['select'] = 'true';

$db = new mysqli('localhost', 'root', '', 'apf');

$query = $db->prepare("INSERT INTO info VALUES('', ?)");
$query->bind_param('s', $_GET['z']);
$query->execute();

$interests = [];
if ($_SESSION['select'] == 'true') {
    $query = $db->prepare('SELECT tekst FROM info;');
    $query->execute();
    $result = $query->get_result();
    while ($row = $result->fetch_assoc()) {
        $interests[] = $row['tekst'];
    }
}

?>
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title> Autoprezentacja | Filip Czeszka </title>
    <link rel="stylesheet" href="ap.css">
</head>
<body>

<header>
    <div id="lewy">
        <h1> Filip Czeszka </h1>
    </div>
    <div id="prawy">
        <img src="zdjecie.JPG" alt="zdjęcie">
    </div>
</header>

<main id="opis">

</main>

<div id="pasek">
    <div id="zaint">
        <h2> Zainteresowania </h2>
        <ul>
            <?php foreach ($interests as $interest): ?>
                <li><?= \htmlSpecialChars($interest) ?> </li>
            <?php endforeach; ?>
        </ul>
    </div>

    <br><br><br><br>

    <div id="insert">
        <h2> Podaj zainteresowanie </h2>
        <form action="" method="get">
            <input type="text" name="z">
            <button type="submit" name="sub">Dalej</button>
            <button type="reset">Usuń</button>
        </form>
    </div>
</div>
</body>
</html>

A co do Twojego problemu, że odświeżenie strony dodaje drugi raz ten sam przedmiot - no program robi dokładnie to do czego został zaprogramowany. Odświeżenie strony, to wywołanie skryptu drugi raz, który dodaje wartość kiedy przyjmie parametr.

To co możesz zrobić to:

  1. Zmienić metodę formularza na POST, i odczytywać $_POST, żeby przynajmniej przeglądarka dała monit. Warto też nie przekazywać danych przez query param, tylko w body.
  2. Dodać klucz do formularza, tak żeby strona wiedziała czy formularz jest wysłany drugi raz.
  3. Pozwolić tylko na unikalne zainteresowania, i dodawać wartość do bazy tylko jeśli takiej już nie ma.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.