der henry: dynamische Webseite mit php

Hallo,

ich möchte mit PHP eine Webseite dynamisch erstellen. Hier ein Teil meines Codes. Mir geht es um die Syntax bzw. die Art wie man dieses Problem lösen kann. Ich kenne "php-Code" in der Webseite, oder php-Variablen, oder eine php-if Anweisung. Jedoch nicht die Kombination 😅

Die Variable $switch wird im php-script gesetzt. Wenn diese true ist, soll der html-Code (table usw.) angezeigt werden und zugleich/im Anhang die for-Schleife aktiviert und die Ausgabe der for-Schleife angezeigt werden. Die erste Zeile (<tr>)ist statisch, alle anderen Zeilen sollen dynamisch angezeigt werden. Aktuell zeigt er mir die for-Schleife (Quellcode) auf der Webseite an

	<?php if ($switch): ?>
				<table cellspacing="2" border="2" cellpadding="3" align="center" frame="box">
				<tr bgcolor=<?= $valuerangeArray[0]->bgcolor ?>>
					<td>
						<INPUT type='radio' id=<?= $valuerangeArray[0]->varname ?> value="0" align="left" checked>
					</td>
					<td class='beschriftung_radio_button' align="left"><?= $valuerangeArray[0]->text ?></td>
				</tr>
				<?php>
						for ($i=1;$i < count($valuerangeArray); $i++)
						{
							echo "<tr bgcolor=\"$valuerangeArray[0]->bgcolor\">";
							echo "<td>";
							echo "<INPUT type=\"radio\" id=\"$valuerangeArray[$i]->varname\" value=\"0\" align=\"left\">";
							echo "</td>";
							echo "<td class=\"beschriftung_radio_button\" align=\"left\">$valuerangeArray[$i]->text</td>";
							echo "</tr>";
						}
				?>       
				echo "</table>";      
			<?php endif; ?>

