Wiele zaznaczeń checkbox + pętla foreach

0

Witam

Mam formularz zamówienia w którym chciałbym poprzez checkbox wybrać kilka pozycji i utworzyć z nich wysyłkę.

<form action="wysylka.php" method="post">
<input type=\"checkbox\" name=\"wybrany[]\" value='". $wiersz['id']."'>
<input type=\"hidden\" name=\"nr_zam\" value='". $wiersz['nr_zam']."'>
<input type=\"hidden\" name=\"status\" value='". $wiersz['status']."'>
<input type=\"submit\" value=\" Utwórz wysyłkę z zaznaczonych \">
</form>

Przetwarzam formularz i aktualizuję zarówno tabelę 'zamow' jak i kopiuję dane do drugiej tabeli 'wys' (wiem, że to można zrobić w jednej tabeli,
ale chciałbym spróbować takiego rozwiązania). Problem polega na tym, że mam błąd w kodzie (źle skonstruowaną pętlę?) i część rekordów kopiuje się wielokrotnie.
Jak można tego uniknąć?

<?php session_start();
require_once('db.php');

$nr_zam = mysqli_real_escape_string($con, $_POST['nr_zam']);
$status = mysqli_real_escape_string($con, $_POST['status']);

foreach($_POST['wybrany'] as $wybrany)
  {
   $id = mysqli_real_escape_string($con,$wybrany);
    if($status=="do zrob")
    {
    $res = mysqli_query($con,"UPDATE `zamow` SET `status`='w realiz' WHERE `id`='$id' ");
    
    $sql = mysqli_query($con, "INSERT INTO `wys` (`data`,`klient`,...) SELECT `data`,`klient`,`...` 
    FROM `zamow` WHERE (`nr_zam`='$nr_zam') AND (`status`='w realiz')");	
	
    echo "<h1>Ok</h1>";	
    }
	 
    else {
    // show error
        }
  }
?>

1

Troszkę mało informacji.
Formularz raczej nie wygląda dokładnie tak jak go wkleiłeś - chyba tam też masz jakąś pętlę.
Pytanie tylko czy tworzysz nią jedynie pola typu checkbox czy zestaw 3 inputów które pokazałeś.

Ale bazując na tym do dodałeś i zakładając, że dane wyglądają tak:

$_POST['wybrany'] = [3,6,12,55,222, ... ];
$_POST['nr_zam'] = "ciagZnakow";
$_POST['status'] = "do zrob";

To zapytanie

$sql = mysqli_query($con, "INSERT INTO `wys` (`data`,`klient`,...) SELECT `data`,`klient`,`...` 
    FROM `zamow` WHERE (`nr_zam`='$nr_zam') AND (`status`='w realiz')");  

wykona się dokładnie tyle razy ile wynosi długość tablicy $_POST['wybrany']
Nie ma tutaj żadnej zmiennej, której wartość zmienia się wraz z iteracją w obrębie pętli foreach() dlatego też te rekordy będę zdublowane .

0

W formularzu mam tak:


mysqli_query($con, 'SET @i:=0');
$zapytanie = "SELECT *, @i:=@i+1 Lp FROM zamow ORDER BY data DESC";
$wykonaj = mysqli_query ($con, $zapytanie);

while ($wiersz=mysqli_fetch_array ($wykonaj)) {
echo (...)

Tworzę zarówno pojedyncze pola typu checkbox (dla każdego rekordu) jak i ww. inputy, oraz inne dane które już nie są inputami.
Pozycje zamówienia przy dopisywaniu dostają status "do zrob", a po ich wybraniu i zatwierdzeniu status się zmienia na "w realiz".
Jesteś w stanie podpowiedzieć jaką zmienną utworzyć i gdzie ją wstawić?

1

Zaczynając od początku.
Tworzenie w pętli takiego zestawu:

<input type=\"checkbox\" name=\"wybrany[]\" value='". $wiersz['id']."'>
<input type=\"hidden\" name=\"nr_zam\" value='". $wiersz['nr_zam']."'>
<input type=\"hidden\" name=\"status\" value='". $wiersz['status']."'>

nie ma sensu.
O ile same checkboxy są tworzone poprawnie, o tyle 2 pola typu hidden już nie.
Zauważ, że przy każdej iteracji, pola typu hidden będą miały ten sam atrybut name (w przypadku checkobxa masz tablicę, więc wartości się tam **dopisują ** - tutaj wartości się nadpisują)

I teraz wracając do skryptu PHP
Wydaje mi się, że zaznaczając kilka checkboxów chcesz dla każdego z nich zmienić status. Świadczy o tym zapis:
$res = mysqli_query($con,"UPDATE `zamow` SET `status`='w realiz' WHERE `id`='$id' ");
To jest jak najbardziej OK i działa tak jak chcesz.

Jeśli chodzi o drugie zapytanie to ona powinno się wykonać chyba tylko raz?
Jeśli tak to "wyrzuć" je poza pętlę for.

Jeśli powinno działać to inaczej, to opisz co ma się dziać z konkretnymi wartościami i co tak na prawdę ma być w bazie danych w tabeli zamow

0

Dzięki za podpowiedzi.
Poprawiłem pola "hidden" i wyrzuciłem drugie zapytanie poza pętlę, ale dalej coś mam źle, bo ono ($sql) nie działa.


<?php session_start();
require_once('db.php');

$nr_zam = mysqli_real_escape_string($con, $_POST['nr_zam']);
$status = mysqli_real_escape_string($con, $_POST['status']);

foreach ($_POST['wybrany'] as $wybrany){  
   
   if ($status=="do zrob"){
	$id = mysqli_real_escape_string($con,$wybrany);
    	$res = mysqli_query($con,"UPDATE `zamowienia` SET `status`='w realiz' WHERE `id`='$id' ");
		}   
	 else {
	 	echo "Wybierz właściwe pozycje zamówienia";
	 	 }
  }
 
 if ($res)
    {
    $sql = mysqli_query($con, "INSERT INTO `wys` (`data`,`klient`,...) SELECT `data`,`klient`,`...`  FROM `zamow` WHERE (`nr_zam`='$nr_zam') AND (`status`='w realiz')");    
    }
 else 
    {
    echo "<br>Zaznacz właściwe pozycje zamówienia";
     }
?>

0

Ten if ($res) w tym miejscu nie ma sensu.
Jeśli $status będzie inny niż 'do zrob' to wywali Ci błąd undefined variable

Zrób echo tych zapytań i sprawdź czy są poprawne. Możesz je skopiować (to co PHP wypluje) i spróbować wykonać w phpMyAdmin ręcznie.
czyli:
echo "UPDATE zamowienia SET status='w realiz' WHERE id=".$id
oraz to drugie.

0

Mam taką próbę (na pierwszym zapytaniu) i widzę że status nie przenosi się do pętli. Tylko nie wiem jak zrobić żeby powiązać każdą wybraną pozycję z jej statusem.

$nr_zam = mysqli_real_escape_string($con, $_POST['nr_zam']);
$status = mysqli_real_escape_string($con, $_POST['status']);


   foreach ($_POST['wybrane'] as $wybrany => $id)
	{
		if ($status=='do zrob')
		{
		echo "UPDATE zamowienia SET status='w realiz' WHERE id='$id'";
		}
		else
		{
		echo "Inny status";
		}
		
	}

1

Jest w ogóle jakiś powód dlaczego te update pchasz do pętli?
Lepiej użyć where in w samym SQL. Wydajniejsze i bardziej bez problemowe.
Jak już wolisz pętlę to zobacz jak wygląda ta zmienna $status po "eskejpowaniu". No i czy takie działanie ma sens, skoro nie pchasz tego do bazy, tylko używasz do porównań.

1 użytkowników online, w tym zalogowanych: 0, gości: 1