Nadine: Per Klick Button erscheinen lassen, der Variable an andere Seite übergeben kann

Hallo,

ich programmiere momentan eine kleine Bilbiotheks-Website und scheitere an meiner letzten Funktion. Vielleicht kann mir hier ja jemand helfen 😀

Und zwar habe ich eine Suchfunktion mit einem Submitbutton. Beim Klicken auf den Button wird auf der selben Seite unten drunter eine Tabelle mit den entsprechenden Suchergebnissen angezeigt. Jetzt wollte ich gerne noch, dass mit dieser Tabelle ein Button erscheint, mit dem man weitere Details auf einer anderen Seite anzeigen lassen kann. Ich hatte anfangs einen Button in den php-Code integriert, allerdings müsste ich diesem Button irgendwie den eingegebenen Suchbegriff übergeben, um mit dem Button dann diesen Suchbegriff auf die nächste Seite zu übergeben.

Das ist der Code für die Suche.

<b>Bestand durchsuchen</b><br>
		<form style="font-family: Calibri" method="post" action="index.php" name="details">
			<input style="font-family: Calibri" type="text" name="suchbegriff">
			<button style="font-family: Calibri" type="submit">Suchen</button><br>
			</form>

	<?php
			include "dbzugang.php";

			if(isset($_POST['suchbegriff'])){
				$suchbegriff = $_POST['suchbegriff'];
				echo "<input type=\"button\" style=\"font-family: Calibri\" onClick=\"parent.location='index.php'\" value='Suche löschen'>";
				$search =mysqli_query($conn, "SELECT * FROM bestand WHERE MATCH(Titel, Autor, Untertitel) AGAINST('$suchbegriff' IN BOOLEAN MODE);") or die(mysqli_error($conn));

				if($search-> num_rows > 0) {
								mysqli_set_charset($conn, "utf-8");
								echo "<table>";
								echo "<tr><th>". "Autor" . "</th><th>" . "Titel" . "</th><th>" . "Untertitel" . "</th><th>" . "Jahr" . "</th><th>" . "BuchID" . "</th><th>" . "Verleihstatus" . "</th></tr>";
								while($row = $search-> fetch_assoc()) {
									echo "<tr><td>". $row["Autor"] . "</td><td>" . $row["Titel"] . "</td><td>" . $row["Untertitel"] . "</td><td>" . $row["Jahr"] . "</td><td>" . $row["BuchID"] . "</td><td>" . $row["Verleihstatus"] . "</td></tr>";
								}
								
								echo "</table>";
				}
				else{
					echo "Die Suche ergab keine Treffer.";
				}
			}

		?>

Hatte wie gesagt überlegt in den php-Code einen Button zu programmieren und dann mit JS durch den Button die Variable 'suchbegriff' an die nächste Seite zu übergeben und dort dann mit $_REQUIRE auszulesen, daran bin ich aber kläglich gescheitert 😟

Würde mich freuen, wenn jemand eine Idee hat.

Vielen Dank schon mal 😀

  1. die Variable 'suchbegriff' an die nächste Seite zu übergeben und dort dann mit $_REQUIRE auszulesen

    Das muss scheitern. Meintest Du $_REQUEST? Diese Variable statt $_POST bzw. $_GET zu benutzen hat längst nicht immer den Vorteil der Vereinfachung sondern führt manchmal zu sehr merkwürdigen und schwer zu findenden logischen Programmfehlern.

    1. Ach ups, klar meinte ich $_REQUEST. Habe das mit einer anderen Seite so gemacht, und das klappt bei mir hervorragend.

      1. Ach ups, klar meinte ich $_REQUEST. Habe das mit einer anderen Seite so gemacht

        Bist Du sicher? Beispiel: Du brauchst eigentlich entweder $_POST['foo'] oder $_GET['foo'], Du (oder gar jemand anderea) baust aber (nachträglich) eine lib ein, die $_SESSION['foo'] oder $_COOKIE['foo'] besetzt - wovon Du nichts weißt. In Regelfall enthält dann $_REQUEST['foo'] nicht etwa die erwarteten Formulardaten sondern ganz anderes Zeug.

        und das klappt bei mir hervorragend.

        Aber nur zufällig. Glaube mir das, ich habe früher auch $_REQUEST benutzt…

  2. Hallo Nadine,

    eine Möglichkeit, so etwas zu lösen, ist ein

    <input type="hidden" name="suchbegriff" value="<?= htmlspecialchars($suchbegriff) ?>">
    

    auf der Seite. Das htmlspecialchars ist wichtig, andernfalls könnten Dir Sonderzeichen in der Eingabe das HTML kaputt machen. Den Feldinhalt findest Du dann wieder unter $_POST.

    Eine Alternative zum hidden Field wäre ein temporärer Cookie (d.h. der expires-Parameter in set_cookie ist 0) oder $_SESSION. Einen Cookie findest Du im nächsten Request in $_COOKIES, Sessiondaten in $_SESSION, für Session-Handling musst Du aber auch etwas vorsehen, um die Sessiondaten zu speichern. Ich weiß grad nicht, ob PHP das immer automatisch tut.

    Für temporäre Cookies (ein Suchbegriff-Cookie oder auch der Cookie für die Session-ID) musst Du den User nicht um Erlaubnis fragen, die verschwinden nach Schließen des Browsers. Du erwähnst einfach in der Datenschutzerklärung, dass Du sie benutzt.

    #Aber Dein SQL Zugriff benötigt dringend eine Korrektur.

    Im vorliegenden Statement kann man nicht viel kaputt machen, aber wenn dein Login-Teil ebenso aussieht, injiziert man Dir damit problemlos einen falschen Login. Und wenn Dein MYSQL Mehrfachstatements zulässt, injiziert man Dir damit auch Code, der deine Tabellen leert oder DROPt.

    Heißt: Du kannst nicht einfach $suchbegriff in das SQL Statement einsetzen, du musst einen korrekten Kontextwechsel von "Plaintext" nach "SQL Parameter" durchführen. Dazu dient die Funktion mysqli_real_escape_string, bzw. $mysqli->escape_string wenn Du die Objektvariante verwendest. Guck's Dir in der PHP Doku an.

    Rolf

    --
    sumpsi - posui - clusi
    1. Tach!

      Und wenn Dein MYSQL Mehrfachstatements zulässt, injiziert man Dir damit auch Code, der deine Tabellen leert oder DROPt.

      Prinzipiell lässt MySQL das nur zu, wenn man eine entsprechende Option beim Verbindungsaufbau setzt. PHP hat das anders implementiert, da muss man explizit die multiquery-Funktionen nehmen. Aber auch ohne Multi-Query-Möglichkeit kann man eine Menge Unheil anrichten, wenn die Querys nicht ordentlich maskiert sind.

      Übrigens, or die() ist auch keine gescheite Fehlerbehandlung. Damit geht die Ausgabe kapuut, was meist nicht besonders hübsch aussieht. Die bessere Lösung fängt damit an, sich zu überlegen, ob man dem Anwender im Fehlerfall nicht eine Alternative bieten kann.

      dedlfix.

    2. Vielen Dank für den Tipp, ich werde mir das jetzt gleich mal anschauen 😀

      Was meinst du mit meinem "Login-Teil"? Aber auch den Link den du dazu gepostet hast werde ich jetzt gleich mal anschauen 😀 vielen Dank

      1. Hallo Nadine,

        Was meinst du mit meinem "Login-Teil"?

        Ich weiß natürlich nicht, ob man sich bei deiner Seite anmelden muss. Aber wenn ja, wirst Du ja ein Login-Form programmiert haben, und das authentifiziert den User gegen eine SQL-Tabelle.

        Solcher Code:

        $pw = getPasswordHash($_POST['password'];
        mysqli_query($conn, "SELECT userid FROM users WHERE username='$_POST[username]' AND passwordhash='$pw'");
        

        war schon auf vielen Seiten das Einfallstor für Hacker.

        Rolf

        --
        sumpsi - posui - clusi
        1. Tach!

          Solcher Code:

          $pw = getPasswordHash($_POST['password'];
          mysqli_query($conn, "SELECT userid FROM users WHERE username='$_POST[username]' AND passwordhash='$pw'");
          

          war schon auf vielen Seiten das Einfallstor für Hacker.

          Die haben dann so lustige Namen wie admin' -- , womit das Passwort dann keine Rolle mehr spielt.

          dedlfix.

        2. Achso, nein ein Login habe ich nicht mit einprogrammiert.

    3. So ich hab mir das mit den Sessions jetzt mal angeschaut, und das funktioniert super. Vielen Dank für den hilfreichen Tipp 😀

    4. <input type="hidden" name="suchbegriff" value="<?= htmlspecialchars($suchbegriff) ?>">
      

      […] Das htmlspecialchars ist wichtig, andernfalls könnten Dir Sonderzeichen in der Eingabe das HTML kaputt machen.

      Übrigens nicht nur an dieser Stelle, alle dynamischen Inhalte müssen maskiert werden.

      PS: Wäre schön, wenn du das in deiner anderen Antwort einfließen lässt.

      1. Hallo 1unitedpower,

        done. Danke für den Hinweis.

        Rolf

        --
        sumpsi - posui - clusi
  3. Hallo Nadine,

    ein Hinweis noch zur Ausgabe deiner Ergebnistabelle. Und ich sehe dabei noch: dein set_charset kommt zu spät, der müsste meiner Meinung nach eigentlich schon vor dem mysqli_query stehen.

    Es ist unschön, größere Mengen HTML per echo auszugeben. Du kannst jederzeit aus dem PHP Kontext aus- und wieder einsteigen, das macht keinen Performance-Unterschied. Eine ECHO-Orgie wie bei Dir ist höchstens interessant, wenn man das HTML sehr kleinteilig zusammensetzt (wenn z.B. die Tabellenspalten konfigurierbar sind).

    	if ($search->num_rows > 0) : ?>
    		<table>
    			<tr>
    				<th>Autor</th>
    				<th>Titel</th>
    				<th>Untertitel</th>
    				<th>Jahr</th>
    				<th>BuchID</th>
    				<th>Verleihstatus</th>
    			</tr>
    <?php while($row = $search-> fetch_assoc()) : ?>
    			<tr>
    				<td><?= htmlspecialchars($row["Autor"]) ?></td>
    				<td><?= htmlspecialchars($row["Titel"]) ?></td>
    				<td><?= htmlspecialchars($row["Untertitel"]) ?></td>
    				<td><?= htmlspecialchars($row["Jahr"]) ?></td>
    				<td><?= htmlspecialchars($row["BuchID"]) ?></td>
    				<td><?= htmlspecialchars($row["Verleihstatus"]) ?></td>
    			</tr>
    <?php endwhile; ?>
    		</table>
    <?php endif;
    	...ggf weiterer PHP Code
    ?>  
    

    Man verwendet bei solchen Konstrukten dann besser die "alternative Syntax" für Kontrollstrukturen, also dies:

    			if ($bedingung) : ?>
    				// html wüste
    <?php endif;
    

    statt dies:

    			if ($bedingung) { ?>
    				// html wüste
    <?php }
    

    Grund: Die einsame } wird bei solchen Konstrukten gern im Getümmel übersehen. Noch besser ist es, die Ausgabe des HTML-Blocks in eine Funktion auszulagern:

    	if ($search->num_rows > 0)
    		show_search_result($search);
    

    Und hinter der eigentlichen Programmlogik notiert man dann die Funktionen:

    	function show_search_result($search) {
    ?>
    		<table>
    			<tr>
    				<th>Autor</th>
    				<th>Titel</th>
    				<th>Untertitel</th>
    				<th>Jahr</th>
    				<th>BuchID</th>
    				<th>Verleihstatus</th>
    			</tr>
    <?php
    		while($row = $search-> fetch_assoc()) {
    			show_search_result_row($row);
        }
    ?>
    		</table>
    <?php
    	}
    
      function show_search_result_row($row) {
    ?>
    			<tr>
    				<td><?= htmlspecialchars($row["Autor"]) ?></td>
    				<td><?= htmlspecialchars($row["Titel"]) ?></td>
    				<td><?= htmlspecialchars($row["Untertitel"]) ?></td>
    				<td><?= htmlspecialchars($row["Jahr"]9 ?></td>
    				<td><?= htmlspecialchars($row["BuchID"]) ?></td>
    				<td><?= htmlspecialchars($row["Verleihstatus"]) ?></td>
    			</tr>
    <?php
      } // endfunction;
    	...ggf weiterer PHP Code
    ?>  
    

    Durch die Funktionengliederung hast Du keine HTML-Blöcke innerhalb von PHP Blockstrukturen, und kannst bei { und } bleiben.

    Edit 10.03.: natürlich müssen die Ausgaben mit htmlspecialchars maskiert werden

    Rolf

    --
    sumpsi - posui - clusi
  4. @@Nadine

    Das ist der Code für die Suche.

    <b>Bestand durchsuchen</b><br>
    		<form style="font-family: Calibri" method="post" action="index.php" name="details">
    			<input style="font-family: Calibri" type="text" name="suchbegriff">
    			<button style="font-family: Calibri" type="submit">Suchen</button><br>
    			</form>
    

    Da ist einiges zu verbessern:

    • Das Eingabefeld hat keine Beschriftung (kein zugehöriges label-Element). Sollte es aber haben, damit das Formular auch für Nutzer bedienbar ist, die die Seite nicht visuell wahrnehmen.

      Wir zeichnen „Bestand durchsuchen“ als Beschriftung aus; dabei kommt das label-Element mit ins form-Element hinein:

      <form >
      	<label>
      		Bestand durchsuchen
      		<input  name="suchbegriff">
      	</label>
      	<button >Suchen</button>
      </form>
      

      oder mit ID und for-Attribut:

      <form >
      	<label for="suchbegriff">Bestand durchsuchen</label>
      	<input  name="suchbegriff" id="suchbegriff">
      	<button >Suchen</button>
      </form>
      
    • Für Suchfelder gibt es einen speziellen Eingabefeld-Typen type="search":

      <input type="search" name="suchbegriff" id="suchbegriff">
      
    • Das ganze Ding sollte die Rolle role="search" bekommen:

      <div role="search">
      	<form >
      		<label for="suchbegriff">Bestand durchsuchen</label>
      		<input type="search" name="suchbegriff" id="suchbegriff">
      		<button >Suchen</button>
      	</form>
      </div>
      
    • Die Angabe der Schrift sollte nicht inline in style-Attributen stehen, sondern gehört mit ins Stylesheet.

      Buttons innerhalb von Formularen sind per Default Submitbuttons; type="submit" ist nicht falsch, aber nicht notwendig.

    Dann bleibt also übrig:

    <div role="search">
    	<form method="post" action="index.php" name="details">
    		<label for="suchbegriff">Bestand durchsuchen</label>
    		<input type="search" name="suchbegriff" id="suchbegriff">
    		<button>Suchen</button>
    	</form>
    </div>
    

    Das kannst du dann wie gewünscht mit CSS stylen, z.B. die Beschriftung in Calibri setzen, das Label „Bestand durchsuchen“ fett setzen …

    Suchformularen ist in Adam Silvers Buch „Form Design Patterns“ ein eigenes Kapitel gewidmet. Dieses Buch sollte in der Bibliothek eines Webentwicklers nicht fehlen.

    LLAP 🖖

    --
    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann