Cuando se habla de manipular el DOM, casi todo el contenido que aparece en Google se centra en JavaScript y el navegador. Sin embargo, PHP también permite trabajar directamente con el DOM HTML, solo que desde el lado del servidor.
En mi caso, cuando empecé a procesar HTML externo desde PHP, descubrí que la clase DOMDocument ofrece muchas de las mismas posibilidades que usamos en JavaScript, pero con un enfoque completamente distinto.
Qué es el DOM y cómo funciona cuando usamos PHP
El DOM como árbol de nodos
El DOM (Document Object Model) es una representación estructurada del documento HTML en forma de árbol de nodos. Cada etiqueta HTML es un nodo, cada atributo pertenece a un nodo y el texto también se representa como nodos hijos.
Cuando trabajamos con PHP, no interactuamos con el navegador, sino que procesamos el HTML directamente en el servidor. Esto es especialmente útil cuando:
- Necesitamos analizar HTML remoto.
- Queremos modificar una página antes de enviarla al cliente.
- Hacemos scraping o automatización.
- Limpiamos o transformamos contenido HTML.
Diferencias entre manipular el DOM con JavaScript y con PHP
Esta diferencia es clave para entender por qué este artículo no compite directamente con los clásicos de JavaScript:
- JavaScript PHP
- Se ejecuta en el navegador Se ejecuta en el servidor
- Manipula el DOM en tiempo real Manipula HTML antes de enviarlo
- Depende del usuario Totalmente controlado por backend
- Ideal para interacción Ideal para procesamiento
PHP es perfecto cuando necesitas modificar HTML sin depender del cliente, algo que JavaScript no puede hacer por sí solo.
Cargar y recorrer HTML con PHP y DOMDocument
En esta entrada veremos cómo acceder al DOM de una página web o contenido HTML con PHP; para esto haremos uso de la clase DOMDocument de PHP que nos permite realizar ciertas operaciones como las que hacemos con JavaScript empleando los selectores en la cual debemos especificar el número de la versión del documento, esto solo es un declaración y no tiene mayores repercusiones; el segundo parámetro corresponde a definir la codificación del contenido.
Cargar contenido HTML desde una URL
Para manipular el DOM en PHP usamos la clase DOMDocument. Un patrón que utilizo mucho es cargar HTML remoto y devolver sus nodos:
function getContent($url) {
if (stripos($url, 'http') !== 0) {
$url = 'http://' . $url;
}
$content = new DOMDocument('1.0', 'utf-8');
$content->preserveWhiteSpace = FALSE;
@$content->loadHTMLFile($url);
return $content->getElementsByTagName('*');
}Para esta función recibimos una URL en la cual validamos que esté presente la referencia al http, creamos un objeto de tipo DOMDocument para luego cargar el contenido HTML de nuestra URL con la función loadHTMLFile() en la cual le indicamos la URL del sitio a cargar; por último una función llamada a getElementsByTagName() que nos permite acceder al elemento que queramos, si es un párrafo p, h1, todos *, o cualquier tag conocido; a posterior, ya con los elementos seleccionados mediante nodos, podemos acceder a sus atributos y de esta manera podemos eliminar y/o secciones de código de una página en HTML desde PHP.
- preserveWhiteSpace permite remover o no espacios en blanco redundantes. Predeterminado a TRUE.
- Se valida que la URL tenga http.
- Se define versión y codificación del documento.
- preserveWhiteSpace elimina espacios en blanco innecesarios.
- loadHTMLFile() carga el HTML externo.
- getElementsByTagName('*') obtiene todos los nodos.
Finalmente, el código anterior tendría una salida como la siguiente:
getContent("http://www.desarrollolibre.net/blog");
// salida
object(DOMNodeList)#2 (1) {
["length"]=> int(184)
}En este punto ya tenemos el DOM completamente accesible desde PHP.
Obtener nodos y etiquetas HTML
Luego que tengamos el contenido referenciado a través de los nodos, podemos acceder al contenido a gusto; por ejemplo, podemos acceder a sus atributos como hacemos en la siguiente función:
function getAttribute($url, $attr) {
$result = array();
$content = new DOMDocument('1.0', 'utf-8');
$content->preserveWhiteSpace = FALSE;
@$content->loadHTMLFile($url);
$elements = $content
->getElementsByTagName('*');
foreach ($elements as $node) {
if ($node->hasAttribute($attr)) {
$value = $node->getAttribute($attr);
$result[] = trim($value);
}
}
return $result;
}Esto nos permite inspeccionar la estructura completa del documento y decidir qué modificar.
Acceder a atributos y contenido de los nodos
Como puedes ver, en esta oportunidad iteramos los nodos, que a la final son cada unos de los tags que tengamos definidos, accedemos a alguno de sus atributos que pasaríamos como uno de los parámetros en la firma de la función y los guardamos en un array; finalmente obtendremos algo como lo siguiente:
getAttribute("http://www.desarrollolibre.net/blog","class")
// *** salida
array(70) { [0]=> string(9) "logo_name" [1]=> string(4) "logo" [2]=> string(14) "logo_150_white" [3]=> string(4) "name" [4]=> string(13) "show_category" [5]=> string(15) "material-design" [6]=> string(19) "promotion col-md-12" [7]=> string(23) "col-md-4-p margin-1-p-p" [8]=> string(27) "card card1 white box-shadow" [9]=> string(15) "material-design" [10]=> string(23) "col-md-4-p margin-1-p-p" [11]=> string(27) "card card1 white box-shadow" [12]=> string(15) "material-design" [13]=> string(23) "col-md-4-p margin-1-p-p" [14]=> string(27) "card card1 white box-shadow" [15]=> string(15) "material-design" [16]=> string(10) "box-result" [17]=> string(14) "col-md-12 left" [18]=> string(22) "item-publication theme" [19]=> string(11) "rating-NULL" [20]=> string(4) "date" [21]=> string(9) "posted-on" [22]=> string(22) "item-publication theme" [23]=> string(11) "rating-NULL" [24]=> string(4) "date" [25]=> string(9) "posted-on" [26]=> string(29) "item-publication theme update" [27]=> string(11) "rating-NULL" [28]=> string(4) "date" [29]=> string(9) "posted-on" [30]=> string(3) "red" [31]=> string(14) "col-md-12 left" [32]=> string(22) "item-publication theme" [33]=> string(11) "rating-NULL" [34]=> string(4) "date" [35]=> string(9) "posted-on" [36]=> string(22) "item-publication theme" [37]=> string(11) "rating-NULL" [38]=> string(4) "date" [39]=> string(9) "posted-on" [40]=> string(22) "item-publication theme" [41]=> string(11) "rating-NULL" [42]=> string(4) "date" [43]=> string(9) "posted-on" [44]=> string(22) "item-publication theme" [45]=> string(11) "rating-NULL" [46]=> string(4) "date" [47]=> string(9) "posted-on" [48]=> string(14) "col-md-12 left" [49]=> string(22) "item-publication theme" [50]=> string(11) "rating-NULL" [51]=> string(4) "date" [52]=> string(9) "posted-on" [53]=> string(22) "item-publication theme" [54]=> string(11) "rating-NULL" [55]=> string(4) "date" [56]=> string(9) "posted-on" [57]=> string(22) "item-publication theme" [58]=> string(11) "rating-NULL" [59]=> string(4) "date" [60]=> string(9) "posted-on" [61]=> string(13) "show_category" [62]=> string(15) "material-design" [63]=> string(10) "pagination" [64]=> string(6) "active" [65]=> string(9) "next-link" [66]=> string(15) "scrollup fab_up" [67]=> string(22) "social-50 arrow_top_50" [68]=> string(19) "scrolldown fab_down" [69]=> string(25) "social-50 arrow_bottom_50" }Podemos también incorporar código HTML en alguna posición en especifica; por ejemplo, luego del quinto nodo por decir alguna posición:
function createElement($url) {
$content = new DOMDocument('1.0', 'utf-8');
$content->preserveWhiteSpace = FALSE;
@$content->loadHTMLFile($url);
$ins = $content->createElement("ins", "***ESTO ES UN TAG AGREGADO CON PHP***");
// agrega un elemento en la posición 5 posicion 5
$content->getElementsByTagName('h2')->item(4)->appendChild($ins);
}Leer atributos como class, id o href
Una tarea muy común es extraer atributos HTML. Por ejemplo, obtener todas las clases CSS de una página:
function getAttribute($url, $attr) {
$result = [];
$content = new DOMDocument('1.0', 'utf-8');
$content->preserveWhiteSpace = false;
@$content->loadHTMLFile($url);
$elements = $content->getElementsByTagName('*');
foreach ($elements as $node) {
if ($node->hasAttribute($attr)) {
$result[] = trim($node->getAttribute($attr));
}
}
return $result;
}Llamando a la función:
getAttribute("http://www.desarrollolibre.net/blog", "class");Obtenemos un array con todas las clases encontradas. Esto es especialmente útil cuando necesitas auditar HTML, limpiar estilos o analizar estructuras existentes.
Trabajar con DOMNodeList y recorrer nodos
DOMNodeList no es un array tradicional, pero se comporta de forma muy similar. Puedes acceder por índice:
$h2 = $content->getElementsByTagName('h2')->item(0);Y a partir de ahí navegar por padres, hijos y hermanos, exactamente como en JavaScript, pero desde PHP.
Crear y añadir elementos HTML dinámicamente con PHP
PHP también permite crear nuevos nodos HTML. En uno de mis proyectos, necesitaba insertar contenido dinámico dentro de una página existente, y este enfoque funciona perfectamente.
Crear nodos con createElement
En la función appendChild() que recibe como parámetro un elemento creado mediante el método createElement() que permite crear un elemento (en este ejemplo se creó un elemento de tipo ins según el primer parámetro establecido, con el contenido de -***ESTO ES UN TAG AGREGADO CON PHP***-).
function deleteElement($url) {
$content = new DOMDocument('1.0', 'utf-8');
$content->preserveWhiteSpace = FALSE;
@$content->loadHTMLFile($url);
// eliminamos un elemento
$h2 = $content->getElementsByTagName('h2')->item(0);
$pnode = $h2->parentNode;
$pnode->removeChild($h2);
}Insertar nodos con appendChild
Una vez creado el nodo, podemos insertarlo en cualquier parte del DOM:
Una vez creado el nodo, podemos insertarlo en cualquier parte del DOM:
$content
->getElementsByTagName('h2')
->item(4)
->appendChild($ins);En este ejemplo, el nuevo elemento se añade como hijo del quinto <h2> del documento. Este tipo de manipulación es muy potente cuando necesitas modificar HTML existente sin reescribirlo por completo.
Eliminar y modificar elementos del DOM HTML en PHP
Para eliminar un elemento, como mostramos en el código anterior con el primer h2 que exista en nuestra selección (para ello es la función item(0)), nos traemos el elemento padre del h2 con $h2->parentNode y luego eliminamos el h2 en cuestión con $pnode->removeChild($h2) empleando el elemento padre y como parámetro la referencia (el hijo) al h2.
Identificar nodos padre e hijo
Para eliminar un elemento, primero necesitamos su nodo padre. Este patrón lo uso constantemente:
$h2 = $content->getElementsByTagName('h2')->item(0);
$pnode = $h2->parentNode;El DOM siempre funciona en relaciones padre–hijo, y PHP no es la excepción.
Eliminar nodos con removeChild
Una vez que tenemos el nodo padre, eliminar el elemento es muy sencillo:
$pnode->removeChild($h2);Con esto eliminamos completamente el nodo <h2> del documento.
Puedes apreciar lo similar que es a JavaScript, pero ejecutándose completamente del lado servidor.
Buenas prácticas al manipular el DOM con PHP
Cuándo usar PHP en lugar de JavaScript
- Manipular el DOM con PHP es ideal cuando:
- Necesitas modificar HTML antes de enviarlo al navegador.
- Trabajas con HTML remoto.
- Automatizas tareas.
- Procesas contenido masivo.
- No reemplaza a JavaScript, pero lo complementa perfectamente.
- Recomendaciones finales
- Usa DOMDocument siempre que sea posible en lugar de expresiones regulares.
- Controla errores con cuidado al cargar HTML externo.
- No olvides la codificación (utf-8).
- Evita manipular nodos innecesarios para mejorar rendimiento.
Preguntas frecuentes (FAQ)
- ¿PHP puede manipular el DOM como JavaScript?
- Sí, pero desde el servidor y usando DOMDocument.
- ¿Se puede modificar HTML externo con PHP?
- Sí, usando loadHTMLFile() o loadHTML().
- ¿DOMDocument es seguro?
- Sí, siempre que controles el origen del HTML.
- ¿Esto sirve para scraping?
- Totalmente. Es uno de sus usos más comunes.
Conclusión
Manipular el DOM HTML con PHP es una técnica potente, poco explotada y extremadamente útil en backend. Con DOMDocument puedes leer, recorrer, modificar, crear y eliminar nodos HTML de forma estructurada y segura, sin depender del navegador ni de JavaScript.
Si ya dominas el DOM en JavaScript, aprender a hacerlo en PHP te abre muchas más posibilidades a nivel servidor.
Acepto recibir anuncios de interes sobre este Blog.
Se explica como emplear la clase de PHP DOMDocument para acceder al DOM de una web HTML, y de esta forma poder eliminar y crear elementos HTML así como acceder a sus atributos.