Wie kann ich dies lösen?

  1. Hi,

      		<?php>
    

    da ist ein > zu viel.

    cu,
    Andreas a/k/a MudGuard

    1. Hallo MudGuard,

      da ist noch mehr zu viel. Dafür fehlt anderes.

      • den input-Elementen fehlt das zwingend erforderliche Label. Es ist zwar theoretisch da, aber nicht zugänglich.

      • align für input - gab es das überhaupt einmal? Aber auch auf dem td wäre es missbilligt und sollte per CSS (text-align) festgelegt werden.

      • bgcolor für tr – diese Eigenschaft ist missbilligt. Statt dessen soll man
        style="background-color: <?= $valuerangeArray[0]->bgcolor ?>"
        schreiben. Sofern es denn sinnvoll ist, die Farben individuell pro Row oder Zelle zu vergeben. Aber das kann man aus dem gezeigten Code schlecht beurteilen und es hängt von der Variabilität der Farben ab, ob man es mit Klassen versuchen sollte.

      • cellspacing="2" border="2" cellpadding="3" align="center" frame="box" für das table-Element: Muss alles weg, ist alles HTML 3 Relikt oder so, das gehört ins CSS. Man gebe der Table eine Klasse und ordne dann im CSS für Tables mit dieser Klasse zu:

        • align="center" zentriert die ganze Tabelle, das sollte sich als margin-inline:auto für das table-Element abbilden lassen
        • cellspacing="2" ist border-spacing: 2px auf dem table-Element
        • cellpadding="3" möchte padding: 3px auf den th/td Elementen sein
        • frame="box" und border="2" wird als "border: 2px solid gray" auf dem table-Element und als "border: 1px solid black" auf de td Elementen festgelegt (Farbe nach Belieben - bei Chrome ist die border-color für Tables per Default gray)
      • Das Innere der For-Schleife sollte besser wieder HTML-Template sein. So wie auch für das table Element. Dito für </table>.

      • Mich deucht, das tr vor der Schleife und die tr in der Schleife unterscheiden sich lediglich im checked Attribut. Um Redundanz zu vermeiden, würde ich dieses tr in die Schleife ziehen und auf $i==0 testen. Hier bietet sich der Auswahloperator ?: an (auch ternärer Operator genannt).

      • Ich würde der Übersichtlichkeit wegen auch versuchen, das Innere des if ($switch) Blocks in eine Funktion auszulagern.

      if ($switch) {
         renderValueRanges($valuerangeArray);
      }
      
      ...
      
      function renderValueRanges($valueRangeArray) {
      ?>
        <table class="value_ranges">
      <?php
        for ($i=0; $i < count($valuerangeArray); $i++):
          $id = $valuerangeArray[0]->varname;
          $text = $valuerangeArray[0]->text;
      ?>
          <tr style="background-color:<?= $valuerangeArray[0]->bgcolor ?>">
            <td>
              <input type='radio' id="<?= $id ?>" value="0" <?= $i==0 ? "checked" : "" ?>>
            </td>
            <td>
              <label for="<?= $id ?>"><?= $text ?></label>
            </td>
      		</tr>
      <?php
         endfor;
      ?>
        </table>
      <?php
      }
      

      Die Variablen $id und $text sind nicht unbedingt nötig und Puristen würden sagen, die braucht man nicht. Ich finde, sie verbessern die Lesbarkeit und verhindern kilometerlange Codezeilen.

      Die Klasse beschriftung_radio_button, die ja ohnehin schon "LABEL" geschrieen hat, sollte im CSS mit einem geeigneten Selektor ersetzt werden. Möglichkeiten wären:

      • .value_ranges td:nth-of-type(2)
      • .value_ranges td:has(label)
      • oder direkt das label formatieren: .value_ranges label

      Je nach Bedarf und Belieben.

      Zu prüfen wäre auch noch, ob die Radiobuttons außer der ID auch noch ein name-Attribut brauchen. Nur mit id werden sie in einem Form nicht gepostet, wenn mich die Erinnerung nicht trügt.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Hallo Leute,

        vielen, vielen Dank. Ja ... der Fehler war banal, ein ">" zu viel.

        Die Verbesserungen/Optimierungen von Rolf habe eingefügt, nochmals Danke.

        Die Klasse beschriftung_radio_button, die ja ohnehin schon "LABEL" geschrieben hat, sollte im CSS mit einem geeigneten Selektor ersetzt werden. Möglichkeiten wären:

        .value_ranges td:nth-of-type(2)
        .value_ranges td:has(label)
        oder direkt das label formatieren: .value_ranges label
        

        Das verstehe ich aber nicht ....

        Anbei das aktuelle Teilscript.

        Hierzu hätte ich noch Fragen. Wie zu erkennen möchte ich einen Eingabedialog programmieren, der entweder ein Eingabefeld für Zahlen, oder ein "Auswahlfeld" (... mehrere Radiobutton) vorwählt. Die Informationen was wie angezeigt wird, erhalte ich aus einer Datenbank.

        Beim "Senden" (bestätigen der Eingabe) muss ich unterscheiden, welcher Radiobutton ausgewählt wurde. Dazu habe ich jedem Radiobutton eine eindeutige ID und NAME gegeben.

        Aktuelle bekomme ich aber nur den Wert (value) des ausgewählten Radiobuttons, was mache ich hier falsch?

        <!DOCTYPE html>
        <html lang="de">
        <head>
            <meta charset="UTF-8">
            <title>Eingabefeld</title>
            <style>
                #overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); display: flex; justify-content: center; align-items: center; color: white; }
                .modal { background: #333; padding: 20px; border-radius: 8px; text-align: center; }
                .hidden { display: none !important; }
        		.value_ranges { margin-inline:auto; border-spacing: 2px; border: 2px solid gray;
        						td { padding: 3px; border: 1px solid black"; }
        					  }
            </style>
        </head>
        
        <body>
        
        <?php if ($message === "SUCCESS"): ?>
            <div id="overlay">
                <div class="modal">
                    <h2>Daten erfolgreich gespeichert!</h2>
                    
                    <h1><?= $datatosave ?></h1>
                    
        <!--			<script>setTimeout(function(){ window.close(); }, 2000);</script>	-->
                    <button onclick="window.close();">Beenden</button>
                </div>
            </div>
        <?php endif; ?>
        
        <div id="overlay" class="<?= $show_form ? '' : 'hidden' ?>">    
            <div class="modal" id="form-container">
                <h2><?= $headline ?></h2>
        		<form method="POST" id="secure-form">
                    <input type="hidden" name="action" value="submit">
                    <label for="password">Passwort: </label><input type="password" id="password" name="password" minlength="4" maxlength="10" required><br><br>
        			<br><br>
        			
        			<!-- wenn value ausgewählt wurde muss ein Eingabefeld für Zahlen eingeblendet werden -->
        			<?php if ($value): ?>
        				<p>min. <?php $valueRangeArray[0]->min ?></p>
        				<p>max. <?php $valueRangeArrayangeArray[0]->max ?></p>
        
        				<input type="text" name="data" placeholder="Deine Daten" required>
        				<label for="data"><?= $valueRangeArray[0]->unit ?></label>
        				<br><br>
        			<?php endif; ?>
                       
                    <!-- wenn switch ausgewählt wurde muessen select Felder her -->
        			<?php 
        				if ($switch) { renderSwitchRange($valueRangeArray); }
        			?>
        			              
                    <br><br>
                    <button type="submit">Senden</button>
                    <button type="button" onclick="cancelAction()">Abbrechen</button>
                </form>
                <hr style="width: 50%;">
                <p id="timer-text">Timout: <span id="seconds">30</span>s</p>
                <?php if ($message === "WRONG_PASSWORD"): ?>
                    <p style="color: red;">falsches Passwort!</p>
                <?php endif; ?>
            </div>
        </div>
        
        <script>
        	
        	window.onload = function() {
        		// Ermittelt die benötigte Breite und Höhe des Inhalts
        		// scrollWidth/Height erfassen den gesamten Inhalt, auch wenn er versteckt ist
        		let contentWidth = document.documentElement.scrollWidth;
        		let contentHeight = document.documentElement.scrollHeight;
        
        		// Optional: Puffer für Browser-Rahmen/Scrollbars hinzufügen
        		window.resizeTo(contentWidth + 50, contentHeight + 200);
        };
        
            let timeLeft = 30;
            const timerSpan = document.getElementById('seconds');
            const overlay = document.getElementById('overlay');
        
            const countdown = setInterval(() => {
                timeLeft--;
                timerSpan.innerText = timeLeft;
                if (timeLeft <= 0) {
                    clearInterval(countdown);
                    cancelAction();
                }
            }, 1000);
        
        //########################################################################################################
        
        function cancelAction()
        {
        	overlay.classList.add('hidden');
        	window.close();
        }
        
            // Timer bei Mausbewegung zurücksetzen (optional)
            window.onmousemove = () => timeLeft = 30;
        
        //########################################################################################################
        
        </script>
        </body>
        </html>
        
        <?php
        function renderSwitchRange($valuerangearray) 
        {
        ?>
        <table class="value_ranges">
        <?php
          for ($i=0; $i < count($valuerangearray); $i++):
            $id = $valuerangearray[$i]->varname;
            $text = $valuerangearray[$i]->text;
            $set = $valuerangearray[$i]->set;
        ?>
            <tr style="background-color:<?= $valuerangearray[$i]->bgcolor ?>">
              <td>
                <input type='radio' id="<?= $id ?>" name="<?= $id ?>" value="<?= $set ?>" <?= $i==0 ? "checked" : "" ?>>
              </td>
              <td>
                <label for="<?= $id ?>"><?= $text ?></label>
              </td>
        		</tr>
        <?php
           endfor;
        ?>
          </table>
        <?php
        }
        
        
        1. Hallo Henry,

          ...beschriftung_radio_button ... geeigneter Selektor

          Das verstehe ich nicht

          Aus dem, was zu zeigst, sieht es so aus als würdest Du das Label gar nicht per CSS ansprechen. Dann wäre eher die Frage, ob Du die Klasse überhaupt brauchst.

          Vieles von dem, was Du zeigst, scheint aus dem Kontext gerissen, als ob Du Teile rausgelöscht hättest. Drum gehe ich lieber nicht sonderlich drauf ein.

          Aber ein paar Sachen hätte ich (die Radiogroup-Sache kommt am Ende).

          Warum setzt Du für das zweite div mit id="overlay" die Klasse hidden, wenn $show_form auf false steht? Warum versteckt zum Client schicken und den Ärger mit einer doppelt vorhandenen ID haben? Warum generierst Du diesen Teil überhaupt, wenn $show_form nicht gesetzt ist? Bei $message==="SUCCESS" machst Du es anders, dieser Teil wird übersprungen, wenn $message nicht "SUCCESS" enthält. Gibt es Gründe, dass Du den form-Teil immer generierst?

          Und warum das Gefummel mit einem fixed-Container? Du setzt die Fenstergröße doch eh auf die Inhaltsgröße, damit müsste dieser Container komplett überflüssig sein. Gib die 3 Flexbox-Eigenschaften einfach dem Body-Element, und setze am Body noch margin:0; width: 100vw; height: 100vh; - Höhe auf 100% dürfte eher nichts nützen. height:100% setzt die Höhe auf 100% des Elternelements, und um auf Fensterhöhe zu kommen, muss dann auch das Root-Element (html) auf height:100% gesetzt werden. 100vh am Body ist einfacher.

          Das Text-Eingabefeld verwendet ein Label, um die Einheit anzuzeigen? Das ist keine brauchbare Beschriftung. Ein Label muss den Zweck der Eingabe erkennen lassen, und ein Placeholder ist kein Label. Wie man das zugänglich mit der Einheit macht, weiß ich nicht genau. Das Label sollte so aussehen und vor dem input stehen (am besten drüber):

          <label for="data">Deine Daten (min. <?= $valueRangeArray[0]->min ?>, max. <?= ... ?></label>
          <input type="text" id="data" name="data" required min="..." max="...">
          

          Wichtig hier:

          • Einsteuern von Werten mit <?= ?>, nicht mit <?php ?>. Ersteres erzeugt einen echo für den Wert, zweiteres führt einen PHP-Befehl aus.
          • min und max können auch am input eingestellt werden. Wirken aber meines Wissens nur für ein numerisches Input. Wenn Du Zahlen erwartest, wäre input type="numeric" eh besser.
          • das input-Element braucht die id für das Label und name für das Senden zum Server. Es braucht beides!
          • "Deine Daten" mag ausnahmweise eine geeignete Beschriftung sein, im Normalfall würde ich aber annehmen, dass das zu abstrakt ist. Welche Bedeutung hat dieser Wert? Das sollte in der Beschriftung stehen.

          In deiner Timeout-Behandlung bist Du zu kompliziert, glaube ich. Hast Du Gründe für diese Fummelei? Reicht es nicht, bei Ablauf der Zeit einfach window.close() aufzurufen? Löschen des Intervalltimers und verstecken von #overlay sollte sich mit dem Schließen des Fensters erübrigen. Beim Klick auf Abbrechen hast Du das Löschen des Timers eh vergessen 😉

          Bezüglich der Radiogroup: da habe ich gepennt. Radiobuttons bilden nur dann eine Gruppe, wenn alle Radiobuttons den gleichen Namen haben. Zum Beispiel name="auswahl", such dir was fachlich passenden aus. Die ID verwendest Du als ID für den Button, damit das Label funktioniert, und speichere sie auch im value-Attribut. Wobei ich nicht weiß, was es mit $valuerangeArray[$i]->set auf sich hat, das Du im Moment als value verwendest.

          Jedenfalls - bei einer Radiogroup sorgt das Auswählen eines Buttons für das Abwählen der übrigen Buttons, und PHP bekommt beim Submit unter dem gemeinsamen Namen den Value des ausgewählten Buttons geschickt.

          Hoffe, ich konnte weiterhelfen.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Hallo Rolf,

            vielen Dank für dein feedback.

            Jedenfalls - bei einer Radiogroup sorgt das Auswählen eines Buttons für das Abwählen der übrigen Buttons, und PHP bekommt beim Submit unter dem gemeinsamen Namen den Value des ausgewählten Buttons geschickt.

            Genau das ist mein Problem, das nur der "value" zurückkommt.

            Hintergrund:

            In ein Datenbankfeld soll, je nach Auswahl der "Radiobutton" ein Wert "X" (value) geschrieben werden. Dazu nutze ich den Namen des Datenbankfeldes als "id" und den zu schreibenden Wert, als "value" das ich je "RadioButton" schreibe. z.B.

            <input type='radio' id="<?= $id ?>" name="immergleich" value="<?= $set ?>">

            Wenn ich einen "RadioButton" auswähle, hat dieser die Info, wie oben beschrieben.

            1. id => welches Datenbankfeld beschrieben werden soll
            2. set => welcher Wert in die Datenbank geschrieben werden soll

            Wie könnte ich dies anders lösen, das beim "senden" die "id" und der "value" des ausgewählten "Radiobutton" an das php-script geschickt wird?

            Vielen Dank!!

            1. Hallo der henry,

              Wie könnte ich dies anders lösen, das beim "senden" die "id" und der "value" des ausgewählten "Radiobutton" an das php-script geschickt wird?

              Du bekommst name=value, wenn in einem Form mit der Radiogroup

              <input type="radio" id="foo-1" name="foo" value="dings"><label for="foo-1">Dings</label>
              <input type="radio" id="foo-2" name="foo" value="bums"><label for="foo-2">Bums</label>
              <input type="radio" id="foo-3" name="foo" value="tra"><label for="foo-3">Tra</label>
              <input type="radio" id="foo-4" name="foo" value="lala"><label for="foo-4">Lala</label>
              

              der dritte Radiobutton ausgewählt ist und das Form mit POST gesendet wird, dann findest Du in PHP in $_POST["foo"] den Wert "tra" vor.

              Wenn Du zwei Werte haben willst, kannst Du tricksen und beide Werte in den Value schreiben. Zum Beispiel:

              <input type="radio" id="foo-3" name="foo" value="foo-3;tra"><label for="foo-3">Tra</label>
              

              Dann steht in $_POST["foo"] der Wert "foo-3;tra" und das kannst Du mit explode zerlegen. Aber ist das nötig? Brauchst Du unbedingt zwei Informationen zu einem Radiobutton?

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Hallo Rolf,

                Und warum das Gefummel mit einem fixed-Container? ....

                weil ich es leider nicht besser weiß 🤔, ich lerne aber dazu ... hoffe ich.

                Anbei mein komplettes Script, was ich bis jetzt programmiert habe. Es fehlt aber noch das Schreiben des Rückgabewertes in die Datenbank, was ich noch nicht erstellt habe. Die Optik ist auch noch nicht berauschend.

                <?php
                
                include_once("../cgi-bin/database_tools.php");
                include_once("../cgi-bin/tools.php");
                
                /*
                Beispieldaten
                
                ["name": "Schaltbefehl1",
                "type":"switch",                          // oder value
                "headline":"Ueberschrift",
                "group":9,
                "role":"user",
                "passwd":"0815"],
                "valuerange":
                [{"varname":"T1.ws_regler_ein","set":1,"min":-10,"max":30,"unit":"cm","multi":1,"text":"WS Regler EIN","bgcolor":"#FF0000"},
                {"varname":"T1.ws_regler_aus","set":1,"min":-10,"max":30,"unit":"cm","multi":1,"text":"WS Regler AUS","bgcolor":"#033dfc"},
                {"varname":"T1.stell_regler_EIN","set":3,"min":-10,"max":30,"unit":"cm","multi":1,"text":"Stell.Regler EIN","bgcolor":"blue"}];
                
                */
                
                // Initialisieren der Variablen
                $message = "";
                $show_form = true;
                $switch = 0;
                $value = 0;
                
                // später wird Name mit übergeben //
                	$name = "Funktionstest Eingabe";
                
                	// öffne Datenbank
                	$db_link = open_database();
                	
                	if ($db_link === false) { return false; }
                
                	try
                	{
                		$sql = "SELECT * FROM writecommands WHERE name ='".$name."'";
                		$db_result = mysqli_query($db_link, $sql);
                
                		if ($db_result->num_rows > 0)
                		{ $writecommand = mysqli_fetch_all($db_result, MYSQLI_ASSOC); }
                		else
                		{ $writecommand = [ "name" => "Name not correct", "valuerange" => "" ]; }
                
                //########################################################################################################
                // eigentlich erst wichtig, wenn das passwort richtig ist
                	
                //		$sql = "SELECT * FROM datapoints WHERE plcvarname ='".$name."'";
                //		$db_result = mysqli_query($db_link, $sql);
                		
                //		if ($db_result->num_rows > 0)
                //		{ $datapoint = mysqli_fetch_all($db_result, MYSQLI_ASSOC); }
                //		else
                //		{ echo "no datapoint found with name: '".$name."'";	}
                //	}
                //	catch(PDOException $e) { echo "database error: " . $e->getMessage(); }
                	
                //	$db_link->close();
                
                	$name = $writecommand[0]['name'];
                	$type = $writecommand[0]['type'];
                	$headline = $writecommand[0]['headline'];
                	$group = $writecommand[0]['group'];
                	$role = $writecommand[0]['role'];
                	$passwd = $writecommand[0]['passwd'];
                	$valueRange = $writecommand[0]['valuerange'];
                	$valueRangeArray = json_decode($valueRange);
                	
                // prüfe welche Schreibbefehl es ist (switch wegen Erweiterungen)
                	switch (strtolower($type))
                	{
                		case "switch":
                			$switch = true;
                			break;
                		case "value":
                			$value = true;
                			break;
                	} 
                
                // überprüfe ob Daten empfangen wurden
                	if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['action'])) 
                	{
                		$inputpwd = $_POST['password'] ?? '';
                	
                		// Passwort prüfen	
                		if ($passwd === $inputpwd)
                		{   // passwort "OK"
                			$message = "SUCCESS"; 
                			$show_form = false;
                
                			$i=0;
                		
                			foreach ($_POST as $key => $value) 
                			{
                				$receiveArray[$i] = htmlspecialchars($key);
                				$i++;
                				$receiveArray[$i] = htmlspecialchars($value);
                				$i++;
                			}
                	
                			$datatosave = "$receiveArray[4] = $receiveArray[5]"; 
                		}
                		else
                		{ $show_form = true; }	
                	}
                
                //########################################################################################################
                ?>
                
                <!DOCTYPE html>
                <html lang="de">
                <head>
                    <meta charset="UTF-8">
                    <title>Eingabefeld</title>
                    <style>
                        .modal { padding: 20px; border-radius: 8px; text-align: center; }
                   
                        #finish_OK { background: #00FF00; }
                        #form-container { background: #D3D3D3; }
                        
                        .value_ranges { margin-inline:auto; border-spacing: 2px; border: 2px solid gray;
                						td { padding: 3px; border: 1px solid black"; }
                					  }
                		.headframe { margin:0; width: 100vw; height: 100vh; justify-content: center; align-items: center; }
                    </style>
                </head>
                
                <body class="headframe">
                
                <?php if ($message === "SUCCESS"): ?>
                	<div class="modal" id="finish_OK">
                		<h2>Daten erfolgreich gespeichert!</h2>
                			<?php print_r($_POST) ?>
                			<h1><?= $datatosave ?></h1>
                <!--		<script>setTimeout(function(){ window.close(); }, 2000);</script>  -->
                		<button onclick="window.close();">Beenden</button>
                	</div>
                	<script>resize();</script> 
                <?php endif; ?>
                
                
                <?php if ($show_form === true): ?>
                <div id="overlay" class="<?= $show_form ?>">    
                    <div class="modal" id="form-container">
                        <h2><?= $headline ?></h2>
                		<form method="POST" id="secure-form">
                			<input type="hidden" name="action" value="submit">
                            <label for="password">Passwort: </label><input type="password" id="password" name="password" minlength="4" maxlength="10" required><br><br>
                			<br><br>
                			
                			<!-- wenn value ausgewählt wurde, muss ein Eingabefeld für Zahlen eingeblendet werden -->
                			<?php if ($value): ?>		
                				<label for="<?=$valueRangeArray[0]->varname?>">Eingabe (<?=$valueRangeArray[0]->unit?>)<br>min. <?= $valueRangeArray[0]->min ?> / max. <?= $valueRangeArray[0]->max ?></label>
                				<input type="text" id="<?=$valueRangeArray[0]->varname?>" name="<?=$valueRangeArray[0]->varname?>" required>
                			<!-- <input type="text" id="data" name="data" required min="<?= $valueRangeArray[0]->min ?>" max="<?= $valueRangeArray[0]->max ?>"> -->
                				<br><br>
                			<?php endif; ?>
                               
                            <!-- wenn switch ausgewählt wurde, muessen select Felder her -->
                			<?php 
                				if ($switch) { renderSwitchRange($valueRangeArray); }
                			?>
                			              
                            <br><br>
                            <button type="submit">Senden</button>
                            <button type="button" onclick="cancelAction()">Abbrechen</button>
                        </form>
                        <hr style="width: 50%;">
                        <p id="timer-text">Timout: <span id="seconds">30</span>s</p>
                        <?php if ($message === "WRONG_PASSWORD"): ?>
                            <p style="color: red;">falsches Passwort!</p>
                        <?php endif; ?>
                    </div>
                <?php endif; ?>
                
                <script>
                	
                    let timeLeft = 30;
                    const timerSpan = document.getElementById('seconds');
                    const overlay = document.getElementById('overlay');
                
                    const countdown = setInterval(() => {
                        timeLeft--;
                        timerSpan.innerText = timeLeft;
                        if (timeLeft <= 0) {
                            clearInterval(countdown);
                            cancelAction();
                        }
                    }, 1000);
                    
                	// Timer bei Mausbewegung zurücksetzen (optional)
                	window.onmousemove = () => timeLeft = 30;
                
                	window.onload = resize();
                
                //########################################################################################################
                function resize() 
                {
                		// Ermittelt die benötigte Breite und Höhe des Inhalts
                		// scrollWidth/Height erfassen den gesamten Inhalt, auch wenn er versteckt ist
                		let contentWidth = document.documentElement.scrollWidth;
                		let contentHeight = document.documentElement.scrollHeight;
                
                		// Optional: Puffer für Browser-Rahmen/Scrollbars hinzufügen
                		window.resizeTo(contentWidth + 50, contentHeight + 200);
                }
                //########################################################################################################
                
                function cancelAction()
                {
                	window.close();
                }
                //########################################################################################################
                
                function singleSelect(actbox)
                {
                	const checkboxes = document.querySelectorAll('.single-select');
                	checkboxes.forEach((item) => {
                        if (item !== actbox) item.checked = false; // Alle anderen abwählen
                    });
                }
                //########################################################################################################
                
                </script>
                </body>
                </html>
                
                <?php
                function renderSwitchRange($valuerangearray) 
                {
                ?>
                <table class="value_ranges">
                <?php
                  for ($i=0; $i < count($valuerangearray); $i++):
                    $id = $valuerangearray[$i]->varname;
                    $text = $valuerangearray[$i]->text;
                    $set = $valuerangearray[$i]->set;
                ?>
                    <tr style="background-color:<?= $valuerangearray[$i]->bgcolor ?>">
                      <td>
                        <input class="single-select" type="checkbox" id="<?= $id ?>" name="<?= $id ?>" value="<?= $set ?>" <?= $i==0 ? "checked" : "" ?>  onclick="singleSelect(this)" />
                      </td>
                      <td>
                        <label for="<?= $id ?>"><?= $text ?></label>
                      </td>
                	</tr>	
                <?php
                   endfor;
                ?>
                  </table>
                <?php
                }
                
                

                Ich nutze jetzt bei Auswahl "switch" eine/mehrere checkboxen bei denen ich per JS eine Singleauswahl erzwinge.

                Als name und id übergebe immer den varnamen z.B. "T1.ws_regler_ein", was zu meinem nächsten Problem führt.

                Ich nehme den $_POST Rückgabewert, lese Schlüssel und Wert aus.

                foreach ($_POST as $key => $value) 
                			{
                				$receiveArray[$i] = htmlspecialchars($key);
                				$i++;
                				$receiveArray[$i] = htmlspecialchars($value);
                				$i++;
                			}
                	
                			$datatosave = "$receiveArray[4] = $receiveArray[5]"; 
                

                Somit erhalte ich bei [4] + [5] den Namen und Wert der ausgewählten Checkbox ... leider aber verändert.

                Ich trage als Name und id "T1.ws_regler_ein" erhalte aber von POST => "T1_ws_regler_ein" ... warum, es ist doch alles text/string? ... kann ich dies irgendwie verhindern, ohne tricksen zu müssen? (Punkt in Raute und später wieder zurück wandeln)

                Noch ein kleines Problem, beim ersten Aufruf des php-scriptes zeigt er im Browser-Debugger einen Fehler an, da das Array bzw. die Variable "$_SERVER["REQUEST_METHOD"]" noch nicht existiert. Wie könnte ich dies vermeiden.

                Vielen Dank !!

                1. Hallo Henry,

                  ich werde erst heute Abend dazu kommen, mir das anzuschauen. Derweil werden dich die anderen genüsslich zerfleischen 😉

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                  1. @@Rolf B

                    ich werde erst heute Abend dazu kommen, mir das anzuschauen. Derweil werden dich die anderen genüsslich zerfleischen 😉

                    Nein, das werden sie nicht. Weil es nichts gibt, worüber man hier reden könnte. Wo kann man sich das Problem denn ansehen? Bislang nirgendwo.

                    Und dafür werde ich nicht den henry genüsslich zerfleischen, sondern dich. Wenn du bei fehlendem Onlinebeispiel dir selbst das Problem nachstellst, erweist du dem Fragenden einen Bärendienst. Du sorgst dafür, dass du der einzige bist, der sich mit dem Problem beschäftigt.

                    Es sollte nicht jeder potentielle Helfer sich erst das Problem nachstellen müssen, sondern das ist Aufgabe des Fragestellers, das einmalig für alle zu tun. Und das sollte gleich am Anfang des Threads klargestellt werden: kein Onlinebeispiel – keine Hilfe.

                    🖖 Live long and prosper

                    --
                    In our chants of “ICE out now”
                    Our city’s heart and soul persists
                    Through broken glass and bloody tears
                    On the streets of Minneapolis

                    — Bruce Springsteen, Streets of Minneapolis
                    1. Hallo Gunnar,

                      Bei php Themen hilft mir kein Online-Beispiel. Ohne die Datenbank kann man das Script eh nicht selber laufen lassen, da kann man nur theoretisch schreiben.

                      Was das generierte HTML angeht, ist es anders, klar, aber da kann man auch einiges sagen ohne den Code live zu sehen.

                      Rolf

                      --
                      sumpsi - posui - obstruxi
                      1. @@Rolf B

                        Bei php Themen hilft mir kein Online-Beispiel.

                        Es gibt Online-PHP-Sandkästen, die auch speichern und teilen anbieten.

                        Aber PHP ist auch nur ein Teil hier im Thread. Es geht zum großen Teil um das generierte HTML, wo egal ist, ob statisch oder mit heißer Nadel gestrickt.

                        Und um das CSS, wo man schon gerne die visuelle Darstellung (und den Inspector in seinem Browser) hätte, um was dazu sagen zu können.

                        Und ums JavaScript. Wozu soll das eigentlich gut sein?

                        🖖 Live long and prosper

                        --
                        In our chants of “ICE out now”
                        Our city’s heart and soul persists
                        Through broken glass and bloody tears
                        On the streets of Minneapolis

                        — Bruce Springsteen, Streets of Minneapolis
                        1. Hallo Gunnar Bittersmann,

                          Es gibt Online-PHP-Sandkästen, die auch speichern und teilen anbieten.

                          Für eine DB-getriebene Seite?

                          Ok, er könnte das SELECT-Ergebnis als Array in den Code mocken.

                          Rolf

                          --
                          sumpsi - posui - obstruxi
                          1. @@Rolf B

                            Für eine DB-getriebene Seite?

                            Ok, er könnte das SELECT-Ergebnis als Array in den Code mocken.

                            Na klar.

                            Wenn es um Markup und Präsentation geht, ist nicht PHP-Code relevant, sondern das generierte HTML.

                            Wenn es um das HTML generierende PHP geht, sind nicht Datanbankabfragen relevant, sondern deren Resultat.

                            🖖 Live long and prosper

                            --
                            In our chants of “ICE out now”
                            Our city’s heart and soul persists
                            Through broken glass and bloody tears
                            On the streets of Minneapolis

                            — Bruce Springsteen, Streets of Minneapolis
                2. Hallo Henry,

                  • Du schreibst, dass Du die switch-Auswahl jetzt mit Checkboxen machst und mit JavaScript ein Radiobutton-Verhalten simulierst. Warum? Radiogruppen existieren und funktionieren. Wie Gunnar schrieb.

                  • Du schreibst, dass T1.ws_regler_ein beim POST zu T1_ws_regler_ein mutieren würde. Ja. TIL: PHP mag keine Spaces und keine Punkte in GET- und POST-Parametern. Wer PHP vor Version 4.1 gemacht hat, weiß warum. Darum wusste ich es nicht. In PHP 3 wurden GET und POST Parameter als globale Variablen registriert. Und in Variablennamen sind Punkt und Space nicht möglich, deshalb die Ersetzung in _. Nachdem genug PHP Seiten durch diesen Unfug gehackt wurden, brachte PHP 4.0 $HTTP_GET_VARS, aber nicht als Superglobal, und die Option register_globals, um nach Migration auf das neue Konzept das alte Verhalten abschalten zu können. Weil $_GLOBALS['HTTP_GET_VARS']einfach lästig war, brachte PHP 4.1 $_GET als Superglobal, und mit PHP 4.2 wurde register_globals bereits missbilligt. Dank der Trägheit der Entwickler zog es sich aber insgesamt 12 Jahre, bis in PHP 5.4 ernst gemacht wurde, seitdem muss man $_GET benutzen. Aber weil sich alle dran gewöhnt haben, dass Punkt und Space zu _ werden, konnte man diese Namensverwurstung wohl nicht loswerden, und die Idee, deshalb einen Schalter in die .ini zu pflanzen, fand auch keinen Anklang (hab ich bei der Recherche hierfür irgendwo gesehen). Dir bleibt nur übrig, vor dem Auslesen im varname die gleiche Ersetzung durchzuführen. Bspw. mit preg_replace("/[. ]/", "_", $varname)

                  • Du schreibst, es gebe die Notice, dass das Array bzw. die Variable $_SERVER["REQUEST_METHOD"] nicht existiert. Kannjagarnichtsein. $_SERVER und der Eintrag REQUEST_METHOD sind immer da, wenn PHP vom Webserver ausgeführt wird. Ich habe keine Ahnung, was da passiert. Oder... was ist der „Browser-Debugger“? Dieser Begriff ist mir fremd. Wird da das PHP möglicherweise nicht im Webserver-Kontext ausgeführt?

                  Zum PHP noch diese Hinweise:

                  • Du hast den catch(PDOException) auskommentiert, aber den try { dazu stehen gelassen
                  • PDOExceptions zu fangen bringt nichts, wenn du mysqli verwendest. Von mysqli bekommst Du eine mysqli_sql_exception, sofern Du mit dem Treiber nichts anderes aushandelst. Wenn Du PDOExceptions verwenden willst, musst Du PDO verwenden.
                  • "SELECT * FROM writecommands WHERE name ='".$name."'" ist verbesserungsbedürftig. Der $name sollte escaped werden, auch wenn er nicht vom User kommt, sondern allein unter deiner Kontrolle steht. Verwende mysqli_real_escape_string. Alternativ kann man mysqli_prepare verwenden, das lohnt aber für einmalig ausgeführte Statements eher nicht.
                  • Dass das Passwort im Klartext in deiner Datenbank steht, ist eine Todsünde. In die Datenbank gehört ein Hash des Passworts, den Du mit password_hash($klartext) erzeugst und dann mit password_verify($inputpwd, $hashFromDatabase) überprüfst. Der Teil, dass das Passwort falsch ist und $message auf WRONG_PASSWORD gesetzt wird, fehlt bei Dir eh noch 😉
                  • $receiveArray solltest Du vor der Abfrage auf die Reques-Methode initialisieren. PHP macht das zwar unter der Haube für Dich, wenn $receiveArray uninitialisiert ist, aber es ist generell schlechter Stil, uninitialisierte Variablen zu benutzen
                  • Statt $receiveArray[$i] = "..."; $i++; kannst Du einfach $receiveArray[] = "..." verwenden. Das hängt den neuen Wert hinten dran.
                  • Was machst Du mit $receiveArray? Du enumerierst das $_POST-Array und speicherst $key und $value als getrennte Werte im $receiveArray - welchem Zweck dient das?
                  • Im $receiveArray gezielt auf Position 4 und 5 zuzugreifen ergibt für mich keinen Sinn. Das ist extrem zerbrechlicher Code - ein neues Formfeld und die Indexe stimmen nicht. Verwende NAMEN. Mir scheint, dass Du in deinem Form immer nur zwei Dinge eingibst: Ein Passwort und einen Wert. Den Wert als Text-Input oder als Radiogruppe. Soll das so bleiben oder soll es später auch möglich sein, mehrere Werte einzugeben?
                  • Solange es nur ein Wert ist, kannst Du Dir das Leben vereinfachen. Verwende einen fixen Wert für das name-Attribut. Und zwar im $switch und im $value-Fall. Dann kannst Du den eingegebenen oder ausgewählten Wert stumpf unter bekanntem Namen in $_POST auslesen. Die ID für das Eingabefeld kann auch fix sein. Die IDs für die Radiobuttons musst Du auch nicht aus $varname herleiten, die kannst Du einfach durchnummerieren.
                  • Die Texte, die Du ausgibst, müssen grundsätzlich durch htmlspecialchars laufen. Und zwar nur vor der Ausgabe. Nicht nach Empfang aus $_POST, wie Du es beim $receiveArray machst. Die Nummer mit dem $receiveArray löst sich vermutlich eh in Luft auf, wenn Du mit einem fixen Namen für die Werteingabe arbeitest.
                  • Das hidden input mit name="action" und value="submit" ist redundant. Gib dem Submit-Button diesen Namen und diesen Value. Fertig.

                  Rolf

                  --
                  sumpsi - posui - obstruxi
              2. @@Rolf B

                Du bekommst name=value, wenn in einem Form mit der Radiogroup

                Eine Gruppe von Radiobuttons sollte i.d.R. auch als solche im Markup ausgezeichnet werden. Und damit meine ich nicht (nur) das name-Attribut, sondern ein fieldset drumherum. Dessen legend-Element wird von Screenreadern zusätzlich zum Label der Radiobuttons angesagt.

                <input type="radio" id="foo-1" name="foo" value="dings"><label for="foo-1">Dings</label>
                <input type="radio" id="foo-2" name="foo" value="bums"><label for="foo-2">Bums</label>
                <input type="radio" id="foo-3" name="foo" value="tra"><label for="foo-3">Tra</label>
                <input type="radio" id="foo-4" name="foo" value="lala"><label for="foo-4">Lala</label>
                

                So möchte man den Code kaum haben, sondern <input> und <label> jeweils in einer Zeile. Das bisschen mehr Zwischenraum zwischen Radiobutton und Beschriftung tut der visuellen Darstellung auch gut.

                Wenn man mit Maus o.a. Pointer nicht auf Radiobutton oder Beschriftung, sondern auf den Zwischenraum clickt, soll trotzdem der Radiobutton aktiviert werden. Derhalb empfielt es sich, bei Radiobuttons und Checkboxen das <input>-Element in das <label>-Element zu schachteln. (Spart Rumgemache mit CSS.)

                <fieldset>
                  <legend>Entdecke die Möglichkeiten:</legend>
                  <label for="foo-1">
                    <input type="radio" id="foo-1" name="foo" value="dings">
                    Dings
                  </label>
                  <label for="foo-2">
                    <input type="radio" id="foo-2" name="foo" value="bums">
                    Bums
                  </label>
                  <label for="foo-3">
                    <input type="radio" id="foo-3" name="foo" value="tra">
                    Tra
                  </label>
                  <label for="foo-4">
                    <input type="radio" id="foo-4" name="foo" value="lala">
                    Lala
                  </label>
                </fieldset>
                

                Da die Radiobuttons untereinander stehen sollen, tut das sowieso sinnvollerweise im Stylesheet stehende

                label {
                  display: block;
                  width: fit-content;
                }
                

                auch hier seinen Dienst.

                🖖 Live long and prosper

                --
                In our chants of “ICE out now”
                Our city’s heart and soul persists
                Through broken glass and bloody tears
                On the streets of Minneapolis

                — Bruce Springsteen, Streets of Minneapolis
          2. @@Rolf B

            • min und max können auch am input eingestellt werden. Wirken aber meines Wissens nur für ein numerisches Input. Wenn Du Zahlen erwartest, wäre input type="numeric" eh besser.

            Nö, das würde rein gar nichts bewirken. Da Browser diesen Typen nicht kennen, ignorieren sie die Angabe und verwenden den Defaulttypen "text".

            Du meinst <input type="number"/>.

            🖖 Live long and prosper

            --
            In our chants of “ICE out now”
            Our city’s heart and soul persists
            Through broken glass and bloody tears
            On the streets of Minneapolis

            — Bruce Springsteen, Streets of Minneapolis
        2. @@der henry

                      <label for="password">Passwort: </label><input type="password" id="password" name="password" minlength="4" maxlength="10" required><br><br>
          			<br><br>
          

          Henry! HENRY! Da ist so ein Geräusch![1]

          <br> ist nicht zum Erzeugen von Abstand da. Dafür gibt es CSS (margin, padding).


          Fun fact: Ich bin gerade zufällig auf Heydon Pickerings Artikel The br element gestoßen. ROTFL:

          This is all made slightly more complex and off-putting by the fact that, in HTML, you don’t actually have to self-close self-closing elements. You can leave the slash out like this: <br>. In XHTML—which is a syntactically stricter hybrid of HTML and XML—removing a slash from a <br/> would be like removing the lead guitarist Slash from the band Guns ‘n’ Roses: a lot of dorks would complain loudly and incessantly. Fortunately, nobody really uses XHTML anymore, like nobody really listens to Guns ‘n’ Roses.

          🖖 Live long and prosper

          --
          In our chants of “ICE out now”
          Our city’s heart and soul persists
          Through broken glass and bloody tears
          On the streets of Minneapolis

          — Bruce Springsteen, Streets of Minneapolis

          1. Jan und Henry ↩︎