Jak spolehlivě uložit jakýkoliv string?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Drake
Člen | 13
+
0
-

Problém: používám CKeditor s nějakými doplňky a výsledný string nijak nekontroluju, chci ho jenom uložit do MySQL a v původní formě načíst zpět, řešení speciálních znaků nechávám na Nette Database. Bohužel, často se mi na vstupu vyskytnou speciální znaky, které způsobí, že se daný string uloží až do daného divného znaku a zbytek se neuloží. MySQL přitom ani nezahlásí žádnou chybu.

Příklad, který má uložit start [speciální znak] konec, ale uloží jenom start:

// příklad jednoho z speciální znaků, který jsem vystopoval přes ord()
$data = "start ".chr("237")." konec";
$id = 1;
$query = "UPDATE ".$this->nazev."
    SET data = ?
    WHERE id = ?";
$this->database->query($query, $data, $id);

Nechci řešit proč a jak se tam ten speciální znak dostal, protože tomu nezabráním. Chci jen nějak zajistit, aby se správně uložil do databáze a pak se zase správně načetl. Nebo aby se alespoň uložil ten zbytek za ním. Žádné řešení mě nenapadá, protože ukládání nefunguje ani přímo přes mysqli_query, ale ten samý sql příkaz v phpmyadmin se stejnými daty udělá to co má.

Řešení:
Problém byl nevalidní UTF-8 řetězec, napraví se pomocí funkce mb_convert_encoding

// příklad jednoho z speciální znaků, který jsem vystopoval přes ord()
$data = "start ".chr("237")." konec";
//oprava špatného řetězce
$data = mb_convert_encoding($data, 'UTF-8');
$id = 1;
$query = "UPDATE ".$this->nazev."
    SET data = ?
    WHERE id = ?";
$this->database->query($query, $data, $id);

Editoval Drake (26. 7. 2013 12:31)

Jan Tvrdík
Nette guru | 2595
+
0
-

@Drake: Jestli ono to není tím, že $data není validní UTF-8 řetězec.

David Grudl
Nette Core | 8228
+
0
-

Odkud ty data získáváš?

Drake
Člen | 13
+
0
-

Data zadávají uživatelé do CKeditoru.

Ano, není to validní UTF-8 řetězec. Testuje to funkce mb_check_encoding. Napadlo mě to tedy převést znovu na UTF-8 funkcí mb_convert_encoding a funguje to. Divné znaky to vynechá, ale zbytek to zapíše do databáze.

Díky za radu, nikdy by mě nenapadlo, že nějaký řetězec může být nevalidní.

Jan Tvrdík
Nette guru | 2595
+
0
-

@Drake: Stejně by mě zajímalo, jak jsi k těm datům přistupoval, protože mám zato, že nevalidní UTF-8 vstupy filtruje Nette na úrovni Nette\Http\RequestFactory, takže pokud nepoužíváš přímo $_POST, ale bereš si ty data z Nette\Application\Request, tak by se tam nevalidní UTF-8 vstupy neměly objevit.

Druhá poznámka je k tomu, že máš pravděpodobně špatně nastavený CKEditor, kódování na stránce nebo tak něco. Rozhodně by CKEditor neměl posílat nevalidní UTF-8 řetězce.

Drake
Člen | 13
+
0
-

Data jsem právě musel brát z $_POST, protože ve formuláři to někdy bylo prázdné.

Co je špatně v CKEditoru netuším, stáhl jsem normální verzi bez doplňků a dělalo to taky. A hrabat se v tom jejich javascriptu je kontraproduktivní.

Navíc tohle byla náhodná chyba, která se nedala pro stejný vstup z editoru zopakovat a to jen na některých počítačích, odchytit se to dalo až na úrovni modelu. Najít tuhle chybu byla noční můra a to navíc ještě není všechno, pořád to občas špatně ukládá data z normálního formuláře bez CKEditoru… Odchytávání takovýchhle chyb mě na programování fakt baví nejmíň.