[PHP/MySQL] Update kilku rekordów na raz

2011-07-09 00:08:57 Post #1 Przemo_75

 
Witam,
Niestety nie mogę przeskoczyć update'a. Chyba mam coś namieszane z tablicą, bo wyświetla najpierw same produkty a później ich id (id_asort).
Próbuję uzyskać taką postać tablicy:

[products] => Array ( [0] => Array ( [produkt] => Produkt_1 [id_asort] => 148 ) [1] => Array ( [produkt] => Produkt_2 [id_asort] => 149 ) )

a wciąż otrzymuję taką:

Array ( [produkt] => Array ( [0] => Produkt_1 [1] => Produkt_2 ) [id_asort] => Array ( [0] => 148 [1] => 149 ) )

Poniżej kod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@$kategoria $_GET['kategoria'];
if (
$kategoria)
{
$link=mysql_query(" SELECT a.id_kategorii aid, a.produkt aprodukt, a.id_asort aida, k.id_kategorii kid, k.nazwa knazwa, k.opis kopis FROM kategoria k LEFT JOIN asortyment a ON a.id_kategorii = k.id_kategorii WHERE k.id_kategorii='$kategoria' ORDER BY a.id_asort ASC ");

$categories = array(); 
while (
$wybor2 mysql_fetch_array($link)){ 
  
$kid $wybor2['kid']; 
 
  if (!isset(
$categories[$kid])) 
     
$categories[$kid] = array('nazwa' => $wybor2['knazwa'], 'opis' => $wybor2['kopis'], 'products' => array()); 
  
  if (!empty(
$wybor2['aprodukt']))
    
$categories[$kid]['products'][] = array('produkt' => $wybor2['aprodukt'], 'id_asort' => $wybor2['aida']); 

  
echo 
'<br><ul>'
foreach (
$categories as $idCat => $category)

  echo 
'<li><b>'.$category['nazwa'].'</b><br>'
  echo 
'<li>'.$category['opis'].'<ul>'
  foreach (
$category['products'] as $produkty)
  {
  echo 
'<form method="POST" action="main_asortyment.php?oferta=wyedytuj">';
  echo 
'<li><input type="hidden" name="id_asort[]" value="'.$produkty['id_asort'].'"><input type="text" name="produkt[]" size="60" value="'.$produkty['produkt'].'"></li>'
  } 
  echo 
'<br><br><input type="submit" value="ZAPISZ">';
  echo 
'</form>';
  echo 
'</ul></li>'

echo 
'</ul>';
}
}

