Avatar billede nemlig Professor
23. juni 2008 - 18:01 Der er 20 kommentarer og
1 løsning

Slet flere MySQL-poster via Submit knap

Hej alle.
Jeg ønsker at lave en liste af poster fra MySQL, hvor der er mulighed for at markere flere poster til sletning.
Jeg lister posterne med while ()med 1 post på hver sin linje. Forrest i hver linje vil jeg placere en Checkbox, som kan afkrydses, hvis posten ønskes slettet.
Og ved tryk på Submit, skal alle markerede poster så slettes.

Men hvordan får jeg posterne slettet.
Når jeg sletter en post, gør jeg normalt dette:

$sql = "DELETE FROM tabelnavn WHERE id = '".$id."'";
database($sql);

Men hvordan sletter jeg de markerede?
Avatar billede expnet Seniormester
23. juni 2008 - 18:12 #1
Jeg tro vi skal bruge lidt kode fra dig af hvis akl kunne hjælpe dig
Avatar billede olebole Juniormester
23. juni 2008 - 18:13 #2
<ole>

Hvis dine checkbox'e hedder 'foo[]', kan du i princippet skrive noget à la:

$a = array();
for ($i=0,$j=count($_POST["foo"]); $i<$j; $i++) {
    $a[$i] = "`id`='".$_POST["foo"][$i]."'";
}
$sql = "DELETE FROM `tabelnavn` WHERE ".implode(" OR ", $a);

- men du bør jo som altid tjekke al brugerinput, før det kommer nær databasen  ;o)

/mvh
</bole>
Avatar billede expnet Seniormester
23. juni 2008 - 18:13 #3
*Jeg tro vi skal bruge lidt kode fra dig af hvis vi skal kunne hjælpe dig
Avatar billede nemlig Professor
23. juni 2008 - 19:12 #4
Min nuværende kode ser sådan her ud, men er godt klar over, at det selvfølgelig ikke virker. Jeg kan sagtens liste posterne, og jeg mener også, at navngivningen af chekcboksene er OK. Men det er mere, når jeg skal slette, det kniber.

<?php
if(isset($_GET['update']) && $_GET['update'])
{
    $id    = mysqlRealEscapeString($_POST['name']);
    $sql = "DELETE FROM kundeliste WHERE id = '".$id."'";
    database($sql);

    echo "Kunderne er nu slettet.<br>";
}

echo "<form action='".$_SERVER['PHP_SELF']."?update=true' method=post>";

  $sql = "SELECT * FROM kundeliste";
  $res = database($sql);
  $row = mysql_fetch_array($res);

while($row = mysql_fetch_array($res))
{
    echo "<input type='checkbox' value='1' name='slet".$row['id']."'>";
    echo $row['navn']."<br>";
}

echo "<input type='submit' value='Slet kunder'>
</form>";
?>
Avatar billede olebole Juniormester
23. juni 2008 - 20:37 #5
Prøv denne kode:

<?php
if(isset($_POST['context']) && $_POST['context']=='update')
{
    $a = array();
    for ($i=0,$j=count($_POST["foo"]); $i<$j; $i++) {
        $id    = mysqlRealEscapeString($_POST['slet'][$i]);
        $a[$i] = "`id`='".$id."'";
    }
    $sql = "DELETE FROM `kundeliste` WHERE ".implode(" OR ", $a);
    database($sql);

    echo "Kunderne er nu slettet.<br>";
}

echo "<form action='".$_SERVER['PHP_SELF']."' method=post>";
echo "<input type='hidden' name='context' value='update'>";

  $sql = "SELECT * FROM `kundeliste`";
  $res = database($sql);
  $row = mysql_fetch_array($res);

while($row = mysql_fetch_assoc($res))
{
    echo "<input type='checkbox' value='".$row['id']."' name='slet[]'>";
    echo $row['navn']."<br>";
}

echo "<input type='submit' value='Slet kunder'>
</form>";
?>
Avatar billede olebole Juniormester
23. juni 2008 - 20:39 #6
Damned ... en copy/paste fejl! Der skal stå:
    for ($i=0,$j=count($_POST["slet"]); $i<$j; $i++) {
Avatar billede olebole Juniormester
23. juni 2008 - 20:41 #7
Hmmm ... flere fejl. Sådan:

<?php
if(isset($_POST['context']) && $_POST['context']=='update')
{
    $a = array();
    for ($i=0,$j=count($_POST["slet"]); $i<$j; $i++) {
        $id    = mysqlRealEscapeString($_POST['slet'][$i]);
        $a[$i] = "`id`='".$id."'";
    }
    $sql = "DELETE FROM `kundeliste` WHERE ".implode(" OR ", $a);
    database($sql);

    echo "Kunderne er nu slettet.<br>";
}

echo "<form action='".$_SERVER['PHP_SELF']."' method='post'>";
echo "<input type='hidden' name='context' value='update'>";

  $sql = "SELECT * FROM `kundeliste`";
  $res = database($sql);

while($row = mysql_fetch_assoc($res))
{
    echo "<input type='checkbox' value='".$row['id']."' name='slet[]'>";
    echo $row['navn']."<br>";
}

echo "<input type='submit' value='Slet kunder'>
</form>";
?>
Avatar billede olebole Juniormester
23. juni 2008 - 20:44 #8
- og for bedre performance burde du nok specificere/minimere din select:
    $sql = "SELECT `id`, `navn` FROM `kundeliste`";
Avatar billede nemlig Professor
23. juni 2008 - 20:56 #9
Hej Olebole. Din sidste kommentar er jeg helt med på.
Jeg har også afprøvet dit forslag til kode, og det virker præcis som ønsket. Så tusind tak for denne hjælp.
Jeg vil bare også gerne forstå, hvad der sker.
Jeg forstår nemlig ikke, hvordan du sletter flere poster på én gang, når DELETE kommandoen ikke er en del af "for"-løkken.
Måske fordi de valgte poster er smidt i et Array ($a)??
Send bare et svar.:-))
Avatar billede olebole Juniormester
23. juni 2008 - 21:06 #10
Hvis du i stedet for at køre sql-sætningen mod databasen, prøver at skrive den ud med echo, vil den se sådan noget lignende ud:

    DELETE FROM `kundeliste` WHERE `id`='4' OR `id`='33' OR `id`='42' OR `id`='67'

