Autor | Zpráva | ||
---|---|---|---|
Prefin Profil |
#1 · Zasláno: 14. 3. 2014, 19:52:08
Ahojda všichni.
Jsem z toho už trotl. Buď něco prostě nevidím, nebo nebo se dějou zázraky. V Mysql mám tabulku poptavka, které jsou mimo jiných sloupce id (int) a podklady (text). Kód: $soubory = "udaje-klienta.pdf"; $sql = "UPDATE poptavka SET podklady='$soubory' WHERE id='".$_POST["id"]."'"; echo $sql; mysql_query($sql); UPDATE poptavka SET podklady='udaje-klienta.pdf' WHERE id='130' Nemůžu přijít na to, proč se mi nezapíše poslední znak 'f' Zápis mysql nevrací žádnou chybu. Díky za Váš čas. |
||
Alphard Profil |
#2 · Zasláno: 14. 3. 2014, 19:54:16
Tak začnu tipovat, opravdu je datový typ
text ? Není tam něco s omezenou délkou? Nějaká SQL chyba, když se tentýž dotaz spustí v SQL adminu?
|
||
Prefin Profil |
#3 · Zasláno: 14. 3. 2014, 20:05:09
Alphard:
Ta tabulka už nějakou dobu běží a zapisujou se tam bezchybně poměrně dlouhý seznamy příloh. Datový typ text je nastaven správně, kódování utf8_unicode_ci, omezení žádné. Blbne to pouze v úryvku, který jsem teď přidával kvůli generování dalších pdfek. Po spuštení v phpmyadminu dotaz proběhne bez chyb a zapíše správně. Ve scriptu to mám přesně podle předlohy. Všechno kontroluji neustále poslední dvě hodiny a fakt nevím čím by to mohlo být. Ale něčím to je a bude to mezi židlí a klávesnicí. |
||
Prefin Profil |
Někde chyba bude. Lepší než chodit s proutkem a hledat jí bude modifikovat celý uryvek kódu.
Chtěl bych požádat o radu s kombinovaným dotazem, který se týká popsaného problému a který by to zjednodušil. Ve scriptu nejprve načítám obsah sloupce podklady, testuji jestli je prázdný či není a poté buď připojím ke stávajícímu obsahu další, nebo vkládám nový. Sloupec obsahu (je-li naplněn) obsahuje seznamy souborů, oddělené čárkou. To testování je třeba proto, aby se nevložila čárka před první záznam (poté s tím pracuji pomocí Explode()). Šlo by při zpracování kontrolovat výskyt čárky na začátku a případně jí odstranit, ale proč dělat bordel v záznamech. Potřeboval tedy bych poradit, jestli je možné v jednom dotazu nejprve zkontrolovat zda je buňka prázdná a poté vložit příslušným způsobem: je prázdná Vloží se soubor.pdf není prázdná Připojí se ke stávajícímu obsahu ,soubor.pdf > vznikne záznam predchozi_soubor.pdf,soubor.pdf. Teď nejprve načtu obsah, pak zkontroluju jestli je prázdný a teprve potom aktualizuju v db (tedy pokouším se). V současnosti to řeším takhle: $nazev_souboru = "udaje-klienta-".utf2ascii($_POST["prijmeni"]).".pdf"; $cesta = "soubory/".$_POST["nazev_slozka"]."/podklady/$nazev_souboru"; // Vygenerování souboru s údaji klienta include "php/pdf/udaje.php"; // Kontrola zda je buňka podklady prázdná $soubory = mysql_result(mysql_query("SELECT podklady FROM poptavka WHERE id='".$_POST["id"]."'"),0); if($soubory!="") { // Není prázdná if(!preg_match("~$nazev_souboru~",$soubory)) { // není obsažen v záznamu - vkládá se if(copy("img/ikony/pdf.png","soubory/".$_POST["nazev_slozka"]."/podklady/nahledy/nahl-".SubStr($nazev_souboru,0,-4).".png")) { // Aktualizace záznamu $nazev_souboru = ",".$nazev_souboru; mysql_query("UPDATE poptavka SET podklady = concat(podklady, '$nazev_souboru') WHERE id='".$_POST["id"]."'"); echo VypisChybuMysql(); // Potom odstranit } } } else { // Je prázdná if(copy("img/ikony/pdf.png","soubory/".$_POST["nazev_slozka"]."/podklady/nahledy/nahl-".SubStr($nazev_souboru,0,-4).".png")) { $sql = "UPDATE poptavka SET podklady = '$nazev_souboru' WHERE id = '".$_POST["id"]."'"; echo $sql."<br />"; mysql_query($sql); echo VypisChybuMysql(); } } Díky |
||
Tori Profil |
$sql = "UPDATE poptavka SET podklady = IF(podklady = '', '$nazev_souboru', CONCAT(podklady, ',', '$nazev_souboru')) WHERE id = ".(int)$_POST['id']; |
||
Prefin Profil |
#6 · Zasláno: 15. 3. 2014, 11:59:56 · Upravil/a: Prefin
Tori:
Díky, to je přesně ono. K těmhle kombinacím jsem se nějak ještě nedostal. Náhodou není nápad, proč by se měl odřezávat poslední znak, viz výše? Tori: Mohu se ještě zeptat na důvod tohoto: WHERE id = ".(int)$_POST['id']. Je to informování db o tom, jaký datový typ je obsažen v $_POST['id']? |
||
juriad Profil |
Prefin:
„WHERE id = ".(int)$_POST['id'].“ Je to z důvodu ošetření vstupu. Představ si, že by uživatel zadal do pole id ' OR 1=1 -- . V takovém případě by byla podmínka platná na všech řádcích.
Musíš tedy zajistit, aby se součástí dotazu stalo jen neškodné ID, v tomto případě ho stačí přetypovat na číslo. Pokud to byl původně řetězec obsahující číslo, nic se nezmění. Pokud id původně obsahovalo něco jiného než číslici, nějak inteligentně se to převede na číslo; obvykle na 0. |
||
Prefin Profil |
#8 · Zasláno: 15. 3. 2014, 12:32:48
Aha, no jasně.
Tady nekontroluju id jenom proto, že se do téhle části serveru nikdo jiný nedostane a pokud neodpovídá typem a hodnotou větší než 0 (třeba nějakou chybou) tak se celá tahle část kódu neprovede. Díky za pěkný typ ošetření. |
||
Tori Profil |
#9 · Zasláno: 15. 3. 2014, 13:00:11
Prefin:
„Náhodou není nápad, proč by se měl odřezávat poslední znak, viz výše?“ V souboru php/pdf/udaje.php přímo pracujete s proměnnou $nazev_souboru? Nemohlo dojít k chybě v něm? (A asi bych generování souboru zabalila do funkce a tu potom volala v hlavním skriptu a předala jí všechny podstatné údaje.)
|
||
Prefin Profil |
Tori:
To už jsem také pověřoval. V php/pdf/udaje.php se využívá $cesta pro $pdf->Output($cesta,F); .
Prostě už mě nenapadá co by to mohlo dělat. Ještě přikládám screen nastavení sloupce podklady: poptavky_screen.png. Asi vrátím občanku, pas, řidičák, piloťák a papíry na vykosozdvižnej vozejk, a pak se půjdu oběsit do rybníka. Upravil jsem to podle Tori: // Vygenerování pdf souboru s údaji $nazev_souboru = "udaje-klienta-".utf2ascii($_POST["prijmeni"]).".pdf"; $cesta = "soubory/".$_POST["nazev_slozka"]."/podklady/$nazev_souboru"; // Vygenerování souboru s údaji klienta include "php/pdf/udaje.php"; $cesta_nahled = "soubory/".$_POST["nazev_slozka"]."/podklady/nahledy/nahl-".SubStr($nazev_souboru,0,-4).".png"; if(!file_exists($cesta_nahled)) { // Není ještě vytvořen náhled copy("img/ikony/pdf.png",$cesta_nahled); } // Kontrola + aktualizace záznamu podklady mysql_query("UPDATE poptavka SET podklady = IF(podklady = '', '$nazev_souboru', CONCAT(podklady, ',', '$nazev_souboru')) WHERE id = ".(int)$_POST['id']); Nejhorší na tom je, že o kousek dál v kódu se do stejné buňky přidávají další vygenerované soubory k původním mysql_query("UPDATE poptavka SET podklady='$soubory' WHERE id='".$_POST["id"]."'"); |
||
Tori Profil |
#11 · Zasláno: 15. 3. 2014, 13:52:00
Ještě jsem z [#1] nepochopila: chybějící znak je vidět i v PhpMyAdmin, nebo jen na std. výstupu? (Že by to mohlo být uložené správně, a jen se špatně zobrazovat.)
|
||
Prefin Profil |
#12 · Zasláno: 15. 3. 2014, 14:04:48
V phpmyadminu ten znak chybí - prostě není v db. Někde mezi dotazem a buňkou se uřízne - myslím že to v kódu není..
Ještě k tomu kombinovanému dotazu. V tomhle provedení ale pouze kontroluje, zda je buňka prázdná. Já byl ale potřeboval, jestli by v dokázal také zkontrolovat, zda není název souboru již vložen, protože takhle to vytváří duplicitu. Strčit do něj tohle if($soubory=="") { mysql_query('...'); // Vložení do prázdné buňky } else { if(!preg_match("/$nazev_souboru/",$soubory)) mysql_query('...'); // Připojení ke stávajícímu } |
||
Tori Profil |
#13 · Zasláno: 15. 3. 2014, 14:36:45
Prefin:
„Já byl ale potřeboval, jestli by v dokázal také zkontrolovat, zda není název souboru již vložen, protože takhle to vytváří duplicitu.“ Tak ještě se to dá mírně násilně řešit tímhle: $sql = "UPDATE poptavka SET podklady = IF(podklady = '', '$nazev_souboru', IF (FIND_IN_SET('$nazev_souboru', podklady) < 1, CONCAT(podklady, ',', '$nazev_souboru'), podklady)) WHERE id = ".(int)$_POST['id']; ... ale pořád to je obcházení správného návrhu, kterým by byla další tabulka se sloupci id_poptavky a soubor a primárním klíčem přes ně oba (vkládalo by se pomocí INSERT IGNORE).
|
||
Prefin Profil |
Vím, že to není správně, taky nejsem programátor.
Vyvíjím jednu poměrně speciální dost komplikovanou databázi a protože jsem sám pořádně netušil v době přípravy co a jak přesně by měla umět, rozhodl jsem se jí postavit nejprve sám a až bude hotová se všemi funkcemi, které by měla mít (na většinu jsem přišel až v průběhu tvorby), zadám jí do prof. výroby. Proto mi celkem až tak moc nejde o kvalitu kódu atd. (programátor ze mě v 48 letech už nebude). Přesto se často objevují problémy, díky kterým mi nedá spát, dokud na ně nepřijdu. Jen pro informaci - tabulka poptavky má celkem 67 sloupců což asi není dobře, ale teď to nevadí. Pořád jsem nepřišel na to, co se to děje s tím znakem. Díky |
||
Kajman Profil |
#15 · Zasláno: 15. 3. 2014, 16:15:20
Prefin:
Zkuste si aplikaci spustit i na jiném stroji (klidně i na jiné (nejlépe stabilní) verzí php a mysql). Třeba v té současné kombinaci je nějaký bug. |
||
Prefin Profil |
#16 · Zasláno: 15. 3. 2014, 16:58:28
Kajman:
Už to mám na Savaně, takže by musel být bug v php webhostingu. |
||
Prefin Profil |
#17 · Zasláno: 16. 3. 2014, 09:46:39
Vyřešeno - chyba mezi židlí a klávesnicí (jako vždy).
Ten znak se odstraňoval o 50 řádků dál. Díky za Váš čas. |
||
Časová prodleva: 11 let
|
0