elseif(isset(
$_GET['oferta']) && $_GET['oferta']=='wyedytuj'// WYEDYTUJ
{
$kid=$_POST['id_kategorii'];

 if (!empty(
$_POST['produkt']))
 
$produkty2[] = array('produkt' => $_POST['produkt'], 'id_asort' => $_POST['id_asort']); 

foreach(
$produkty2 as $produkt => $id_asort)
{
$query "UPDATE asortyment SET produkt='$produkt' WHERE id_asort='$id_asort'";
$result mysql_query ($query);
}
}

Będę wdzięczny za pomoc, bo siedzę nad tym już stanowczo za długo i próbuje rozpracować na różne sposoby, niestety bezskutecznie.

2011-07-11 10:39:51 Post #2 nospor

 
Przeciez pod $_POST['produkt'] znajduje się tablica.
Zrób sobie
print_r($_POST['produkt'];
to sam zobaczysz.
Teraz pomyśl co z tym fantem zrobić

2011-07-11 12:04:19 Post #3 Przemo_75

 
Wielkie dzięki kolego. Po raz kolejny uświadomiłeś mi pewne rzeczy i nakierunkowałeś mnie na odpowiedni tor.
Poniżej (działające) rozwiązanie:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
elseif(isset($_GET['oferta']) && $_GET['oferta']=='wyedytuj'// WYEDYTUJ 
{
$kid=$_POST['id_kategorii'];

 if (!empty(
$_POST['produkt']))
$tab1 $_POST['produkt'];
$tab2 $_POST['id_asort'];
$tablica array_combine($tab1$tab2);

foreach(
$tablica as $produkt => $id_asort)
{
 
mysql_query("UPDATE asortyment SET produkt='{$produkt}' WHERE id_asort='{$id_asort}'");

$message2='<br> Pomyślnie wyedytowałem produkt - '.$produkt.' <br>';
echo 
"<p align=\"center\" class=\"style3\">$message2</p>";
}
}

2011-07-11 12:08:44 Post #4 nospor

 
Żeby używać dwóch tablic z POST nie musisz ich łączyć w jedną tablicę.
Iteruj FOREACH po jednej z nich, a w środku foreach odwołuj się do drugiej, poprzez indeks z foreach. Przecież obie tablice mają taki sam indeks.

Co nie zmienia oczywiście faktu, że rozwiązanie które podałeś też jest poprawne. Miałbyś jednak problem, gdybyś miał więcej danych niż dwie dane.

2011-07-11 12:22:33 Post #5 Przemo_75

 
OK. Spróbuję też zrobić z FOREACH.
Jeszcze raz dzięki.

Zrobiłem 2 wersje z FOREACH, choć ta 2. jest trochę za bardzo "rozrośnięta" i nie tak dobra jak 1.:
1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
elseif(isset($_GET['oferta']) && $_GET['oferta']=='wyedytuj'// WYEDYTUJ 
{
$kid=$_POST['id_kategorii'];

 if (!empty(
$_POST['produkt']))

$tab1 $_POST['produkt'];
$tab2 $_POST['id_asort'];

foreach(
array_keys($tab1) as $n)
{
    
mysql_query("UPDATE asortyment SET produkt='{$tab1[$n]}' WHERE id_asort='{$tab2[$n]}'");

$message2='<br> Pomyślnie wyedytowałem produkt - <b>'.$tab1[$n].'</b> o id <b>'.$tab2[$n].'</b><br>';
echo 
"<p align=\"center\" class=\"style3\">$message2</p>";
}
}

2.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
elseif(isset($_GET['oferta']) && $_GET['oferta']=='wyedytuj'// WYEDYTUJ 
{
$kid=$_POST['id_kategorii'];

 if (!empty(
$_POST['produkt']))

$tab1 $_POST['produkt'];
$tab2 $_POST['id_asort'];

$i=0;
foreach (
$tab1 as $prod)
{
$tablica[$i][1] = $prod;
$i++;
}
$i=0;
foreach (
$tab2 as $prod)
{
$tablica[$i][2] = $prod;
$i++;
}
foreach (
$tablica as $produkty)
{
    
mysql_query("UPDATE asortyment SET produkt='{$produkty[1]}' WHERE id_asort='{$produkty[2]}'");

$message2='<br> Pomyślnie wyedytowałem produkt - <b>'.$produkty[1].'</b> o id <b>'.$produkty[2].'</b><br>';
echo 
"<p align=\"center\" class=\"style3\">$message2</p>";
}
}

2011-07-11 22:49:13 Post #6 Przemo_75

 
Mam jeszcze jeden mały problem podczas edycji / update'u rekordów.
Jeśli zmodyfikuję kilka wpisów na raz (zmienię treść), to wszystko działa OK i wszystkie rekordy zostają zmodyfikowane.
Jeśli zmodyfikuję wpisy (więcej niż jeden) poprzez usunięcie zawartości ich wpisów, to usuwa tylko ostatni ze zmodyfikowanych wpisów.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
elseif(isset($_GET['oferta']) && $_GET['oferta']=='wyedytuj'// WYEDYTUJ  

$kid=$_POST['id_kategorii']; 

 if (!empty(
$_POST['produkt'])) 
$tab1 $_POST['produkt']; 
$tab2 $_POST['id_asort']; 
$tablica array_combine($tab1$tab2); 

foreach(
$tablica as $produkt => $id_asort)
    {

    if (
strlen($produkt) > 0)
        {
        
$query1 "UPDATE asortyment SET produkt='{$produkt}' WHERE id_asort='{$id_asort}'";
        
$result1 mysql_query ($query1);
        
$message1='<br> Pomyślnie zaktualizowałem produkt - <b>'.$produkt.' o id <b>'.$id_asort.'</b></b><br>';
        echo 
"<p align=\"center\" class=\"style3\">$message1</p>";
        } 
    else
        {
        
$query2 "DELETE FROM asortyment WHERE id_asort='$id_asort'";
        
$result2 mysql_query ($query2);
        
$message2='<br> Pomyślnie skasowałem produkt o id <b>'.$id_asort.'</b><br>';
        echo 
"<p align=\"center\" class=\"style3\">$message2</p>";
        }    
    }
}

Nie wiem jak temu zaradzić.

2011-07-13 10:25:13 Post #7 nospor

 
Nie za bardzo rozumiem problem. Przecież w tym kodzie nic nie usuwasz.

2011-07-13 10:45:30 Post #8 Przemo_75

 
W przypadku niespełnienia warunku if (strlen($produkt) > 0) powinno wykonać się poniższe:
1
2
3
4
5
       $query2 "DELETE FROM asortyment WHERE id_asort='$id_asort'"
        
$result2 mysql_query ($query2); 
        
$message2='<br> Pomyślnie skasowałem produkt o id <b>'.$id_asort.'</b><br>'
        echo 
"<p align=\"center\" class=\"style3\">$message2</p>"

2011-07-13 11:01:50 Post #9 nospor

 
No faktycznie.... ślepnę na starość

Zrób
print_r($_POST) ;
dla sytuacji, gdy kasujesz produkty.

2011-07-13 11:17:21 Post #10 Przemo_75

 
W którym miejscu kodu powinienem to umieścić?

2011-07-13 11:20:41 Post #11 nospor

 
Chociażby przed pętlą FOREACH

2011-07-13 11:37:34 Post #12 Przemo_75

 
Przy print_r($_POST); otrzymuję tablicę w postaci:

Array ( [id_asort] => Array ( [0] => 148 [1] => 149 ) [produkt] => Array ( [0] => Produkt_1 [1] => Produkt_2 )

natomiast przy print_r($tablica); tablicę:

Array ( [Produkt_1] => 148 [Produkt_2] => 149 )

2011-07-13 11:41:56 Post #13 nospor

 
Miałeś to zrobić dla sytuacji gdy usuwasz.... przecież dla takiej tablicy nic nie usuwasz.

2011-07-13 11:42:50 Post #14 nospor

 
Jak zrobisz to dla sytuacji gdy usuwasz, to sam zobaczysz w czym problem. Ja już wiem

ps: mówiłem ci, że z tym kombine będziesz miał tylko problemy

2011-07-13 12:16:27 Post #15 Przemo_75

 
Dla sytuacji gdy usuwam (np. 2 wpisy) otrzymuję tablicę:
Array ( [id_asort] => Array ( [0] => 148 [1] => 149 [2] => 150 [3] => 151 ) [produkt] => Array ( [0] => Produkt_1 [1] => Produkt_2 [2] => [3] => ) )

2011-07-13 12:20:18 Post #16 nospor

 
No ale wyświetl sobie jeszcze $tablica, tak jak to zrobiłeś poprzednim razem, a doznasz olśnienia

2011-07-13 12:21:55 Post #17 nospor

 
Żeby Cię nie męczyć:
jeśli chcesz nadal używać array_combine, to nie:
$tablica = array_combine($tab1, $tab2);
a:
$tablica = array_combine($tab2, $tab1);
Zmieniły ci się teraz klucze i wartości, więc zmień to co wkładasz do zapytań.

2011-07-13 12:46:32 Post #18 Przemo_75

 
Teraz działa jak należy. Wielkie dzięki nospor za Twoją wielką i nieocenioną pomoc.
Czy zamiast combine lepsze byłoby łączenie tablic za pomocą array_keys (wersja 1. z postu #5)?

2011-07-13 12:51:47 Post #19 nospor

 
Jak już ci pisałem array_combine jest mało wygodne i w ogóle nie przydatne przy większej liczbe danych niź dwie.
Twoja wersja z foreach jest też nie do końca taka, o jaką mi chodziło. Mi chodziło o coś takiego:
1
2
3
4
5
6
7
8
<?php
foreach($_POST['produkt'] as $key=>$produkt

echo 
'Produkt:'.$produkt;
echo 
'Id:'.$_POST['id_asort'][$key];
//echo 'Cos innego:'.$_POST['cos_innego'][$key];
}
?>


Ty za bardzo starasz się chyba na siłę wykorzystać gdzie się da funkcję z rodziny array_....

2011-07-13 14:09:13 Post #20 Przemo_75

 
To się bierze raczej z mojej, jeszcze, niewielkiej wiedzy. Mam nadzieję, że kiedyś uda mi się ją opanować chociaż w połowie tak dobrze jak Ty.

Odpowiedz