Array'et ser sådan ud:
    $a = array("`id`='4'", "`id`='33'", "`id`='42'", "`id`='67'");

Udtrykket:
    implode(" OR ", $a);

- skaber strengen:
    `id`='4' OR `id`='33' OR `id`='42' OR `id`='67'

http://dk2.php.net/manual/en/function.implode.php
Avatar billede olebole Juniormester
23. juni 2008 - 21:08 #11
Det er en langt mere effektiv måde, end at rette 4 separate queries mod databasen  =)
Avatar billede nemlig Professor
23. juni 2008 - 21:12 #12
Super forklaring - så er jeg endnu engang blevet meget klogere.
Avatar billede olebole Juniormester
23. juni 2008 - 21:16 #13
- Nemlig!  ;D
Jeg ville nok også foretrække at udskrive dine felter på følgende måde:

$aHTML = array();
while($row = mysql_fetch_assoc($res))
{
    $aHTML[] = "<input type='checkbox' value='".$row['id']."' name='slet[]'>".$row['navn'];
}
echo implode("<br>", $aHTML);

Det er somregel en del hurtigere. Tak for points  ;o)
Avatar billede olebole Juniormester
23. juni 2008 - 21:26 #14
Læg i øvrigt mærke til mine andre ændringer:

Jeg bruger mysql_fetch_assoc i stedet for mysql_fetch_array, der som default henter både et talindekseret array og et associativt array. Vi skal kun bruge det associative:
    http://dk2.php.net/manual/en/function.mysql-fetch-array.php
    http://dk2.php.net/manual/en/function.mysql-fetch-assoc.php

Jeg har ændret koden, så du kun bruger post-variabler (det skjulte felt 'context'). Dels er det mere tro mod idéen bag HTTP metoderne get og post, ikke at blande dem sammen - og dels er det rart at vide præcis, hvor alle ens variabler kommer fra.

Derudover backtick'er jeg alle felt- og tabelnavne i MySQL kald af hensyn til evt. reserverede navne. Ordet 'by' har f.eks. en betydning i MySQL, hvorfor du enten må kalde feltet for 'city' - eller bruge backticks
Avatar billede nemlig Professor
23. juni 2008 - 21:40 #15
Ok - tak for de udførlige informationer.
Avatar billede olebole Juniormester
23. juni 2008 - 21:41 #16
Selvtak  ;o)
Avatar billede nemlig Professor
23. juni 2008 - 22:03 #17
Øh - jeg har lige en lille udfordring mere.
Hvis der nu ikke er markeret nogle checkbokse og der klikkes på knappen, så får jeg en MySQL-fejl.
Jeg vil derfor lave et tjek på om Arrayet er tomt, og hvis ja, så skriver jeg en fejltekst.
Men hvad er syntax for om et Array er tomt??
Avatar billede showsource Seniormester
23. juni 2008 - 22:30 #18
Jeg ville nu:

if(isset($_POST["context"],$_POST["slet"]) && $_POST["context"]== "update" && is_array($_POST["slet"]))
{

$sql = "DELETE FROM `kundeliste` WHERE `id` IN (".implode(",", $_POST["slet"]).")";
database($sql);

}
Avatar billede nemlig Professor
24. juni 2008 - 16:31 #19
Showsource: Skal jeg forstå dit forslag som en løsning til at undgå MySQL fejl, hvis der ikke er markeret nogen checkbokse eller mener du, det er bedre kode, end det olebole har leveret eller?????
Og brugerinput bliver vist nok ikke tjekket inden der skrives i databasen. Dette sker jo i den anden kode med funktionen "mysqlRealEscapeString"
Avatar billede nemlig Professor
24. juni 2008 - 19:42 #20
Jeg løste problemet med Mysql-fejlen ved at lave et tjek på variablen $j. Hvis den er 0, så springes over DELETE og der gives en fejlmeddelelse.
Avatar billede showsource Seniormester
25. juni 2008 - 07:34 #21
Nu var jeg ikke klar over andre kunne poste også.
Bedre kode ? næhh

Hvis ingen checkbox er markeret, er $_POST["slet"] ikke sat.
Og for at sikre det er tal som er i array'et "slet"

if(isset($_POST["context"],$_POST["slet"]) && $_POST["context"]== "update" && is_array($_POST["slet"]))
{

$delete = (int)$_POST["slet"][0];
$antal = count($_POST["slet"]);

    for($i = 1; $i < $antal; $i++) {
    $delete .= ",".(int)$_POST["slet"][$i];
    }


$sql = "DELETE FROM `kundeliste` WHERE `id` IN (".$delete.")";

database($sql);

}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester