A fluent api for the php dom extension.

6.2.0 2017-07-29 17:49 UTC


Build Status Code Coverage Scrutinizer Code Quality

License Total Downloads Latest Stable Version Latest Unstable Version

Copyright: 2009-2017 FluentDOM Contributors
Licence: The MIT License

FluentDOM provides an easy to use fluent interface for DOMDocument. We tried to keep the jQuery API but adapted it to PHP and the server environment.

FluentDOM is a test driven project. We write tests before and during the development. You will find the PHPUnit test in the "tests" subdirectory.

Table Of Contents

  • Examples
  • Support
  • Requirements
  • Packagist
  • Usage
  • Backwards Compatibility Breaks


Read All Links in a HTML File

$document = FluentDOM::load(
  [FluentDOM\Loader\Options::ALLOW_FILE => TRUE]
foreach ($document('//a[@href]') as $a) {
  $links[] = [
    'caption' => (string)$a,
    'href' => $a['href']

Create a Select From an Array

$_ = FluentDOM::create();
$_->formatOutput = TRUE;
echo $_(
  ['name' => 'example'],
    ['One', 'Two', 'Three'],
    function($text, $index) use ($_) {
      return $_('option', ['value' => $index], $text);

Read Large XML Files (FluentDOM 6.2)

$reader = new FluentDOM\XMLReader();
$reader->registerNamespace('s', 'http://www.sitemaps.org/schemas/sitemap/0.9');

foreach (new FluentDOM\XMLReader\SiblingIterator($reader, 's:url') as $url) {
  /** @var FluentDOM\DOM\Element $url */
      'location' => $url('string(s:loc)'),
      'updated' => $url('string(s:lastmod)')


The wiki provides information and usage examples.

If you find a bug or have a feature request please report it in the issue tracker.

You can check out the Gitter chat, too.

Be ware that the release packages (downloads) do not include the examples or tests. They are not needed to use the library. If you clone the repository, they will be included.

Security Issues

If you find a bug that has security implications, you can send an email directly to thomas@weinert.info.



  • PHP >= 7.0
  • ext/dom

FluentDOM needs at least PHP 7.0 and the DOM extension. For some features additional extensions might be needed, like ext/json to load JSON strings.


FluentDOM 5.2 and later requires HHVM 3.5.

FluentDOM 4.0 to 5.1 work with HHVM 3.3 but it was limited. If you like to use HHVM it is strongly suggest to use newer releases.

FluentDOM 7.0 and later has not support for HHVM any more.


FluentDOM is available on Packagist.org, just add the dependency to your composer.json.

  "require" : {
    "fluentdom/fluentdom": "^6.0"

CSS Selectors

To use CSS selectors, you need a CSS to XPath library.

FluentDOM >= 5.3

Here is a new interface FluentDOM\Xpath\Transformer which is implemented in separate connector packages. Two are currently available.

  1. FluentDOM/Selectors-PHPCss
  2. FluentDOM/Selectors-Symfony

The packages provide a fluentdom/css-selector meta package.

FluentDOM <= 5.2

Had fixed support for two CSS to XPath libraries. If they are installed in the project CSS selects are available.

  1. Carica/PhpCss
  2. Symfony/CssSelector


The examples load the sample.xml file, look for tags <h1> with the attribute "id" that has the value "title", set the content of these tags to "Hello World" and output the manipulated document.

Extended DOM (FluentDOM >= 5.2)

Using the FluentDOM\Document class:

$fd = FluentDOM::load('sample.xml');
foreach ($fd('//h1[@id = "title"]') as $node) {
  $node->nodeValue = 'Hello World!';

echo $fd->saveXml();

jQuery Style API

Using the FluentDOM\Query class:

echo FluentDOM('sample.xml')
  ->find('//h1[@id = "title"]')
  ->text('Hello World!');

CSS Selectors

If you install a CSS selector to Xpath translation library into a project, you can use the FluentDOM::QueryCss() function. It returns a FluentDOM\Query instance supporting CSS 3 selectors.

$fd = FluentDOM::QueryCss('sample.xml')
  ->text('Hello World!');

Creating XML

New features in FluentDOM make it easy to create XML, even XML with namespaces. Basically you can register XML namespaces on the document and methods without direct namespace support (like createElement()) will resolve the namespace and call the namespace aware variant (like createElementNS()).

Check the Wiki for an example.

Backwards Compatibility Breaks

From 6.2 to 7.0

The minimum required PHP version now is 7.0. HHVM is not supported any more. Scalar type hints and return types were added.

Moved the extended DOM classes into the FluentDOM\DOM namespace. (FluentDOM\Document -> FluentDOM\DOM\Document). FluentDOM\Nodes\Creator was moved to FluentDOM\Creator. Several internal classes were moved into a FluentDOM\Utiltity namespace.

FluentDOM\Query::get() now return a DOMNodeis the position was provided, not an array any more.

FluentDOM\DOM\Element::find() was removed, use FluentDOM($element)->find().

From 5.3 to 6.0

The minimum required PHP version now is 5.6. HHVM support was removed.

FluentDOM\Query now parses fragment arguments depending on the content type. It uses the loaders to parse the fragments for methods like FluentDOM\Query::append(). To parse the fragments as XML change the content type after loading.

$fd = FluentDOM($content, 'type/some-type');
$fd->contentType = 'text/xml';

FluentDOM\Query::attr(), FluentDOM\Query::css() and FluentDOM\Query::data() now recognize that the second argument is provided, even if it is NULL.

Serializer factories can now be registered on the FluentDOM class. Loaders implement an additional method to parse a fragment. This allows the FluentDOM\Nodes() class to keep the content type used to load a source. Methods like append() now parse a string as a fragment of the current content type. Casting the FluentDOM\Nodes() instance to a string serializes it to the current content type.

$fd = FluentDOM('{"firstName": "John"}', 'text/json');
echo $fd->find('/*')->append('{"lastName": "Smith"}');

To get the previous behaviour you will have to change the content type to 'text/xml' after loading a source.

$fd = FluentDOM('{"firstName": "John"}', 'text/json');
$fd->contentType = 'text/xml';
echo $fd->find('/*')->append('<lastName>Smith</lastName>');

  <json:json xmlns:json="urn:carica-json-dom.2013">

Loaders have an additional method loadFragment(). Serializers are now expected to be able to serialize a node (not only a document).

You will now have to explicitly allow loaders to load a file.

$fd = FluentDOM('...', '...', [FluentDOM\Loader\Options::ALLOW_FILE => TRUE]);
$fd = FluentDOM('...', '...', [FluentDOM\Loader\Options::IS_FILE => TRUE]);

Previous BC breaks are documented in the Wiki.