Autor Zpráva
Karol.H123
Profil *
Ahojte, mám na webe select (multiple) pre výber kategórii do ktorých sa má zaradiť článok.

Chcel by som Vám poprosiť o radu, ako spraviť aby sa mi do DB k článku zapísali všetky kategórie ktoré užívateľ vyberie.
Aktuálne sa mi zapíše len posledná.

Moja DB vyzerá nejak takto:

--clanky:
-id
-nazov
...

--kategorie:
-kat_id
-kat_meno

--clanky_kategorie:
-clanok_id
-kategoria_id
Keeehi
Profil
A SQL dotazy které posíláš?
Karol.H123
Profil *
    $conn->query("INSERT INTO clanky(nazov, autor, datum) VALUES ('$c_nazov','$c_autor','$c_datum')");
    $posledne_id = $conn->insert_id;    
    $conn->query("INSERT INTO clanky_kategorie(ck_kategoria_id, ck_clanok_id) VALUES ('$clanokid','$posledne_id')");



pardon, do ck_kategoria_id sa samozrejme zapisuje ID kategórie a nie článku
Keeehi
Profil
Velmi zjednodušeně takto:
<select multiplex name="kategorie[]">
    ...

$conn->query("INSERT INTO clanky(nazov, autor, datum) VALUES ('$c_nazov','$c_autor','$c_datum')");
$posledne_id = $conn->insert_id;

foreach ($_POST['kategorie'] as $ kategorie) {
    $conn->query("INSERT INTO clanky_kategorie(ck_kategoria_id, ck_clanok_id) VALUES ('$karegorie','$posledne_id')");
}

Je potřeba ošetřit, pokud se nevybere žádná kategorie, escapování a další. Taky by se hodilo složit si všechny vkládané hodnoty do tabulky clanky_kategorie do jedné proměnné a pak provést jeden hromadný insert.
Karol.H123
Profil *
Ďakujem Keeehi, toto som už pred tým skúšal ale nešlo mi to lebo som v selecte pri name vynechal [] takže som tam mal
<select multiplex name="kategorie"> namiesto <select multiplex name="kategorie[]">
ešte raz ďakujem za pomoc


Pardon, ešte by som sa chcel spýtať, doteraz (dala sa vybrať len jedna kategória) som správnosť výberu (či taká kategória existuje) kontroloval nasledovne

$tkategoria = mysqli_query($conn, "SELECT kat_meno FROM kategorie WHERE kat_id='".$_POST['kategorie']."'");

if (mysqli_num_rows($tkategoria ) == 0) {
      die('<div>Vybraná kategória nie je platná.</div>');
  }  

ako by som to prosím mohol kontrolovať aktuálne?


---------------------

Escapovanie môže byť poriešené aj takto:

    foreach ($_POST['kategorie'] as $kategorie) {
      $katid = $conn->escape_string($kategorie); 
      $conn->query("INSERT INTO clanky_kategorie(ck_kategoria_id, ck_clanok_id) VALUES ('$katid','$posledne_id')");
    }

Ak mám hlúpe otázky tak sa ospravedlňujem web si robím vo voľnom čase pre seba ako koníček, nevenujem sa tomu.
Kajman
Profil
Pokud použijete typ tabulek innodb, můžete v databázi zřídit cizí klíče, které samy pohlídají správnost id kategorie.

Pokud používáte myisam, tak kontrolu dejte do toho foreach cyklu a kontrolujte $katid, protože $_POST['kategorie'] je pole. A pokud je id kategorie číselné, neošetřujte string, ale přetypujte proměnnou na číslo. Např.
$katid = (int)$kategorie;
V dotazech ji pak nemusíte obalovat apostrofy.

A v tagu select se atribut jmenuje multiple, ne multipex.
Karol.H123
Profil *
Všetko funguje. Ďakujem Vám za pomoc a čas ktorý ste mi venovali!
Dan Charousek
Profil
Karol.H123:
Osobně bych cyklické vkládání záznamů (viz. [#4] Keeehi) nedoporučoval. V tomto případě, kdy je počet kategorií v řádu jednotek, to není tak markantní, ale s narůstajícím počtem záznamů se vkládání zpomaluje. Viz. ukázka. Pro názornost graf.
Karol.H123
Profil *
Dan Charousek:

takže by to vyzeralo nejak takto?

$hodnota = array();
foreach ($_POST['kategorie'] as $kategorie){
  $katid = (int)$kategorie;
  $values[] = "($posledne_id, $katid)";
}
$conn->query("INSERT INTO clanky_kategorie(ck_kategoria_id, ck_clanok_id) VALUES " . implode(", ", $hodnota) . "");
Keeehi
Profil
Karol.H123:
Ano tak. Jen máš přehozené pořadí IDček kategorií a článku.
Karol.H123
Profil *
Ďakujem.
Mal by som niečo také aplikovať aj na tú kontrolu správnosti výberu čo som spomínal? Tá aktuálne vyzerá takto:

  foreach ($_POST['kategorie'] as $kategorie){
    $katid = (int)$kategorie;
      $tkategoria = mysqli_query($conn, "SELECT kat_meno FROM kategorie WHERE kat_id=".$katid."");   
      if (mysqli_num_rows($tkategoria) == 0) {
        die('<div>Vybraná kategória nie je platná.</div>');
      }  
    }
Dan Charousek
Profil
Karol.H123:
Je otázka jak to řešit. Pokud máš v tabulce clanky_kategorie cizí klíč na tabulku kategorie, tak to možná ani není třeba ošetřovat, protože to neplatnou hodnotu nepustí. Nejsem si teď jistý, jestli se dotaz celý neprovede (pokud tam bude neplatná hodnota) nebo se vloží jen ty platné. Chtělo by to zkusit. V druhém případě si myslím, že to není třeba ošetřovat. V tom prvním bych jen vyhodil nějaké varování, že dotaz neuspěl. Stejně jej uvidí jen zlobiví lidé, co si hrají s kódem toho formuláře.

Druhá možnost (jen jedním dotazem) je udělat něco takového:

$query = mysqli_query($conn, "SELECT COUNT(id) AS pocet FROM kategorie WHERE kat_id IN (" . implode(",", $kategorie) . ")");
// a potom porovnat count($_POST['kategorie']) s výsledkem toho dotazu. Pokud se hodnoty neshodují, uživatel se pokouší o to vložit neplatnou hodnotu

Řešit to [#11] Karol.H123 mi přijde nešikovné, protože to pak postrádá smysl jednodotazové řešení, které jsem nastínil.
Karol.H123
Profil *
Dan Charousek:
Asi to ani nebude nutné kontrolovať pretože ako píšete ak sa v DB objaví cudzí kľúč s neplatnou hodnotou tak ho web odignoruje. Ale čisto teoreticky, ak by chcel byť niekto veľmi neposlušný a chcel by zahltiť databázu tak má ako.. :)

Prepáčte ale pri tom scripte čo ste mi napísali asi robím niečo zle lebo pokaždé mi vráti nulovú hodnotu (kontrolujem to cez echo $query;) či už ho skúsim vložiť pod foreach alebo do neho.
Dan Charousek
Profil
Karol.H123 [#9]:
Inicialzuješ prázdné pole do proměnné $hodnota, ale naplňuješ proměnnou $values

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0