Autor Zpráva
leomato
Profil *
Zdravím, chcem sa spýtať, ako mam UPDATEnuť databázu s PDO a nastaviť tam JSON s uloženou diakritikou bez straty diakritiky ?
Jan Tvrdík
Profil
leomato:
JSON je řetězec jako každý jiný. Stačí správně nastavit kódování při práci s databází. Viz také stackoverflow.com/questions/4361459/php-pdo-charset-set-names
leomato
Profil *
Jan Tvrdík:
Prosím Vás mohli by ste mi poradiť ako na to ? :)


Aha no ono je problem v tom že json to konvertuje do stringu kde su " a ' a PDO pridava pred ' \ čiže je tam potom \' a to už json_decode nespracuje spravne preto sa chcem spýtať ako sa da vypnuť pre tento string escapovanie v PDO :)
juriad
Profil
leomato:
Tak to prostě zkus. A pak se přes nějaký nástroj podívej, jestli se to do databáze zapsalo v pořádku.
Máš někde jinde problém s ukládáním diakritiky? Proč myslíš, že by to tentokrát nemuselo fungovat?


Ukaž kus kódu, pomocí kterého ukládáš ten JSON do databáze. Nejspíše něco neescapuješ nebo escapuješ špatně.
leomato
Profil *
->query("UPDATE products SET name = '".$new_name."' WHERE shop = '1' AND id = 'a9t8'");
a json je
{"sk":"\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1","en":"","de":"","cz":""}
a do databáze se zapíše
{"sk":"u00e1u00e1u00e1u00e1u00e1u00e1u00e1u00e1","en":"","de":"","cz":""}
takže v podstate to odstáni "\" ako sa to dá vypnúť prosím ? :)
juriad
Profil
Každý (opravdu každý) řetězec z proměnné, který ukládáš do databáze musíš prohnat funkcí PDO::quote. Jinak ti vždy bude hrozit, že uživatel zadá na vstupu apostrof a nebo něco horšího a selže ti dotaz; v horším případě můžeš přijít o data v databázi.

Co kdyby $new_name bylo náhodou ' --? Překrásný UPDATE, který změní name všem existujícím záznamům.
Na kolika místech toto neošetřuješ? Jaká, že je adresa tvého webu?

->query("UPDATE products SET name = '" . $conn->quote($new_name) . "' WHERE shop = '1' AND id = 'a9t8'");

Opraveno, ať to nemate budoucí generace.
leomato
Profil *
juriad:
Já vím, ale data uložene v JSONu jsou již zabezpečene a jen je potrebuju uložit ale PDO mi to nedovoluje.
Jan Tvrdík
Profil
juriad:
Metodu quote nelze volat staticky, musí být volaná na instanci připojení, tedy např:

$new_name = '{"sk":"\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1","en":"","de":"","cz":""}';
$conn = new PDO('...');
$conn->query("UPDATE products SET name = '" . $conn->quote($new_name) . "' WHERE shop = '1' AND id = 'a9t8'");

leomato:
PDO mi to nedovoluje
PDO tě v ničem neomezuje, JSON musíš escapovat jako každý jiný řetězec.
leomato
Profil *
Jan Tvrdík:
Jo, až na to když to budu quotovat tak se mi odstráni \ a pak už JSON decode z toho neudela zpatky diakritiku.
juriad
Profil
Jan Tvrdík:
Máš pravdu, přečetl jsem v dokumentaci návratovou hodnotu string jako static. :)


leomato:
Nepřemýšlej nad tím jako nad zabezpečením. Databáze prostě nějak chápe znak ' a nabízí metodu quote, která zajistí, že vstup pozmění tak, že vložen do databáze bude mít stejnou podobu jako byl na vstupu.
To, jak to provede je zcela v režii té metody quote; teoreticky by mohla vrátit něco co by se ani zdaleka neblížilo vstupu, ale ty bys měl stále záruku, že když to vložíš do databáze, bude následně obsahovat to, co jsi ty chtěl.
leomato
Profil *
juriad:
Až na to že quote tam nedávam protože odstrani \ a už se tam zpátky neobjeví ;) To je ten základní problem.
Radek9
Profil
leomato:
Nevěřím. Mně lomítka nemizí:
$pdo = new PDO(…);
echo $pdo->quote('{"sk":"\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1","en":"","de":"","cz":""}');
// '{\"sk\":\"\\u00e1\\u00e1\\u00e1\\u00e1\\u00e1\\u00e1\\u00e1\\u00e1\",\"en\":\"\",\"de\":\"\",\"cz\":\"\"}'
Jan Tvrdík
Profil
leomato:
Ach, proč se ptáš, když nám stejně nevěříš. Problém je jinde – $pdo->quote vrací řetězec už obalený uvozovkami, správně je to tedy takhle:

$new_name = '{"sk":"\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1\u00e1","en":"","de":"","cz":""}';
$conn = new PDO('...');
$conn->query("UPDATE products SET name = " . $conn->quote($new_name) . " WHERE shop = '1' AND id = 'a9t8'");

Případně si můžeš vyzkoušet i triviální
$conn->query("SELECT " . $conn->quote($new_name))->fetch();
leomato
Profil *
Dekuju už mi to funguje.

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: