Autor Zpráva
nethor
Profil
Dobrý den,
řešil jsem nahrávání foto, které uživatel přetáhne (drag & drop) do pole TiniMce.

TiniMce takový obrázek zapíše přímo do HTML jako:
<img src="data:image/jpeg;base64,/9j/4AAQ ... šíleně dlouhý ... MDeAAeAGf/Z" alt="" />

Dekódování i upload jsem rozchodil, ale při úpravě zdroje pomocí preg_replace(); jsem narazil na hlášku
Compilation failed: regular expression is too large ...
Chápu, je to opravdu hodně dlouhý, ale nevíte , jak to řešit?

Jen potřebuju nahradit src "data:image/jpeg;base64,/9j/4AAQ ... šíleně dlouhý ... MDeAAeAGf/Z"' za "foto/new-filename.jpg".
anonymníí
Profil *
nethor:
Myslím, že můžeš ten regulár o prostředek zkrátit. Nejsem si jistý, jak přesně data:image formát vypadá, ale pokud je zdánlivě náhodný, bude stačit něco takového, riziko kolize v rámci jednoho postu je asi nulové.

~^data:image/jpeg;base64,/9j/4AAQ(.*)MDeAAeAGf/Z$~

Pokud potřebuješ vytáhnout i s okolním HTML (obrázkem a jeho atributy), do reguláru si začátek a konec doplň.
juriad
Profil
anonymníí:
Jen ty zarážky ^$ tam být nemají.

nethor:
Ty to můžeš dokonce udělat vše najednou. Pomocí preg_replace_callback si najdeš všechny obrázky "data:image/jpeg;base64[^"]", v callbacku je přeuložíš a nahradíš za cestu k souboru.
DarkMeni
Profil
Edit: blbě sem to pochopil, sorry, nenapadlo mě že to celý budeš psát do zdrojovýho kódu
nethor
Profil
anonymníí:
Jo, to funguje, díky.
Použil jsem:
// $Puvodni načteno jinde ...
$Nahrada= "~".preg_quote(substr($value, 0, 50))."(.*)".preg_quote(substr($value, -50, 50))."~iU"    ;    
...

$Html = preg_replace($PuvodniArray, $NahradaArray,$Html)  ;   // první dva parametry jsou pole.

juriad:
Nevím, ale na tohle se asi preg_replace_callback() nehodí, nejde o rutinní funkci,
Naplnil jsem si pole $PuvodniArray, $NahradaArray (zjednodušeno) v průběhu uploadu ve třídách a s těmi to umí preg_replace().

Narazil jsem ale na další problém, fce
    preg_match_all('~<img src="(data:([^;]*);base64,(.*))"~iU', $Html, $Arr)    ;    
mi nenachází shodu, když je řetězec delší než cca 100 000 znaků (to jsou jpegy cca 80kB) , vrací false, žádní chybová hláška, prázdné pole $Arr.

Tomu moc nerozumím, v manuálu jsem o omezení délky $subjectu nic nenašel.
Nevíte, jak řešit tohle?
tiso
Profil
nethor: ja som sa s tým už stretol. Jedno z riešení je rozdeliť regulár na 2 časti, nechať si vrátiť pozície jednotlivých častí a potom pomocou substr funkcie poskladať výsledok.
DarkMeni
Profil
Zkus
ini_set("pcre.backtrack_limit", "300000"); //300 000 znaků
php.net/manual/en/pcre.configuration.php
Monkeys
Profil *
Ja pozivam tento kod pri vypise z editoru,
netreba nastavovat ziadne limity a pocty znakov.

array_map("unlink", glob(TMP."*"));  //odstrani vsetky docasne subory zo zlozky
print preg_replace_callback('#(<img\s(?>(?!src=)[^>])*?src=")data:image/(gif|png|jpeg|jpg);base64,([\w=+/]++)("[^>]*>)#', "data_to_img", preg_replace('/<p[^>]*><\\/p[^>]*>/', "", $produkt['popis']));

function data_to_img( $match ) {
    list(, $img, $type, $base64, $end) = $match;

    $bin = base64_decode($base64); // vygeneruje obrazok
    $md5 = substr(md5($bin).uniqid(rand(0,1)),0,20);   // vygeneruje unikatny nazov obrazku
    $fn = TMP.$md5.".".$type; //spoji cestu, obrazok a typ obrazku
    file_exists($fn) or file_put_contents($fn, $bin); // ulozi obrazok do docasnej zlozky

    return "$img".str_replace(TMP, URL . "tmp/", $fn)."$end";  // vrati konecny obrazok do obsahu
}

TMP - docasna zlozka na ukadanie obrazkov
URL - domena

M.
nethor
Profil
DarkMeni:

ini_set("pcre.backtrack_limit","5000000"); zafungoval, děkuju!

... jen jsem ho musel nastavit o něco výš - na 5 000 000

Díky.

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:

0