PHP

Web o webu

Uložení a mazání dat

Administrace dat - vložení nového záznamu, upravení a smazání záznamu

administrace.zip

Na stránku provádějící mazání (DELETE) či změnu (UPDATE) dat povede odkaz z výpisu dat s předáním id záznamu metodou get - viz předchozí kapitola.

Ukázka výpisu pro administraci dat

Objektové metody pro změnu dat

Schématický postup mazání, vkládání či provedení změny daného záznamu:

  1. new mysqli - připojení k databázi - include souboru spojeni.php
  2. set_charset - nastavení UTF8 - v souboru spojeni.php
  3. !isset - zjištění zda ještě nebyl odeslán formulář ($_POST)
    • když nebyl ještě odeslán formulář - pro INSERT:
      1. vytvoření formuláře pro zadání dat
    • když nebyl ještě odeslán formulář - pro DELETE a UPDATE:
      1. prepare - připravení dotazu SELECT s podmínkou pro id - načtení daného záznamu
      2. bind_param - přiřazení parametru $_GET["id"] do podmínky
      3. bind_result - přiřazení výstupních proměnných
      4. execute - spuštění dotazu
      5. fetch - bez cyklu - načtení 1 záznamu do výstupních proměnných
      6. close - uzavření dotazu
      7. zobrazení záznamu
        - při DELETE - vypsání údajů a vytvoření formuláře s tlačítkem Smazat,
        - při UPDATE - vložení údajů do editačního formuláře
    • když byl odeslán formulář:
      1. kontrola odeslaných dat (neprázdné povinné údaje, příp. kontrola regulárními výrazy) (pouze UPDATE a INSERT)
      2. vytvoření chybějících hodnot (nezaškrtnutý checkbox apod.) (pouze UPDATE a INSERT)
      3. prepare - připravení dotazu DELETE nebo UPDATE s podmínkou WHERE pro id nebo dotazu INSERT
      4. bind_param - přiřazení vstupních proměnných (pouze pro UPDATE a INSERT) a $_GET["id"] (pouze UPDATE a DELETE)
      5. execute - spuštění dotazu - v podmínce - vypsání zprávy o úspěšném či neúspěšném provedení
      6. close - uzavření dotazu
      7. odkaz zpět na výpis, případně na vložený či upravený záznam

Smazání záznamu - DELETE

Na stránku smazani.php vede odkaz z výpisu, který stránce prostřednictvím odkazu předá id záznamu, který má být smazán - viz výše Ukázka výpisu pro administraci dat.

Stránka nejprve zobrazí daný záznam (obdobně jako vypis_detail.php) s formulářem, který obsahuje pouze tlačítko Smazat. Po kliknutí na tlačítko dojde k vymazání záznamu z tabulky.

Ukázka kódu pro zobrazení zvoleného záznamu a jeho smazání

<h1>Smazání zvoleného záznamu</h1>
<?php
include 'spojeni.php'; // 1 - vytvoření objektu $spojeni a 2 - nastavení UTF-8

