Dosazení odkazů do textu

Školení, která pořádám

API Twitteru v exportech nabízí tzv. entity – informace o aktivních částech textu, např. o URL adresách, uživatelích nebo haších. Aktivní části jsou označeny pomocí pozice svého začátku a konce. Jak postupovat, když chceme z textového tvítu vytvořit HTML kód s odkazy na jednotlivé entity?

Při přímočarém přístupu (bereme jednotlivé entity a postupně je nahrazujeme) samozřejmě narazíme hned u dvou entit – nahrazením původního textu vznikne delší text, takže se změní původní pozice. Nabízelo by se postupovat odzadu, to je ale taky problematické: entit je více druhů, takže bychom nejprve museli projít všechny, seřadit je do jednoho pole a zpracovat teprve to. Zásadní problém je ale v něčem jiném: tvíty obsahují běžný text, takže je před vytvořením HTML kódu musíme ošetřit funkcí htmlspecialchars – nemůžeme to udělat před nahrazením entit (protože by se změnily pozice) a nemůžeme to udělat ani potom (protože by se ošetřily i vytvořené odkazy). K problému bude potřeba přistoupit jinak.

Elegantní řešení spočívá v tom, že si text rozdělíme na jednotlivé znaky a pracujeme s nimi:

<?php
/** Vytvoří HTML kód s dosazenými URL adresami
* @param string čistý text v UTF-8
* @param array obsahuje pole array("start" => , "end" => , "url" => , "display_url" => )
* @return string HTML
* @copyright Jakub Vrána, https://php.vrana.cz/
*/
function html_urls($text, $urls) {
    $fragments = preg_split('~~u', $text, -1, PREG_SPLIT_NO_EMPTY);
    $fragments = array_map('htmlspecialchars', $fragments);
    foreach ($urls as $url) {
        $length = $url["end"] - $url["start"];
        $link = '<a href="' . htmlspecialchars($url["url"]) . '">' . htmlspecialchars($url["display_url"]) . '</a>';
        array_splice($fragments, $url["start"], $length, array($link) + array_fill(0, $length, ""));
    }
    return implode($fragments);
}
?>

Pro nahrazení části pole se používá funkce array_splice. Předáváme jí stejně dlouhé pole jako nahrazujeme (vytvořené pomocí array_fill(0, $length, "")), abychom neporušili nahrazení dalších entit.

Jakub Vrána, Řešení problému, 24.6.2011, diskuse: 1 (nové: 0)

Diskuse

Tomáš Fejfar:

Nice!

Diskuse je zrušena z důvodu spamu.

avatar © 2005-2024 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.