PHPackages                             ryangittings/didom - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. ryangittings/didom

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

ryangittings/didom
==================

Simple and fast HTML parser

1.13(8y ago)034MITPHPPHP &gt;=5.4

Since Aug 15Pushed 7y agoCompare

[ Source](https://github.com/ryangittings/DiDOM)[ Packagist](https://packagist.org/packages/ryangittings/didom)[ Docs](https://github.com/Imangazaliev/DiDOM)[ RSS](/packages/ryangittings-didom/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependencies (1)Versions (51)Used By (0)

DiDOM
=====

[](#didom)

DiDOM - simple and fast HTML parser.

Contents
--------

[](#contents)

- [Installation](#installation)
- [Quick start](#quick-start)
- [Creating new document](#creating-new-document)
- [Search for elements](#search-for-elements)
- [Verify if element exists](#verify-if-element-exists)
- [Supported selectors](#supported-selectors)
- [Output](#output)
- [Creating a new element](#creating-a-new-element)
- [Getting the name of an element](#getting-the-name-of-an-element)
- [Getting parent element](#getting-parent-element)
- [Getting sibling elements](#getting-sibling-elements)
- [Getting the child elements](#getting-the-child-elements)
- [Getting document](#getting-document)
- [Working with element attributes](#working-with-element-attributes)
- [Comparing elements](#comparing-elements)
- [Adding a child element](#adding-a-child-element)
- [Replacing element](#replacing-element)
- [Removing element](#removing-element)
- [Working with cache](#working-with-cache)
- [Miscellaneous](#miscellaneous)
- [Comparison with other parsers](#comparison-with-other-parsers)

Installation
------------

[](#installation)

To install DiDOM run the command:

```
composer require imangazaliev/didom

```

Quick start
-----------

[](#quick-start)

```
use DiDom\Document;

$document = new Document('http://www.news.com/', true);

$posts = $document->find('.post');

foreach($posts as $post) {
    echo $post->text(), "\n";
}
```

Creating new document
---------------------

[](#creating-new-document)

DiDom allows to load HTML in several ways:

##### With constructor

[](#with-constructor)

```
// the first parameter is a string with HTML
$document = new Document($html);

// or URL
$document = new Document('http://www.example.com/', true);
```

The second parameter specifies if you need to load file. Default is `false`.

##### With separate methods

[](#with-separate-methods)

```
$document = new Document();

$document->loadHtml($html);

$document->loadHtmlFile('http://www.example.com/');
```

There are two methods available for loading XML: `loadXml` and `loadXmlFile`.

These methods accept additional options:

```
$document->loadHtml($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
```

Search for elements
-------------------

[](#search-for-elements)

DiDOM accepts CSS selector or XPath as an expression for search. You need to path expression as the first parameter, and specify its type in the second one (default type is `Query::TYPE_CSS`):

##### With method `find()`:

[](#with-method-find)

```
use DiDom\Document;
use DiDom\Query;

...

// CSS selector
$posts = $document->find('.post');

// XPath
$posts = $document->find("//div[contains(@class, 'post')]", Query::TYPE_XPATH);
```

If the elements that match a given expression are found, then method returns an array of instances of `DiDom\Element`, otherwise - an empty array. You could also get an array of `DOMElement` objects. To get this, pass `false` as the third parameter.

##### With magic method `__invoke()`:

[](#with-magic-method-__invoke)

```
$posts = $document('.post');
```

##### With method `xpath()`:

[](#with-method-xpath)

```
$posts = $document->xpath("//*[contains(concat(' ', normalize-space(@class), ' '), ' post ')]");
```

You can do search inside an element:

```
echo $document->find('nav')[0]->first('ul.menu')->xpath('//li')[0]->text();
```

### Verify if element exists

[](#verify-if-element-exists)

To verify if element exist use `has()` method:

```
if ($document->has('.post')) {
    // code
}
```

If you need to check if element exist and then get it:

```
if ($document->has('.post')) {
    $elements = $document->find('.post');
    // code
}
```

but it would be faster like this:

```
if (count($elements = $document->find('.post')) > 0) {
    // code
}
```

because in the first case it makes two requests.

Supported selectors
-------------------

[](#supported-selectors)

DiDom supports search by:

- tag
- class, ID, name and value of an attribute
- pseudo-classes:
    - first-, last-, nth-child
    - empty and not-empty
    - contains
    - has

```
// all links
$document->find('a');

// any element with id = "foo" and "bar" class
$document->find('#foo.bar');

// any element with attribute "name"
$document->find('[name]');
// the same as
$document->find('*[name]');

// input field with the name "foo"
$document->find('input[name=foo]');
$document->find('input[name=\'bar\']');
$document->find('input[name="baz"]');

// any element that has an attribute starting with "data-" and the value "foo"
$document->find('*[^data-=foo]');

// all links starting with https
$document->find('a[href^=https]');

// all images with the extension png
$document->find('img[src$=png]');

// all links containing the string "example.com"
$document->find('a[href*=example.com]');

// text of the links with "foo" class
$document->find('a.foo::text');

// address and title of all the fields with "bar" class
$document->find('a.bar::attr(href|title)');
```

Output
------

[](#output)

### Getting HTML

[](#getting-html)

##### With method `html()`:

[](#with-method-html)

```
$posts = $document->find('.post');

echo $posts[0]->html();
```

##### Casting to string:

[](#casting-to-string)

```
$html = (string) $posts[0];
```

##### Formatting HTML output

[](#formatting-html-output)

```
$html = $document->format()->html();
```

An element does not have `format()` method, so if you need to output formatted HTML of the element, then first you have to convert it to a document:

```
$html = $element->toDocument()->format()->html();
```

#### Inner HTML

[](#inner-html)

```
$innerHtml = $element->innerHtml();
```

Document does not have the method `innerHtml()`, therefore, if you need to get inner HTML of a document, convert it into an element first:

```
$innerHtml = $document->toElement()->innerHtml();
```

### Getting XML

[](#getting-xml)

```
echo $document->xml();

echo $document->first('book')->xml();
```

### Getting content

[](#getting-content)

```
$posts = $document->find('.post');

echo $posts[0]->text();
```

Creating a new element
----------------------

[](#creating-a-new-element)

### Creating an instance of the class

[](#creating-an-instance-of-the-class)

```
use DiDom\Element;

$element = new Element('span', 'Hello');

// Outputs "Hello"
echo $element->html();
```

First parameter is a name of an attribute, the second one is its value (optional), the third one is element attributes (optional).

An example of creating an element with attributes:

```
$attributes = ['name' => 'description', 'placeholder' => 'Enter description of item'];

$element = new Element('textarea', 'Text', $attributes);
```

An element can be created from an instance of the class `DOMElement`:

```
use DiDom\Element;
use DOMElement;

$domElement = new DOMElement('span', 'Hello');

$element = new Element($domElement);
```

### Using the method `createElement`

[](#using-the-method-createelement)

```
$document = new Document($html);

$element = $document->createElement('span', 'Hello');
```

Getting the name of an element
------------------------------

[](#getting-the-name-of-an-element)

```
$element->tag;
```

Getting parent element
----------------------

[](#getting-parent-element)

```
$document = new Document($html);

$input = $document->find('input[name=email]')[0];

var_dump($input->parent());
```

Getting sibling elements
------------------------

[](#getting-sibling-elements)

```
$document = new Document($html);

$item = $document->find('ul.menu > li')[1];

var_dump($item->previousSibling());

var_dump($item->nextSibling());
```

Getting the child elements
--------------------------

[](#getting-the-child-elements)

```
$html = 'FooBar';

$document = new Document($html);

$div = $document->first('div');

// element node (DOMElement)
// string(3) "Bar"
var_dump($div->child(1)->text());

// text node (DOMText)
// string(3) "Foo"
var_dump($div->firstChild()->text());

// comment node (DOMComment)
// string(3) "Baz"
var_dump($div->lastChild()->text());

// array(3) { ... }
var_dump($div->children());
```

Getting document
----------------

[](#getting-document)

```
$document = new Document($html);

$element = $document->find('input[name=email]')[0];

$document2 = $element->getDocument();

// bool(true)
var_dump($document->is($document2));
```

Working with element attributes
-------------------------------

[](#working-with-element-attributes)

#### Creating/updating an attribute

[](#creatingupdating-an-attribute)

##### With method `setAttribute`:

[](#with-method-setattribute)

```
$element->setAttribute('name', 'username');
```

##### With method `attr`:

[](#with-method-attr)

```
$element->attr('name', 'username');
```

##### With magic method `__set`:

[](#with-magic-method-__set)

```
$element->name = 'username';
```

#### Getting value of an attribute

[](#getting-value-of-an-attribute)

##### With method `getAttribute`:

[](#with-method-getattribute)

```
$username = $element->getAttribute('value');
```

##### With method `attr`:

[](#with-method-attr-1)

```
$username = $element->attr('value');
```

##### With magic method `__get`:

[](#with-magic-method-__get)

```
$username = $element->name;
```

Returns `null` if attribute is not found.

#### Verify if attribute exists

[](#verify-if-attribute-exists)

##### With method `hasAttribute`:

[](#with-method-hasattribute)

```
if ($element->hasAttribute('name')) {
    // code
}
```

##### With magic method `__isset`:

[](#with-magic-method-__isset)

```
if (isset($element->name)) {
    // code
}
```

#### Removing attribute:

[](#removing-attribute)

##### With method `removeAttribute`:

[](#with-method-removeattribute)

```
$element->removeAttribute('name');
```

##### With magic method `__unset`:

[](#with-magic-method-__unset)

```
unset($element->name);
```

Comparing elements
------------------

[](#comparing-elements)

```
$element  = new Element('span', 'hello');
$element2 = new Element('span', 'hello');

// bool(true)
var_dump($element->is($element));

// bool(false)
var_dump($element->is($element2));
```

Appending child elements
------------------------

[](#appending-child-elements)

```
$list = new Element('ul');

$item = new Element('li', 'Item 1');

$list->appendChild($item);

$items = [
    new Element('li', 'Item 2'),
    new Element('li', 'Item 3'),
];

$list->appendChild($items);
```

Adding a child element
----------------------

[](#adding-a-child-element)

```
$list = new Element('ul');

$item = new Element('li', 'Item 1');
$items = [
    new Element('li', 'Item 2'),
    new Element('li', 'Item 3'),
];

$list->appendChild($item);
$list->appendChild($items);
```

Replacing element
-----------------

[](#replacing-element)

```
$element = new Element('span', 'hello');

$document->find('.post')[0]->replace($element);
```

Removing element
----------------

[](#removing-element)

```
$document->find('.post')[0]->remove();
```

Working with cache
------------------

[](#working-with-cache)

Cache is an array of XPath expressions, that were converted from CSS.

#### Getting from cache

[](#getting-from-cache)

```
use DiDom\Query;

...

$xpath    = Query::compile('h2');
$compiled = Query::getCompiled();

// array('h2' => '//h2')
var_dump($compiled);
```

#### Cache setting

[](#cache-setting)

```
Query::setCompiled(['h2' => '//h2']);
```

Miscellaneous
-------------

[](#miscellaneous)

#### `preserveWhiteSpace`

[](#preservewhitespace)

By default, whitespace preserving is disabled.

You can enable the `preserveWhiteSpace` option before loading the document:

```
$document = new Document();

$document->preserveWhiteSpace();

$document->loadXml($xml);
```

#### `count`

[](#count)

The `count ()` method counts children that match the selector:

```
// prints the number of links in the document
echo $document->count('a');
```

```
// prints the number of items in the list
echo $document->first('ul')->count('li');
```

#### `matches`

[](#matches)

Returns `true` if the node matches the selector:

```
$element->matches('div#content');

// strict match
// returns true if the element is a div with id equals content and nothing else
// if the element has any other attributes the method returns false
$element->matches('div#content', true);
```

#### `isElementNode`

[](#iselementnode)

Checks whether an element is an element (DOMElement):

```
$element->isElementNode();
```

#### `isTextNode`

[](#istextnode)

Checks whether an element is a text node (DOMText):

```
$element->isTextNode();
```

#### `isCommentNode`

[](#iscommentnode)

Checks whether the element is a comment (DOMComment):

```
$element->isCommentNode();
```

Comparison with other parsers
-----------------------------

[](#comparison-with-other-parsers)

[Comparison with other parsers](https://github.com/Imangazaliev/DiDOM/wiki/Comparison-with-other-parsers-(1.0))

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity71

Established project with proven stability

 Bus Factor1

Top contributor holds 96.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~17 days

Recently: every ~40 days

Total

49

Last Release

3076d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5872869?v=4)[Ryan Gittings](/maintainers/ryangittings)[@ryangittings](https://github.com/ryangittings)

---

Top Contributors

[![Imangazaliev](https://avatars.githubusercontent.com/u/11244193?v=4)](https://github.com/Imangazaliev "Imangazaliev (222 commits)")[![pronskiy](https://avatars.githubusercontent.com/u/1196825?v=4)](https://github.com/pronskiy "pronskiy (4 commits)")[![atefBB](https://avatars.githubusercontent.com/u/10966925?v=4)](https://github.com/atefBB "atefBB (1 commits)")[![rakvium](https://avatars.githubusercontent.com/u/6672367?v=4)](https://github.com/rakvium "rakvium (1 commits)")[![tobeorla](https://avatars.githubusercontent.com/u/5021184?v=4)](https://github.com/tobeorla "tobeorla (1 commits)")[![nullproduction](https://avatars.githubusercontent.com/u/4736403?v=4)](https://github.com/nullproduction "nullproduction (1 commits)")[![ImangazalievM](https://avatars.githubusercontent.com/u/15188126?v=4)](https://github.com/ImangazalievM "ImangazalievM (1 commits)")

---

Tags

xmlparserhtmldidom

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/ryangittings-didom/health.svg)

```
[![Health](https://phpackages.com/badges/ryangittings-didom/health.svg)](https://phpackages.com/packages/ryangittings-didom)
```

###  Alternatives

[masterminds/html5

An HTML5 parser and serializer.

1.8k242.8M229](/packages/masterminds-html5)[imangazaliev/didom

Simple and fast HTML parser

2.2k2.3M64](/packages/imangazaliev-didom)[paquettg/php-html-parser

An HTML DOM parser. It allows you to manipulate HTML. Find tags on an HTML page with selectors just like jQuery.

2.4k7.9M123](/packages/paquettg-php-html-parser)[sunra/php-simple-html-dom-parser

Composer adaptation of: A HTML DOM parser written in PHP5+ let you manipulate HTML in a very easy way! Require PHP 5+. Supports invalid HTML. Find tags on an HTML page with selectors just like jQuery. Extract contents from HTML in a single line.

1.3k9.4M61](/packages/sunra-php-simple-html-dom-parser)[querypath/querypath

HTML/XML querying and processing (like jQuery)

8197.0M27](/packages/querypath-querypath)[laravie/parser

XML Document Parser for PHP

2342.1M8](/packages/laravie-parser)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
