Diskuze: Chybný preg_match
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 21 zpráv z 21.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Ahoj, v paternech se moc nevyznám, ale když jsem to zkusil spustit, tak mi to fungovalo. Do proměnné $match se mi uložily dvě hodnoty.
Array
(
[0] => <div id="lyrics-body-text">nějaký text</div>
[1] => nějaký text
)
Regex mas spravne,
Ak $obsah nemas prazdny, tak musis mat vsetko v poli $match. Vies nam ukazat
var_dump tvojho $obsah-u ?
Osobne, zvolil by som iny pristup, ale ten bude fungovat len ak je html kod je validny:
$dom = new DOMDocument();
$dom->loadHTML($obsah);
$xpath = new DOMXPath($dom);
$obsah = $xpath->query('//div[id="lyrics-body-text"]');
Vytvoris is DOM objejt a do neho si nacitas obsah. Objekt sa postara o parsovanie. A potom sa pytas DOM objektu na div s id=lyrics-body-text. Je to podbne ako PDO, ktoreho sa pytas rozne query do DB.
Nejsem moc znalý tak sem vložím celou funkci:
function ziskatlyrics($url) {
$platnost = 30; // 60 s
$soubor = urlencode($url);
if (
! file_exists($soubor) ||
(filemtime($soubor) <= time() - $platnost)
) {
// obsah se musí stáhnout z cizí URL
$obsah = file_get_contents($url);
preg_match('/<div id=\"lyrics-body-text\">(.*)<\/div>/', $obsah, $match);
// uložení obsahu do cache
file_put_contents("soubory/".$soubor, $match[1]);
}
// obsah je určitě v cachi
return file_get_contents("soubory/".$soubor);
}
echo ziskatlyrics("http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html");
echo "http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html";
Funkcia file_get_cotents nevie stiahnuť obsah z cudzej URL. To pravdepodobne vedie k nečakanému výsledku regulárneho výrazu, čo znefunkční file_put_contents (nehovoriac o tom, že ak súbor neexistuje z funkcie sa nevráti očakávaný obsah).
Zapni si vypisovanie chýb a skopíruj sem tie hlásenia.
žádné chyby to neháže, a script bych řekl že jefunkční, protože např. toto funguje:
function ziskatlyrics($url) {
$platnost = 30; // 60 s
$soubor = urlencode($url);
if (
! file_exists($soubor) ||
(filemtime($soubor) <= time() - $platnost)
) {
// obsah se musí stáhnout z cizí URL
$obsah = file_get_contents($url);
preg_match('/<pre.*?>(.*)<\/pre>/', $obsah, $match);
// uložení obsahu do cache
file_put_contents($soubor, $match[1]);
}
// obsah je určitě v cachi
return file_get_contents($soubor);
}
echo ziskatlyrics(
"http://www.classic-country-song-lyrics.com/babywontyoucomeouttonightlyricschords.html"
);
To znamená, že sa požadovaný obsah uloží do súboru?
Existuje na tej druhej stránke <div id="lyrics-body-text">?
EDIT: Odober zo zápisu v regexe to escapovanie. Keď nie je potrebné, tak sa zoberie a na stránke sa hľadá prvok <div id=\"lyrics-body-text\">, ktorý sa nenájde.
Text potřebuji vytáhnout z této stránky: http://www.metrolyrics.com/…-denver.html
Ano měl by se uložit do souboru.
A na této stránce existuje <div id="lyrics-body-text">
Ani když použiji
preg_match('/<div id="lyrics-body-text">(.*)<\/div>/', $obsah, $match);
nic se nestane
Vlož do kódu pod inicializáciu premennej $obsah:
var_dump($obsah)
Čo to vypíše?
Při var_dump($obsah); to načetlo celou tu stránku a v levém horním rohu je:string(101865) "
Skusal si uz toto?
function ziskatlyrics($url)
{
$dom = new DOMDocument();
$dom->loadHTMLFile($url);
$xpath = new DOMXPath($dom);
$obsah = $xpath->query('//div[id="lyrics-body-text"]');
return $obsah;
}
echo ziskatlyrics("http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html");
echo "http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html";
Zkoušel a hodí to chybu Catchable fatal error: Object of class DOMNodeList could not be converted to string in na řádku
echo ziskatlyrics("http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html");
aha, no tak to preto lebo je DOM je pokazeny, html stranka je prepletena
scriptami a podobne.
Ja nerad pouzivam regularne vyrazy lebo vzdy nieco nefunguje ako ma. Dalsie
riesenie ma napada rozdelit ho funkciou explode
function ziskatlyrics($url)
{
$content = file_get_contents($url);
$first_step = explode( '<div id="lyrics-body-text">' , $content );
$second_step = explode("</div>" , $first_step[1] );
$obsah = $second_step[0];
return $obsah;
}
echo ziskatlyrics("http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html");
echo "http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html";
EDIT: toto ale nebude fungovat spravne ak tvoj <div> obsahuje vo vnutri
dalsie divy a ukoncenia divov, lebo ti to sekne tam.
Moc ti děkuji za tvůj čas. Velice si mi pomohl. Žádné jiné divy tam nejsou takže je to v pořádku. Ještě jednou díky.
Jenom mi teď nastal problém při načítaní ajaxem. Pokud si otevřu tento samotný script v pořádku se text zobrazí. Pokud ho zavolám ajaxem tak se bohužel text nezobrazí
Je to proto, protože vracíš element a ne text. DOMNodeList nemá definovanout metodu toString, takže to vrátí chybu. Navíc DOMXPath je zbytečný, pokud jdou využít nativní metody DOMDocumentu.
function ziskatlyrics($url){
$dom = new DOMDocument();
$dom->loadHTMLFile($url);
$lyrics_element = $dom->getElementById('lyrics-body-text');
return $lyrics_element ? $lyrics_element->textContent : '';
}
echo ziskatlyrics("http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html");
Tvůj script hodí chyby http://country.funsite.cz/lyrics_2.php
To je chyba DOMDocumentu, protože takové HTML5 neovládá vůbec. Takže máš 3 možnosti:
Zobrazeno 21 zpráv z 21.