Intereting Posts
PHP: защита от инъекций с использованием подготовленных операторов Попытка получить общую сумму на основе ввода пользователем Как создать документацию по автоматическому коду для проекта PHP? Определить конечное назначение сокращенного URL-адреса в PHP? PHP добавляет 1 месяц к настоящему времени PHP – включена функция «включить»? Ошибка руководства Phalcon PhalconException: класс обработчика TestController не может быть загружен Symfony2 / Doctrine2 – Escaping специальный символ в пароле Eclipse indigo PDT 3.0 получил Как установить тип контента с помощью Zend_Http_Client в PUT? Как обновить строку с несколькими изображениями, которые имеют только одно изображение, вставленное первоначально в php Как перенаправить и / или задержать в зависимости от реферера? Увеличивает ли php время загрузки страницы? Как создать разбиение на страницы в Codeiginter? Как зарегистрировать пользователя в сеансе в функциональном тесте в Symfony 2.3?

Изменить атрибут html с помощью php

У меня есть строка html, содержащая в ней ровно один a-элемент. Пример:

<a href="http://www.test.com" rel="nofollow external">test</a> 

В php мне нужно проверить, содержит ли rel внешние и если да, то измените href и сохраните строку.

Я искал узлы и объекты DOM. Но они кажутся слишком сильными только для одного элемента A, поскольку я должен итерации, чтобы получить html-узлы, и я не уверен, как проверить, существует ли rel и содержит внешние .

 $html = new DOMDocument(); $html->loadHtml($txt); $a = $html->getElementsByTagName('a'); $attr = $a->item(0)->attributes(); ... 

На этом этапе я собираюсь получить NodeMapList, который кажется накладным. Есть ли более простой способ для этого или я должен делать это с DOM?

Есть ли более простой способ для этого или я должен делать это с DOM?

Сделайте это с помощью DOM.

Вот пример:

 <?php $html = '<a href="http://example.com" rel="nofollow external">test</a>'; $dom = new DOMDocument; $dom->loadHTML($html); $xpath = new DOMXPath($dom); $nodes = $xpath->query("//a[contains(concat(' ', normalize-space(@rel), ' '), ' external ')]"); foreach($nodes as $node) { $node->setAttribute('href', 'http://example.org'); } echo $dom->saveHTML(); 

Лучший способ – использовать парсер HTML / DOM, но это решение регулярных выражений:

 $html = '<a href="http://www.test.com" rel="nofollow external">test</a><br> <p> Some text</p> <a href="http://test.com">test2</a><br> <a rel="external">test3</a> <-- This won\'t work since there is no href in it. '; $new = preg_replace_callback('/<a.+?rel\s*=\s*"([^"]*)"[^>]*>/i', function($m){ if(strpos($m[1], 'external') !== false){ $m[0] = preg_replace('/href\s*=\s*(("[^"]*")|(\'[^\']*\'))/i', 'href="http://example.com"', $m[0]); } return $m[0]; }, $html); echo $new; 

Онлайн-демонстрация .

Я продолжал изменять с помощью DOM. Это то, что я получаю:

 $html = new DOMDocument(); $html->loadHtml('<?xml encoding="utf-8" ?>' . $txt); $nodes = $html->getElementsByTagName('a'); foreach ($nodes as $node) { foreach ($node->attributes as $att) { if ($att->name == 'rel') { if (strpos($att->value, 'external')) { $node->setAttribute('href','modified_url_goes_here'); } } } } $txt = $html->saveHTML(); 

Я не хотел загружать любую другую библиотеку только для одной строки.

Вы можете использовать регулярное выражение, например, if it matches /\s+rel\s*=\s*".*external.*"/ затем замените /(<a.*href\s*=\s*")([^"]\)("[^>]*>)/\1[your new href here]\3/ как /(<a.*href\s*=\s*")([^"]\)("[^>]*>)/\1[your new href here]\3/

Хотя использование библиотеки, которая может делать такие вещи для вас, намного проще (например, jquery для javascript)