Skip to content

Instantly share code, notes, and snippets.

@sumitpore
Created August 19, 2020 03:56
Show Gist options
  • Save sumitpore/fbc02157be054fda5a05e38f0a265f83 to your computer and use it in GitHub Desktop.
Save sumitpore/fbc02157be054fda5a05e38f0a265f83 to your computer and use it in GitHub Desktop.
Modify Html Tag Attributes in the HTML String
<?php
/**
* Modifies html tag attributes in the html string
*
* Remember, this will autofix the passed html. So if invalid html string is sent (e.g. `a` tag w/o end),
* then the o/p returned by function will be valid html string.
*
* Examples:
* 1. modifyHtmlTagAttrsInString(
* '<a href="http://example.com" class="bg-gray-200" data-extra="present">Example Site</a>',
* 'a',
* ['rel' => 'nofollow external', 'class' => '{EXISTING_VALUE} color-red']
* );
* Above will return `<a href="http://example.com" class="bg-gray-200 color-red" data-extra="present" rel="nofollow external">Example Site</a>`
*
* 2. modifyHtmlTagAttrsInString(
* '<a href="#""><span>Example Site</span></a>',
* '//a/span',
* ['class' => 'external-icon']
* );
* Above will return `<a href="#"><span class="external-icon">Example Site</span></a>`
*
* 3. modifyHtmlTagAttrsInString(
* '<a href="#">',
* 'a',
* ['class' => 'link']
* );
* Above will return `<a href="#" class="link"></a>`.
*
* @param string $htmlString html string in which we want to update tag attribute
* @param string $htmlTagXPath Query to search the html tag we are looking for. @see https://www.php.net/manual/en/domxpath.query.php
* @param array $attrs Attributes to be updated
* @return void
*/
function modifyHtmlTagAttrsInString($htmlString, $htmlTagXPath, $attrs = []) {
$dom = new DOMDocument;
$dom->loadHTML(mb_convert_encoding($htmlString, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
$htmlTagXPath = strpos($htmlTagXPath, '//') !== 0 ? "//{$htmlTagXPath}" : $htmlTagXPath;
$nodes = $xpath->query($htmlTagXPath);
foreach($nodes as $node) {
foreach($attrs as $attrName => $attrValue) {
$node->setAttribute($attrName, str_replace('{EXISTING_VALUE}', $node->getAttribute($attrName), $attrValue));
}
}
return $dom->saveHTML();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment