portseven: Kommentar löschen Problem

Tag liebe Leute,

ich habe ein Skript geschrieben wo man etwas in einem Beitrag kommentieren kann.

Alles klappt wunderbar. Das problem ist:

-nehmen wir mal an, ich kommentiere 2 mal im gleichen Beitrag.

Wenn ich jetzt den ersten Kommentar löschen möchte, löscht er immer den neusten Kommentar und nicht den ersten. Obwohl ich deutlich gesagt habe: Lösche wo die K(ommentar)-Id = :kommentar_id ist. Das ist mir so komisch und nach langem ausprobieren und nachdenken musste ich mich einfach hier melden, da ich wirklich nicht mehr weiter komme.

Hier mal noch ein kleines Video, falls ihr nicht versteht was ich meine:

https://www.youtube.com/watch?v=OU5-vfH7UMI&feature=youtu.be

			<?php
	if(isset($_POST['delete_comment'])) {
	
	$kid = $_POST['kid'];
	
	$delete_comment = $pdo->prepare("
	DELETE FROM comments WHERE comments.k_id = :kid");
	$delete_comment->BindParam(':kid', $kid);
	if(!$delete_comment->execute()) {
	print_r($delete_comment->errorInfo());
	} else {
	var_dump($kid);
	}
}
	?>
		<section class="comment_main">
			<?php
			if(isset($_POST['show_comments']) && $_POST['comment_pid'] === $row['p_id']) { ?>
			<?php
				while($row2 = $com->fetch()) { ?>
					<section class="all_comments_from_post">
Kommentar: <?php echo $row2['comment']; ?></p> <br> <p>KommentarID: <?php echo $row2['kid']; ?></p><br>

		<?php if($_SESSION['id'] === $row2['id']) { ?>

			<p><input type="hidden" name="kid" value="<?php echo $row2['kid']; ?>"></p>
			<p><input type="submit" name="delete_comment" value="<?php echo $row2['kid']; ?> (Kommentar loeschen)"></p>

	<?php } ?>
			</p>
					
	</section>	

akzeptierte Antworten

  1. EDIT:

    Tabelle Comments: (MYSQL)

    k_id, (Kommentar-ID)

    p_id, (In welchem Beitrag kommentiert wurde) (In diesem Fall 59)

    u_id, (Wer alles kommentiert hat bzw welcher User) (in diesem Fall: 11)

    comment, (Kommentar) date, (Datum)

    Dies sieht bei mir z.b jetzt so aus:

    Damit ihr ein Überblick habt. Mir fallen wirklich keine Ideen mehr ein wie ich es sonst machen soll.

  2. Im zweiten CodeBlock werden mehr { geöffnet als } geschlossen. Und mit den </p>s stimmt auch was nicht.

  3. Tach!

    Wenn ich jetzt den ersten Kommentar löschen möchte, löscht er immer den neusten Kommentar und nicht den ersten.

    Schau mal nach, was "er" für einen Wert übergeben bekommt. Es sieht so aus, als ob ein anderer "er" ihm wohl nicht die eigentlich gewünschten Daten übermittelt. Öffne in diesem anderen "er", welches konkret benannt der Browser ist, die Entwicklertools und schau dir im Netzwerk-Tab den Request an, der da an den ersten "er", sprich den Server, gesendet wird.

    Allgemein gesagt, wenn Wunsch und Wirklichkeit voneinander abweichen, und man den Fehler nicht sieht, sollte man mit dem (meist ungeliebten) Debugging anfangen und genau nachvollziehen, welche Werte wo entstehen und weitergereicht werden. Und das sowohl zwischen Systemen als auch in ihnen.

    dedlfix.

  4. Hallo @portseven,

    		<section class="comment_main">
    			<?php
    			if(isset($_POST['show_comments']) && $_POST['comment_pid'] === $row['p_id']) { ?>
    

    Zu diesem beginnenden if fehlt das Ende. Woher kommt eigentlich $row?

    			<?php
    				while($row2 = $com->fetch()) { ?>
    					<section class="all_comments_from_post">
    Kommentar: <?php echo $row2['comment']; ?></p> <br> <p>KommentarID: <?php echo $row2['kid']; ?></p><br>
    

    Hier wird ein p geschlossen, der nicht geöffnet worden ist und die br sind auch überflüssig. Zudem sagst du in deinem anderen Post, dass das Tabellenfeld k_id heißt, was etwas Anderes als das kid hier ist.

    		<?php if($_SESSION['id'] === $row2['id']) { ?>
    

    Kommentar und ID werden also immer angezeigt, das Löschen allerdings nur angeboten, wenn die ID passend zu der aus der Session ist. Welche Idee steckt dahinter?

    			<p><input type="hidden" name="kid" value="<?php echo $row2['kid']; ?>"></p>
    			<p><input type="submit" name="delete_comment" value="<?php echo $row2['kid']; ?> (Kommentar loeschen)"></p>
    

    Wieso übergibst du hier eigentlich zwei mal die kid?

    	<?php } ?>
    			</p>
    

    Hier wird ein p geschlossen, der nicht geöffnet worden ist.

    	</section>	
    

    Viele Grüße
    Robert

    1. @@Robert B.

      		<section class="comment_main">
      			<?php
      			if(isset($_POST['show_comments']) && $_POST['comment_pid'] === $row['p_id']) { ?>
      

      Zu diesem beginnenden if fehlt das Ende.

      Ich finde schon den Anfang verkehrt.

      In Views sollte die altenative Schreibweise genutzt werden. Wie ich unlängst erst wieder sagte und dort auch die Diskussion über die Gründe verlinkte.

      LLAP 🖖

      --
      “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
  5. Hallo portseven,

    deine HTML Struktur ist total kaputt, wie schon andere bemerkt haben. Das ist aber hier nicht das Problem.

    Sondern: Du generierst pro Kommentar ein hidden-field mit der Kommentar-ID, diese Felder haben aber alle den gleichen Namen und liegen alle in einem Form. Submit postet das GANZE Form und damit alle hidden fields. Bei gleichem Namen gewinnt das letzte, darum löscht er den letzten Kommentar.

    Wenn Du den Wert von $_POST['delete_comment'] verwendest (wo Du ja die Kommentar-ID auch ablegst), statt $_POST['kid'], dürfte das Problem weg sein, weil meines Wissens nur der geklickte Submit-Button übertragen wird und die übrigen nicht. Hidden Fields brauchst Du dann gar nicht mehr.

    Wichtig noch: Du musst beim DELETE prüfen, ob die User-ID am Kommentar der ID in der Session entspricht. Sonst kann man mit fabrizierten POSTs Kommentare löschen, die einem nicht gehören.

    Grundregel für Server: DEIN CLIENT IST NICHT VERTRAUENSWÜRDIG.

    Rolf

    --
    sumpsi - posui - clusi
    1. Erstmal ein dickes Dankeschön für eure Hilfe.

      Das dient erstmal dazu, das der User der den Kommentar gepostet hat auch wieder löschen kann. Es ist sein Kommentar deswegen kann er auch sein Kommentar löschen. Wenn ich das nicht tue kann er jeden Kommentar löschen. Oder besser gesagt steht bei jedem Kommentar "Kommentar Löschen" obwohl es nicht seins ist. Dient halt nur zur Identifikation.

      
      		<?php if($_SESSION['id'] === $row2['id']) { ?>
      

      @Rolf B

      Danke, es hat so geklappt, aber es ist ja nicht schön, wenn da die Kommentar-ID steht anstatt "Kommentar Löschen".

      <p><input type="submit" name="delete_comment" value="<?php echo $row2['kid']; ?>"></p>
      

      Ich habe mal es etwas anders gemacht. Könnt ihr mir sagen ob es so ohne Sicherheitslücken geht? Klappen tut es schonmal:

      Beta.php

      			<p><a href="delete_comment.php?type=comment_delete&id=<?php echo $row2['kid']; ?>">Löschen</a></p>
      

      Delete_comment.php

      <?php
      session_start();
      include 'config/connect.php';
      include 'function.php';
      
      	if(isset($_GET["type"], $_GET["id"])) {
      	
      	$type = $_GET["type"];
      	$id = (int)$_GET["id"];
      	
      		switch($type) {
      		
      		case 'comment_delete':
      		$sql = $pdo->prepare("DELETE FROM comments WHERE comments.k_id = :kid AND comments.u_id = :uid");
      		$sql->BindParam(':kid', $id);
      		$sql->BindParam(':uid', $_SESSION['id']);
      		if(!$sql->execute()) {
      		print_r($sql->errorInfo());
      		} else {
      		header('location: beta.php');
      		}
      		break;
      		}
      	}
      ?>
      
      1. Hallo portseven,

        sorry für den value-Irrtum, natürlich ist das der angezeigte Text. Trotzdem ist <a> hier semantisch falsch, das ist kein Link, sondern eine Funktion auf dieser Seite und damit ein Button. Nimm ein <button> Element ohne type-Angabe (oder mit type="submit"), da kannst Du name und value als Parameter setzen und in den Button einen Text, der nicht mit dem value übereinstimmen muss. Den inline-Echo für die Kommentar-ID kannst Du mit dem „short echo tag“ auch kürzer fassen:

        <button name="delete_comment" value="<?= $row2['kid'] ?>">Kommentar löschen</button>
        

        Der DELETE ist so in Ordnung, meine ich.

        Rolf

        --
        sumpsi - posui - clusi
        1. Super! Hat geklappt. Ein dickes dankeschön an dir und den anderen das ihr euch Zeit genommen habt und mir geholfen habt!!

      2. Hallo @portseven,

        Danke, es hat so geklappt, aber es ist ja nicht schön, wenn da die Kommentar-ID steht anstatt "Kommentar Löschen".

        <p><input type="submit" name="delete_comment" value="<?php echo $row2['kid']; ?>"></p>
        

        ist das schöner?

        <button type="submit" name="delete_comment" value="<?= htmlspecialchars($row2['kid']); ?>">Kommentar Löschen</button>
        

        Viele Grüße
        Robert

        1. @@Robert B.

          Hab ich gleich mal im Stylesheet ergänzt:

          :root
          {
          	--warning-color: orange;
          	--warning-outline: 0.5rem solid var(--warning-color);
          }
          
          input[type="button"],
          input[type="reset"],
          input[type="submit"]
          {
          	WARNING: 'bad usage of input element; use button instead';
          	outline: var(--warning-outline);
          }
          

          LLAP 🖖

          --
          “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
  6. Hi,

    ~~~php
    		<section class="comment_main">
    			<?php
    			if(isset($_POST['show_comments']) && $_POST['comment_pid'] === $row['p_id']) { ?>
    			<?php
    				while($row2 = $com->fetch()) { ?>
    					<section class="all_comments_from_post">
    Kommentar: <?php echo $row2['comment']; ?></p> <br> <p>KommentarID: <?php echo $row2['kid']; ?></p><br>
    
    		<?php if($_SESSION['id'] === $row2['id']) { ?>
    
    			<p><input type="hidden" name="kid" value="<?php echo $row2['kid']; ?>"></p>
    			<p><input type="submit" name="delete_comment" value="<?php echo $row2['kid']; ?> (Kommentar loeschen)"></p>
    
    	<?php } ?>
    			</p>
    					
    	</section>	
    

    Das <form></form> umschließt (weil's nicht in jedem Schleifendurchlauf steht) also alle Kommentare?

    Dann hast Du mehrere <input name="kid"> im selben Formular. PHP kriegt das nicht auf die Reihe, wenn der Name keine [] enthält, und nimmt dann m.W. den letzten. Die [] hinzuzufügen hilft aber auch nicht wirklich, denn dann bekommst Du ein Array mit allen kids. Unabhängig davon, welcher Button genutzt wurde.

    ==> nicht ein form für alles, sondern ein form für jeden löschbaren Kommentar.

    Oder aber den Wert des delete_comment auslesen, da wird nur der von dem Button übertragen, der ausgelöst wurde.

    cu,
    Andreas a/k/a MudGuard