Autor Zpráva
Prefin
Profil
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);
Echo vypíše:
UPDATE poptavka SET podklady='udaje-klienta.pdf' WHERE id='130'
Do db se však zapíše pouze udaje-klienta.pd
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
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
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();
    }
}
kdy v případě prázdné buňky se vloží výše zmíněný název souboru pro mě nepochopitelně zkrácený o poslední znak.
Díky
Tori
Profil
$sql = "UPDATE poptavka SET podklady = IF(podklady = '', '$nazev_souboru', CONCAT(podklady, ',', '$nazev_souboru')) WHERE id = ".(int)$_POST['id'];
Ale musí tam být přesně prázdný řetězec, ne mezera ani NULL.
Prefin
Profil
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
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
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']);
a stejně se uřízne poslední znak.
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"]."'");
a znaky to neuřezává.
Tori
Profil
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
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
}
Díky za Váš čas
Tori
Profil
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
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
Kajman:
Už to mám na Savaně, takže by musel být bug v php webhostingu.
Prefin
Profil
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.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

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