// 3 - zjištění zda byl odeslán formulář - metoda POST, smazat je name tlačítka
if(!isset($_POST["smazat"])) {
  // když $_POST["smazat"] neexistuje - nebylo odesláno - načtení a zobrazení záznamu
  // 3.1 - připravení dotazu s podmínkou pro id - načtení daného záznamu
  $dotaz=$spojeni->prepare("SELECT kategorie.kategorie,vyrobci.nazev,vyrobky.nazev,
                            cena,skladem,stav,popis FROM vyrobky
                            JOIN kategorie ON vyrobky.id_kategorie=kategorie.id
                            JOIN vyrobci ON vyrobky.id_vyrobce=vyrobci.id
                            WHERE vyrobky.id=? LIMIT 1");
  // 3.2 - přiřazení parametru $_GET["id"] do podmínky
  $dotaz->bind_param("i",$_GET["id"]);
  // 3.3 - přiřazení výstupních proměnných
  $dotaz->bind_result($kategorie,$znacka,$nazev,$cena,$skladem,$stav,$popis);
  $dotaz->execute();  // 3.4 - spuštění dotazu
  $dotaz->fetch();    // 3.5 - načtení záznamu do výstupních proměnných - bez cyklu
  $dotaz->close();    // 3.6 - uzavření dotazu
  // 3.7 - vypsání údajů a vytvoření formuláře s tlačítkem Smazat
  echo "<h2>$nazev - $cena Kč</h2>";
  echo "<p>$kategorie - $znacka</p>";
  if($skladem==1){echo "<p>Zboží je skladem</p>";}
    else {echo "<p>Zboží není skladem</p>";}
  switch($stav){
    case 'n': echo "<p>Nové zboží</p>"; break;
    case 'r': echo "<p>Rozbalené zboží</p>"; break;
    case 'o': echo "<p>Opravené zboží</p>"; break;
    case 'v': echo "<p>Vystavené zboží</p>"; break;
  }
  echo "<p>$popis</p>";
  echo "<form method='post'>
        <a href='vypis_administrace.php'>Zpět</a>
        <input type='submit' name='smazat' value='Smazat'>
        </form>";
} // konec části 3
else {
  //formulář byl odeslán - smazat - name odesílacího tlačítka
  // 4.3 - připravení dotazu pro smazání záznamu s daným id
  $dotaz=$spojeni->prepare("DELETE FROM vyrobky WHERE id=?");
  // 4.4 - přiřazení vstupního parametru id
  $dotaz->bind_param("i",$_GET["id"]);
  // 4.5 - spuštění dotazu - v podmínce - pokud se provede, vrací true
  if($dotaz->execute()) {echo "<h2>Záznam byl smazán</h2>\n"; }
  else {echo "<h2 class='chyba'>Záznam nebyl smazán</h2>\n";}
  // 4.6 uzavření dotazu
  $dotaz->close();
  // 4.7 - odkaz zpět na výpis
  echo "<p><a href='vypis_administrace.php'>«&nbsp;Zpět na výpis</a></p>";
  }
?>

Vložení nového záznamu - INSERT

Formulář pro vložení záznamu může obsahovat textová pole, číselná pole, přepínače, zaškrtávací pole, výběrová pole apod. - viz HTML - Formuláře.

Ukázka formuláře pro vložení výrobku

Pro výběr hodnoty z přidružené tabulky (např. kategorie nebo výrobce) vytvoříme výběrové pole <select> s položkami <option> načtenými z tabulky databáze. Hodnotou položky (value) bude primární klíč (obvykle id).

Načtení a vypsání těchto položek provedeme obdobně jako výpisy popsané v předchozí kapitole. Databázový dotaz však bude načítat data pouze z jedné přidružené tabulky bez propojení s hlavní tabulkou (SELECT bez JOIN).

Ukázka kódu pro vytvoření formuláře a vložení nového výrobku do vzorové databáze

<h1>Vložení nového záznamu do tabulky vyrobky</h1>
<?php
include 'spojeni.php'; // 1 - vytvoření objektu $spojeni a 2 - nastavení UTF-8

// 3 - zjištění zda byl odeslán formulář - metoda POST, ulozit je name tlačítka
if(!isset($_POST["ulozit"])) {
  // když $_POST["ulozit"] neexistuje - formulář ještě nebyl odeslán
  // 3.1 - vytvoření formuláře pro zadání dat
  ?>
  <form method="post" onsubmit="return kontrola()">
  <label>Kategorie</label>
  <select name="kategorie">
    <option value="">&nbsp;</option>
    <?php
      $dotaz=$spojeni->prepare("SELECT id,kategorie FROM kategorie ORDER BY kategorie");
      $dotaz->bind_result($id,$kategorie);
      $dotaz->execute();
      while($dotaz->fetch()) {
        echo "<option value='$id'>$kategorie</option>\n";
      }
      $dotaz->close();
    ?>
  </select><br>
  <label>Výrobce</label>
  <select name="vyrobce">
    <option value="">&nbsp;</option>
    <?php
      $dotaz=$spojeni->prepare("SELECT id,nazev FROM vyrobci ORDER BY nazev");
      $dotaz->bind_result($id,$nazev);
      $dotaz->execute();
      while($dotaz->fetch()) {
        echo "<option value='$id'>$nazev</option>\n";
      }
      $dotaz->close();
    ?>
  </select><br>

  <label>Název výrobku</label><input type="text" name="nazev" maxlength="30"><br>
  <label>Cena bez DPH</label><input type="number" name="cena" min="1"><br>
  <label>Skladem</label><input type="checkbox" name="skladem" value="1"><br>
  <label>Stav zboží</label><input type="radio" name="stav" value="n"> nové
                           <input type="radio" name="stav" value="o"> opravené
                           <input type="radio" name="stav" value="v"> vystavené<br>
  <label>Popis</label><br><textarea name="popis"></textarea><br>
  <input type="submit" name="ulozit" value="Uložit">
  </form>

  <?php
} // konec části 3 - konec formuláře pro zadání dat
else {  // 4 - $_POST["ulozit"] existuje - formulář byl odeslán
  // 4.1 - kontrola dat - prázdné povinné údaje nebo data neodpovídajícího formátu
  $zprava=""; //zůstane-li prázdná, můžou se data uložit
  if($_POST["kategorie"]=="") {$zprava.="Nebyla zadána kategorie. ";}
  if($_POST["vyrobce"]=="") {$zprava.="Nebyl zadán výrobce. ";}
  if($_POST["nazev"]=="") {$zprava.="Nebyl zadán název. ";}
  //cenu můžeme zkontrolovat funkcí is_numeric nebo regulárním výrazem
  //if($_POST["cena"]==""||!is_numeric($_POST["cena"])){$zprava.="Nebyla zadána cena.";}
  if(!preg_match("/^[0-9]{1,}$/",$_POST["cena"])) {$zprava.="Nebyla zadána cena. ";}
  //nezvolené radio nevytvoří proměnnou - neřešíme zda je prázdná, ale !isset
  if(!isset($_POST["stav"])){$zprava.="Nebyl určen stav výrobku. ";}

  if($zprava!="") {
    echo "<h2 class='chyba'>Data nemohla být vložena</h2> <h3 class='chyba'>$zprava</h3>
          <a href='vlozeni.php' class='tlacitko'>Zadat záznam znovu</a>";
  } else {
    // když je $zprava prázdná - všechny údaje byly v pořádku
    // 4.2 - vytvoření proměnné - nezaškrtnutý checkbox nevytvoří proměnnou
    if(!isset($_POST["skladem"])){$_POST["skladem"]=0;}
    // 4.3 - připravení dotazu pro vložení záznamu do tabulky
    $dotaz=$spojeni->prepare("INSERT INTO vyrobky (id_kategorie,id_vyrobce,nazev,
                              cena,skladem,popis) VALUES(?,?,?,?,?,?)");
    // 4.4 - přiřazení vstupních parametrů za otazníky (i-integer, s-string, d-double)
    $dotaz->bind_param("iisiis",$_POST["kategorie"],$_POST["vyrobce"],$_POST["nazev"],
                                $_POST["cena"],$_POST["skladem"],$_POST["popis"]);
    // 4.5 - spuštění dotazu - v podmínce - pokud se provede, vrací true
    if($dotaz->execute()) {
      echo "<h2>Data byla vložena</h2>";
      $id=$dotaz->insert_id;  //id vloženého záznamu
      echo "<a href='zobrazeni.php?id=$id' class='tlacitko'>Zobrazit záznam</a>";
      echo "<a href='vlozeni.php' class='tlacitko'>Vložit další záznam</a>";
    }
    else {echo "<h2 class='chyba'>Data nebyla vložena</h2>".$dotaz->error;}
    // 4.6 uzavření dotazu
    $dotaz->close();
    // 4.7 - odkaz zpět na výpis
    echo "<p><a href='vypis_administrace.php'>«&nbsp;Zpět na výpis</a></p>";
  }
}
?>

Formulář doplníme funkcí JavaScriptu, která se spustí při odeslání formuláře (onsubmit) a která stejně jako php skript provede kontrolu odesílaných dat. Tato kontrola je spuštěna v internetovém prohlížeči, ještě před odesláním dat formuláře na server. V případě, že data nebudou v pořádku, může funkce zastavit odeslání dat. Díky tomu nedojde k opuštění stránky s formulářem a tedy vymazání vyplnění dat. Jelikož však funkce JavaScriptu mohou být v prohlížeči vypnuté, musí být provedena kontrola i v php.

Volání funkce musí být s klíčovým slovem return - čekání na návratovou hodnotu funkce (funkce vrací true nebo false):

<form method="post" onsubmit="return kontrola()">

Ukázka JavaScriptové funkce pro kontrolu dat před odesláním

<script type="text/javascript">
function kontrola() {
  //funkce vrátí false, pokud nebudou správně vyplněna data a zruší odeslání formuláře
  var zprava="";  //zůstane-li prázdná, funkce vrátí true - data se odešlou na server
  if(document.getElementsByName("kategorie")[0].value==""){
    zprava+="Nevybrána kategorie\n";  //připojí větu k proměnné zprava a odřádkuje
  }
  if(document.getElementsByName("vyrobce")[0].value==""){zprava+="Nevybrán výrobce\n";}
  if(document.getElementsByName("nazev")[0].value==""){zprava+="Nezadán název\n";}

  var regCena = new RegExp("^[0-9]{1,5}$");; // regulární výraz: 1 až 5 číslic
  if(!document.getElementsByName("cena")[0].value.match(regCena)){
    zprava+="Nezadána cena - celé číslo\n";
  }

  /*jiný způsob řešení regulárního výrazu pro cenu
  if(!regCena.test(document.getElementsByName("cena")[0].value)){
    zprava+="Nebyla zadána cena - celé číslo\n";}
  */

  if(document.getElementsByName("stav")[0].checked==false 
     && document.getElementsByName("stav")[1].checked==false 
     && document.getElementsByName("stav")[2].checked==false){zprava+="Nezvolen stav";}

  if(zprava=="") return true;
  else {
    alert(zprava);
    return false;
  }
}
</script>

Funkci JavaScriptu můžeme nahradit novými prvky a atributy formulářů html5. Pro povinné pole použijeme atribut required, pro číselné hodnoty input typu number nebo range s hodnotami minmax, pro datumy date, čas time, apod. Regulární výraz zapíšeme do parametru pattern. Pro upřesnění požadavků pro vložené hodnoty využijeme placeholder.

Upravení údajů záznamu - UPDATE

Stejně jako při mazání záznamu vede na stránku upraveni.php odkaz z výpisu, který stránce prostřednictvím odkazu předá id záznamu, který má být upravován - viz výše Ukázka výpisu pro administraci dat.

Stránka načte daný záznam a zobrazí jeho hodnoty ve formuláři a to prostřednictvím:

  • value - input typu text, date, number, range, apod.
  • vložení mezi párové tagy - textarea
  • checked - input typu checkbox a radio - je-li hodnota editovaného záznamu shodná s value prvku
  • selected - option výběrového pole select - je-li hodnota editovaného záznamu shodná s value option

Po odeslání formuláře se obdobně jako při vkládání nového záznamu nejprve provede kontrola dat a poté uložení změn záznamu s daným id. Při provádění kontroly jak pomocí php, tak pomocí JavaScriptu nebo html5, můžeme vynechat ty prvky, které při editaci již nejdou odeslat prázdné (input typu radio nebo select, který již nemá prázdnou option).

Ukázka kódu pro editaci dat

<h1>Upravení zvoleného záznamu</h1>
<?php
include 'spojeni.php'; // 1 - vytvoření objektu $spojeni a 2 - nastavení UTF-8

// 3 - zjištění zda byl odeslán formulář - metoda POST, ulozit je name tlačítka
if(!isset($_POST["ulozit"])) {
  // když $_POST["ulozit"] neexistuje - načtení a zobrazení údajů do edit. formuláře
  // 3.1 - připravení dotazu s podmínkou pro id - načtení daného záznamu
  $dotaz=$spojeni->prepare("SELECT id_kategorie,id_vyrobce,nazev,cena,skladem,
                            stav,popis FROM vyrobky WHERE vyrobky.id= ? LIMIT 1");
  // 3.2 - přiřazení parametru $_GET["id"] do podmínky
  $dotaz->bind_param("i",$_GET["id"]);
  // 3.3 - přiřazení výstupních proměnných
  $dotaz->bind_result($eid_kategorie,$eid_vyrobce,$enazev,$ecena,$eskladem,
                      $estav,$epopis);
  $dotaz->execute();  // 3.4 - spuštění dotazu
  $dotaz->fetch();    // 3.5 - načtení záznamu do výstupních proměnných - bez cyklu
  $dotaz->close();    // 3.6 - uzavření dotazu
  // 3.7 - zobrazení editovaných údajú do formuláře
  ?>
  <form method="post" onsubmit="return kontrola()">
  <label>Kategorie</label>
  <select name="kategorie">
    <?php
      $dotaz=$spojeni->prepare("SELECT id,kategorie FROM kategorie ORDER BY kategorie");
      $dotaz->bind_result($id,$kategorie);
      $dotaz->execute();
      while($dotaz->fetch()) {
        if($eid_kategorie==$id) {echo "<option value='$id' selected>$kategorie</option>";}
        else {echo "<option value='$id'>$kategorie</option>\n";}
      }
      $dotaz->close();
    ?>
  </select><br>
  <label>Výrobce</label>
  <select name="vyrobce">
    <?php
      $dotaz=$spojeni->prepare("SELECT id,nazev FROM vyrobci ORDER BY nazev");
      $dotaz->bind_result($id,$nazev);
      $dotaz->execute();
      while($dotaz->fetch()) {
        //použijeme obdobný if jako výše nebo můžeme vložit ternární výraz
        echo "<option value='$id' ".($eid_vyrobce==$id?"selected":"").">$nazev</option>";
      }
      $dotaz->close();
    ?>
  </select><br>

  <label>Název výrobku</label>
  <input type="text" name="nazev" maxlength="30" value="<?php echo $enazev; ?>"><br>
  <label>Cena bez DPH</label>
  <input type="text" name="cena" value="<?php echo $ecena; ?>"><br>
  <label>Skladem</label>
  <input type="checkbox" name="skladem" value="1" <?php if($eskladem==1){
                                                        echo "checked";} ?>><br>
  <label>Stav zboží</label>
  <input type="radio" name="stav" value="n" <?php if($estav=="n"){echo "checked";} ?>>nové
  <input type="radio" name="stav" value="o" <?php if($estav=="o"){echo "checked";} ?>>opravené
  <input type="radio" name="stav" value="v" <?php if($estav=="v"){echo "checked";} ?>>vystavené
  <br>
  <label>Popis</label><br><textarea name="popis"><?php echo $epopis;?></textarea><br>
  <input type="submit" name="ulozit" value="Uložit změny">
  </form>
  <p><a href="vypis_administrace.php">«&nbsp;zpět na výpis</a></p>
<?php
} // konec části 3
else {  // 4 - $_POST["ulozit"] existuje - formulář byl odeslán
  // 4.1 - kontrola dat - prázdné povinné údaje nebo data neodpovídajícího formátu
  $zprava=""; //zůstane-li prázdná, můžou se data uložit
  //kategorii a výrobce nemusíme kontrolovat - v selectu není prázdná option
  if($_POST["nazev"]=="") {$zprava.="Nebyl zadán název. ";}
  if(!preg_match("/^[0-9]{1,}$/",$_POST["cena"])) {$zprava.="Nebyla zadána cena. ";}
  if($zprava!="") {echo "<h3 class='chyba'>$zprava</h3>";}
  else {
    // když je $zprava prázdná - všechny údaje byly v pořádku
    // 4.2 - vytvoření proměnné - nezaškrtnutý checkbox nevytvoří proměnnou
    if(!isset($_POST["skladem"])){$_POST["skladem"]=0;}
    // 4.3 - připravení dotazu pro vložení záznamu do tabulky
    $dotaz=$spojeni->prepare("UPDATE vyrobky SET id_kategorie=?,id_vyrobce=?,nazev=?,
                              cena=?,skladem=?,stav=?,popis=? WHERE id=?");
    // 4.4 - přiřazení vstupních parametrů - budou dosazeny za otazníky - včetně id
    $dotaz->bind_param("iisiissi",$_POST["kategorie"],$_POST["vyrobce"],$_POST["nazev"],
            $_POST["cena"],$_POST["skladem"],$_POST["stav"],$_POST["popis"],$_GET["id"]);
    // 4.5 - spuštění dotazu - v podmínce - pokud se provede, vrací true
    if($dotaz->execute()) {
      echo "<h2>Změny byly uloženy</h2>
      <a href='zobrazeni.php?id={$_GET["id"]}' class='tlacitko'>Zobrazit změny</a>"; }
    else {echo "<h2 class='chyba'>Změny nebyly uloženy</h2>\n".$dotaz->error;}
    // 4.6 uzavření dotazu
    $dotaz->close();
    // 4.7 - odkaz zpět na výpis
    echo "<p><a href='vypis_administrace.php'>«&nbsp;Zpět na výpis</a></p>";
    }
  }
?>

Stažení zdojových kódů všech ukázek pro mazání, vložení a upravení dat - administrace.zip

Stažení zdojových kódů všech ukázek - výpisy i administrace - vyrobky.zip