AnHa: table cell mengen werte vergleichen

Hallo Forumer,

ich hoffe Ihr könnt mir bei einem kleinen Problem helfen. Ich lerne gerade PHP in der Schule. Hier muss ich ein kleines Projekt (Minishop)erstellen und komme gerade nicht so richtig weiter. Mein Problem: Ich befülle über ein mehrdimensionales assoziatives Array eine Tabelle (Menge, Artikel,Preis etc.). Jetzt habe ich zwei weitere Zellen hinzugefügt (ein Inputfeld & ein Submitbutton). In der ersten der beiden Zellen (Input) möchte ich gerne, dass der User eine Menge eintragen kann, diese darf aber nicht höher sein als die Menge aus dem Array (Menge Zelle1) bzw. nicht ins Minus gehen. Des Weiteren sollten sich die Mengen nach Klick auf den Button aktualisieren.
Ich stehe hier irgendwie auf dem Schlauch. Evtl. könnt Ihr Profis mir auf die Sprünge helfen.

Danke vorab.

Grüße Andreas

  1. Tach!

    Ich befülle über ein mehrdimensionales assoziatives Array eine Tabelle (Menge, Artikel,Preis etc.). Jetzt habe ich zwei weitere Zellen hinzugefügt (ein Inputfeld & ein Submitbutton). In der ersten der beiden Zellen (Input) möchte ich gerne, dass der User eine Menge eintragen kann, diese darf aber nicht höher sein als die Menge aus dem Array (Menge Zelle1) bzw. nicht ins Minus gehen.

    Es gibt <input type=number>, das mit min und max daherkommt. Den Minimalwert kannst du fest auf 0 setzen, den Maximalwert entsprechend deiner Datenhaltung.

    Es empfiehlt sich, eine grundlegende Struktur in ein Projekt zu bringen. Das einfachste ist das EVA-Prinzip. Das trennt die Teile Eingabe, Verarbeitung und Ausgabe. Insbesondere sollte die Verarbeitung unabhängig von einer späteren Ausgabe erfolgen. Dieser Teil sammelt und berechnet lediglich alle für die Ausgabe benötigten Daten. Wenn man beispielsweise die Summe der Dinge im Warenkorb berechnen möchte, muss man dazu nicht beachten, an welcher Stelle diese Summe später in der Ausgabe landet. Es wird lediglich de Summe ermittelt und in einer Variablen oder anderweitig geeigneten Datenstruktur abgelegt.

    Des Weiteren sollten sich die Mengen nach Klick auf den Button aktualisieren.

    Hier könnte die Technik namens Affenformular zum Einsatz kommen.

    dedlfix.

    1. @@dedlfix

      Es gibt <input type=number>, das mit min und max daherkommt. Den Minimalwert kannst du fest auf 0 setzen, den Maximalwert entsprechend deiner Datenhaltung.

      Ergänzend der Hinweis, dass eine clientseitige Validierung von Eingabedaten ein nützlicher Zusatz ist, um die User Experience zu verbessern. Die serverseitige Prüfung muss aber trotzdem erfolgen.

      LLAP 🖖

      --
      „Man kann sich halt nicht sicher sein“, sagt der Mann auf der Straße, „dass in einer Gruppe Flüchtlinge nicht auch Arschlöcher sind.“
      „Stimmt wohl“, sagt das Känguru, „aber immerhin kann man sich sicher sein, dass in einer Gruppe Rassisten nur Arschlöcher sind.“

      —Marc-Uwe Kling
  2. Hallo Andreas,

    du hast also ein PHP Script, das eine HTML Seite darstellt. Diese Seite klingt nach einem Warenkorb. Der Warenkorb zeigt eine Bestellmenge, den bestellten Artikel und den Preis an.

    Im PHP Script repräsentierst Du diesen Warenkorb durch ein "mehrdimensionales assoziatives Array".

    Nun hast Du im HTML pro Bestellposition ein Eingabefeld hinzugefügt, um die Menge zu ändern, richtig? Hast Du den Submitbutton ebenfalls pro Position gemacht, oder für die ganze Liste? Davon hängt die Vorgehensweise ab.

    Was mir in deiner Beschreibung fehlt, ist noch die Frage nach der Herkunft des Arrays, und die Frage, wo das Array verbleibt, während der Anwender den Warenkorb auf dem Bildschirm hat. Denn Dir ist hoffentlich klar, dass PHP nicht Visual Basic ist. Das heißt: jeder Submit löst einen neuen PHP Request aus, und der neue Request weiß vom vorigen Request nur das, was der Client mitsendet oder was Du Dir ausdrücklich anderswo (Session oder Datenbank) gemerkt hast.

    Grundsätzlich ist es so, dass Du die Eingabefelder zur Änderung der Menge einer Bestellposition dem richtigen Array-Eintrag zuordnen können musst. Dafür braucht es eine Art von ID. Diese könnte in das name-Attribut des input-Feldes hineingeschlüsselt sein (wenn Du mehrere Mengen auf einmal ändern können willst), oder du machst pro Zeile ein eigenes Form, dann kannst Du die ID auch über ein hidden input oder über die URL der Form Action übermitteln. Konkreter kann ich ohne genauere Kenntnis deines Projekts, und dessen, was Du schon gebaut hast, kaum werden.

    Rolf

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

      vielen Dank für deine ausführliche Antwort. Ich habe tatsächlich für jede Bestellposition eine Mengeneingabe und ein Submitbutton eingefügt. Das Array der Artikel ist in eine seperaten PHP-Datei ausgelagert. Zudem gibt es noch eine weitere seperate Datei in der die Funktionen hinterlegt sind (so haben wir es bis dato gelernt). Ich poste mal den Code der Dateien. Ziel des Projektes ist es, dass der User den Warenkorb befüllt, seine Summe der bestellten Artikel sieht und dann zu einem Login-Formular weitergeleitet wird. Falls er noch nicht registriert wurde soll die Weiterleitung auf eine Registierungsseite erfolgen......soweit der Plan.

      index.php

      index.php
      
      <?php require_once 'Funktionen/func_artikel.php'; ?>
      <?php require_once 'artikel.php'; ?>
      
      <!DOCTYPE html>
       <html>
           <head>
               <meta charset="UTF-8">
               <title>Computer-Store</title>
           </head>
           <body>
               <h1>  
               <?php echo 'Willkommen in unserem Computerladen';?></h1>
               <h2><?php echo 'Ihrem Onlineshop rund um den PC!';?>  </h2>
               <h3>
               <?php echo 'Hier finden Sie eine große Auswahl an günstigen Artikeln';?>    
               </h3>
               <br>
               <br>
               <table border ="2" >
                  <tr>
                      <th>Menge</th>
                      <th>Artikel</th>
                      <th>Preis</th>
                      <th>Gesamtpreis</th>
                      <th>Mehrwertsteuer<br>je Artikel</th>
                      <th>Mehrwertsteuer<br> gesamt</th>
                  </tr>
                   
                  <?php
                  $Summe_Netto = 0;
                  foreach ($artikel_array as $artikel) {
                      $gp_netto = rechneGesamtpreisArtikel($artikel['Preis'], $artikel['Menge']);  
                      $Summe_Netto += $gp_netto;
                      $mwst_netto = berechneMwst ($artikel['Preis'], $artikel['Mwst']);
                      $gp_mwst_netto = berechne_gp_Mwst ($artikel['Menge'], $mwst_netto);   
                  ?>
                   
                  <tr>
                      <td><?php echo $artikel['Menge']; ?> Stück</td>
                      <td><?php echo $artikel['Name']; ?></td>
                      <td><?php echo number_format($artikel['Preis'], 2,",","."); ?> €</td>
                      <td><?php echo number_format($gp_netto, 2, ",", ".");?> €</td>   
                      <td><?php echo number_format($mwst_netto, 2, ",", ".");?> €</td>
                      <td><?php echo number_format($gp_mwst_netto, 2, ",", ".");?> €</td>   
                      <td><input type="number" name="bestellmenge" value=<?php echo $artikel['Menge']; ?>></td>
                      <td><input type="submit" name="warenkorb" value="In den Warenkorb"></td>
                  </tr>
                   
                  <?php } ?>
                  
              </table>
           </body>
       </html>    
      
      func_artikel.php
      <?php
              
              function rechneGesamtpreisArtikel($preis_artikel, $menge_artikel) {
                  return $preis_artikel * $menge_artikel;            
                  
              } 
              
              function berechneMwst ($preis_artikel, $mehrwertsteuer) {
                  return $preis_artikel * $mehrwertsteuer /100;           
              }  
      
              function berechne_gp_Mwst ($menge_artikel, $mehrwertsteuer_artikel) {
                  return $menge_artikel * $mehrwertsteuer_artikel;          
              }  
          
      ?>
      
      artikel.php
      <?php require_once 'Funktionen/func_artikel.php';?>
      
      <?php
      
      $artikel_array = array(
                  array(
                      'Menge' => 5,
                      'Name' => 'Computerzeitschrift',
                      'Preis' => 12.95,
                      'Mwst' => 7
                  ),
                  array(
                      'Menge' => 1,
                      'Name' => 'Computer',
                      'Preis' => 799,
                      'Mwst' => 19
                  ),
                  array(
                      'Menge' => 25,
                      'Name' => 'Tastatur',
                      'Preis' => 24.50,
                      'Mwst' => 19
                  ),
                  array(
                      'Menge' => 80,
                      'Name' => 'Maus',
                      'Preis' => 9,
                      'Mwst' => 19
                  ),
                  array(
                      'Menge' => 16,
                      'Name' => 'Bildschirm',
                      'Preis' => 247.50,
                      'Mwst' => 19
                  ),
                  array(
                      'Menge' => 7,
                      'Name' => 'Drucker',
                      'Preis' => 139.75,
                      'Mwst' => 19
                  ),
                  array(
                      'Menge' => 5,
                      'Name' => 'Arbeitsspeicher 8 GB RAM',
                      'Preis' => 59.95,
                      'Mwst' => 19
                  ),
                  array(
                      'Menge' => 2,
                      'Name' => 'Arbeitsspeicher 32 GB RAM',
                      'Preis' => 104.95,
                      'Mwst' => 19
                  ),
                  array(
                      'Menge' => 3,
                      'Name' => '500 GB Festplatte',
                      'Preis' => 49.95,
                      'Mwst' => 7
                  ),
                  array(
                      'Menge' => 5,
                      'Name' => '1 TB Festplatte',
                      'Preis' => 85.00,
                      'Mwst' => 7
                  ),
              );
      ?>
      
      1. Hallo Andreas,

        da hast Du noch einiges zu tun. Dass Du auf dem Schlauch draufstehst, erklärt nicht, warum kein Wasser rauskommt. Dir fehlt noch der Wasserhahn, dessen Zuleitung und die Hälfte des Wasserwerks.

        Ganz wichtiges Zubehör für den Werkzeugkasten: PHP Sessions. Spätestens beim Weiterleiten zur Registrierungsseite wird es ohne Sessions sehr umständlich bis unmöglich.

        Eine Bemerkung vorab: Erwarte nicht, eine Lösung vorprogrammiert zu bekommen.

        Zunächst ein paar Hinweise zum HTML:

        • das html Element bekommt ein lang="de" Attribut
        • Es ist überflüssig, konstante Texte von PHP aufbereiten zu lassen, das geht einfacher.
        <h1>Willkommen in unserem Computerladen</h1>
        <h2>Ihrem Onlineshop rund um den PC!</h2>
        <h3>Hier finden Sie eine große Auswahl an günstigen Artikeln</h3>
        
        • es ist falsch (darum ist das Beispiel rot), Header-Elemente (h1, h2, h3) allein wegen der zugeordneten Schriftgröße zu verwenden. Header-Elemente dienen der Gliederung des Dokumentes. Wenn Du nichts zu gliedern hast, gehören auch keine Überschriften dahin. Verwende statt dessen p Elemente, und wenn sie verschiedene Schriftgrößen haben sollen, dann verwende CSS, um die Darstellung zu beeinflussen. In deinem Fall wäre es ein Titel und ein Untertitel, sowie ein Erklärtext.
        <header>
        <h1>Willkommen in unserem Computerladen</h1>
        <p>Ihr Onlineshop rund um den PC!</p>
        </header>
        <p>Hier finden Sie eine große Auswahl an günstigen Artikeln</p>
        

        das kannst Du mit CSS z.B. so gestalten, um dem h1 im Header-Bereich doppelte Basisschriftgröße zu geben (was auch entfallen kann weil ein h1 eh eine große Schrift hat), und dem p im Header-Bereich die anderthalbfache Schriftgröße:

        header h1 {
           font-size: 2rem
        }
        header p {
           font-size: 1.5rem
        }
        

        Das CSS kannst Du entweder in einem <style> Element des <head> unterbringen, oder in einer eigenen shop.css Datei, die Du im <head> mit <link href="/css/shop.css" rel="stylesheet"> einbindest (die href-Angabe musst Du natürlich für deine Zwecke anpassen).

        • Dort kannst Du auch der table einen Rand geben. border="2" bedeutet zwei Pixel Rand, und die Zellen bekommen automatisch einen dünnen Rand dazu. Das border-Attribut des <table> Elements ist veraltet.

        Jetzt zum PHP

        • Die Ausgabe von einfachen Werten mit <?php echo $dings; ?> ist umständlich. Dafür kennt PHP die Kurzform <?= $dings ?>

        • Warum bindest Du in artikel.php die Funktionensammlung ein? Die brauchst Du dort doch gar nicht.

        • Es ist üblich und sinnvoll, in reinen Code-Dateien (func_artikel.php und artikel.php) das abschließende ?> wegzulassen. Grund: Alles, was hinter ?> folgt, wird von PHP an den Browser geschickt. Auch eine Leerstelle oder ein Zeilenumbruch. Das kann aus verschiedenen Gründen Ärger machen. Die Details führen jetzt zu weit; nimm es bitte als Empfehlung an.

        • Ich nehme an, dass Du aus Gründen der Einfachheit die jetztige Artikelliste als "Katalog" nutzen willst, wo man einfach die gewünschte Menge einträgt. Es ist aber eigentlich merkwürdig (finde ich), in der Tabelle links die bereits eingetragene Menge anzuzeigen und rechts ein Eingabefeld zum Ändern der Menge zu platzieren. Guck Dir Amazon an. Die haben NUR das Eingabefeld, das ist Ausgabe der aktuellen Menge und Du kannst es überschreiben, um die Menge zu ändern. Oder ich missverstehe deine Oberfläche...

        • Die Benutzereingabe muss zum Server gesendet werden können. Das geht (für den Einstieg) nur, wenn ein <form> Element verwendet wird. Du musst deine Table in ein <form> einschließen:

        <form method="post" action="index.php">
           <table>
           ...
           </table>
        </form>
        
        • Es ist nicht sinnvoll, jeder Zeile einen eigenen Button zu geben. Vielleicht möchte der Anwender mehrere Werte auf einmal ändern? Deswegen sollte es nur einen Submit-Button geben, der unter der Tabelle steht.

        • Wenn Du nun submit drückst, wird ein neuer HTTP Request an den Server geschickt. Im Gegensatz zum einfachen Seitenabruf mit dem Browser ist dies aber kein GET Request, sondern ein POST Request (steht im form: method="post"). Das kannst Du im PHP abfragen, indem Du $_SERVER['REQUEST_METHOD'] prüfst. Darin steht GET oder POST. Bei GET wurde die Seite vom Kunden aufgerufen, und alle Mengen sind 0. Beim POST wurde etwas ausgefüllt, und es sind Mengen da.

        • Die Frage ist nun, wie Du die eingegebenen Werte deinen Artikeln zuordnest. Dazu musst Du überhaupt erstmal die Werte einzeln bekommen. So, wie es jetzt ist, bekommst Du nur die Bestellmenge zum letzten Artikel. Verwende im input Feld name="bestellmenge[]". Dann macht PHP da ein Array draus, mit einem Eintrag pro Eingabefeld. Nach einem POST findest Du es in $_POST['bestellmenge']. Für eine simple Übung kannst Du die Zuordnung über die Position machen, d.h. der x-te Eintrag in $artikel_array hat seine Bestellmenge im x-ten Eintrag von $_POST['bestellmenge'].

        • Lass für die Ausgabe eine for-Schleife laufen (for ($zeile=0; $zeile<count($artikel_array); $zeile=$zeile+1)), und dann findest Du die Bestellmenge von $artikel_array[$i] in $_POST['bestellmenge'][$i]. Daraus kannst Du dann den Gesamtpreis für diese Position bestimmen und die Gesamtmehrwertsteuer, und du kannst aufsummieren für den Bestellwert.

        • Zusätzlich zum "Speichern" Button machst Du noch einen "Zur Bestellung" Button. Der macht ebenfalls einen POST, führt aber zur Registrierung und Adresseingabe. Ab jetzt wird's knifflig, denn entweder steuerst du das alles über das gleiche PHP Script (das geht durchaus, macht das Script aber gewaltig groß), oder Du bekommst irgendwann Probleme mit der Speicherung der geposteten Daten. Du solltest daher die Bestellmengen in der Session des Anwenders speichern. Dann kannst Du das formaction-Attribut des "Zur Bestellung" Buttons verwenden, um zur Registrierseite zu kommen, läufst aber Gefahr, dass ältere Browser (älter als Internet Explorer 10) das nicht verstehen. Als Fallback musst Du im index.php prüfen, ob dieser Button geklickt wurde, und dann eine Weiterleitung auslösen (header('location:...').

        Rolf

        --
        sumpsi - posui - clusi
        1. Hi there,

          Es ist nicht sinnvoll, jeder Zeile einen eigenen Button zu geben. Vielleicht möchte der Anwender mehrere Werte auf einmal ändern? Deswegen sollte es nur einen Submit-Button geben, der unter der Tabelle steht.

          Das kann man generell so nicht sagen und hängt imho vom Anwendungsfall ab. Auf alle Fälle aber wäre so etwas in der Praxis nur mehr mit Ajax sinnvoll zu realisieren und insoferne ist Deine Kritik an einem Beispiel, das offensichtlich ohne selbiges auskommen soll, berechtigt...

          1. Hallo klawischnigg,

            Ajax

            auch da würde ich bei einem einzigen "Speichern" Button bleiben, und den als Fallback für nicht aktives JavaScript verwenden. Wenn JS da ist, macht es progressive enhancement, versteckt den Button und registriert sich auf's change-Event des Forms. Dort blubbern die changes der Eingabefelder vorbei, werden per Ajax zum Server geschickt und lösen ggf. Aktualsierungen in der Zeile aus, wo das change Event hergeblubbert kam. Ohne JS wird über den Button das Form gepostet.

            Einen Button pro Zeile würde ich für Action-Buttons (Löschen o.Ä. in Erwägung ziehen).

            Für Andreas ist das aber der Overkill.

            Rolf

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

      Das heißt: jeder Submit löst einen neuen PHP Request aus

      Einen PHP-was?

      Du meinst einen HTTP-Request, woraufhin serverseitig ein PHP-Script losackert?

      LLAP 🖖

      --
      „Man kann sich halt nicht sicher sein“, sagt der Mann auf der Straße, „dass in einer Gruppe Flüchtlinge nicht auch Arschlöcher sind.“
      „Stimmt wohl“, sagt das Känguru, „aber immerhin kann man sich sicher sein, dass in einer Gruppe Rassisten nur Arschlöcher sind.“

      —Marc-Uwe Kling