Найти и добавить ссылки определенного класса - PullRequest
2 голосов
/ 13 апреля 2011

Я искал решение этой проблемы, но пока не нашел правильной вещи.

Ситуация такая: Мне нужно найти все ссылки на странице с данным классом (скажем, class="tracker"), а затем добавить значения строки запроса в конце, поэтому, когда пользователь загружает страницу, эти определенные ссылки обновляются с некоторой динамической информацией.

Я знаю, как это можно сделать с Javascript , но я бы очень хотел адаптировать его для запуска на стороне сервера. Я совершенно новичок в PHP , но, судя по всему, XPath может быть тем, что я ищу, но я не нашел подходящего примера для начала. Есть что-нибудь вроде GetElementByClass?

Любая помощь будет принята с благодарностью!

Shadowise

Ответы [ 3 ]

3 голосов
/ 13 апреля 2011

Есть ли что-то вроде GetElementByClass?

Вот реализация, которую я взбил ...

function getElementsByClassName(DOMDocument $domNode, $className) {
    $elements = $domNode->getElementsByTagName('*');
    $matches = array();
    foreach($elements as $element) {
        if ( ! $element->hasAttribute('class')) {
            continue;
        }
        $classes = preg_split('/\s+/', $element->getAttribute('class'));
        if ( ! in_array($className, $classes)) {
            continue;
        }
        $matches[] = $element;
    }
    return $matches;
}

Эта версия не зависит отвспомогательная функция выше.

$str = '<body>
    <a href="">a</a>
        <a href="http://example.com" class="tracker">a</a>
        <a href="http://example.com?hello" class="tracker">a</a>
    <a href="">a</a>
</body>
    ';

$dom = new DOMDocument;

$dom->loadHTML($str);

$anchors = $dom->getElementsByTagName('body')->item(0)->getElementsByTagName('a');

foreach($anchors as $anchor) {

    if ( ! $anchor->hasAttribute('class')) {
        continue;
    }

    $classes = preg_split('/\s+/', $anchor->getAttribute('class'));

    if ( ! in_array('tracker', $classes)) {
        continue;
    }

    $href = $anchor->getAttribute('href');

    $url = parse_url($href);

    $attach = 'stackoverflow=true';

    if (isset($url['query'])) {
        $href .= '&' . $attach;
    } else {
        $href .= '?' . $attach;
    }

    $anchor->setAttribute('href', $href);
}

echo $dom->saveHTML();

Вывод

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
    <a href="">a</a>
        <a href="http://example.com?stackoverflow=true" class="tracker">a</a>
        <a href="http://example.com?hello&amp;stackoverflow=true" class="tracker">a</a>
    <a href="">a</a>
</body></html>
2 голосов
/ 13 апреля 2011

Мне нужно найти все ссылки на странице с данным классом (скажем, class="tracker") [...] Я совершенно новичок в PHP , но, судя по всему,, XPath может быть то, что я ищу, но я не нашел подходящего примера для начала.Есть ли что-нибудь вроде GetElementByClass?

Это выражение XPath 1.0:

//a[contains(
       concat(' ',normalize-space(@class),' '),
       ' tracker '
    )
]
0 голосов
/ 13 апреля 2011

Немного короче, используя xpath:

$dom = new DomDocument();
$dom->loadXml('<?xml version="1.0" encoding="UTF-8" ?>
<root>
    <a href="somlink" class="tracker foo">label</a>
    <a href="somlink" class="foo">label</a>
    <a href="somlink">label</a>
    <a href="somlink" class="atrackerb">label</a>
    <a href="somlink">label</a>
    <a href="somlink" class="tracker">label</a>
    <a href="somlink" class="tracker">label</a>
</root>');

$xpath = new DomXPath($dom);

foreach ($xpath->query('//a[contains(@class, "tracker")]') as $node) {
    if (preg_match('/\btracker\b/', $node->getAttribute('class'))) {
        $node->setAttribute(
            'href',
            $node->getAttribute('href') . '#some_extra'
        );
    }

}

header('Content-Type: text/xml; charset"UTF-8"');
echo $dom->saveXml();
...