krzar / laravel-dom
Modern tool for Laravel to read and manipulate DOM Documents in Laravel style.
Requires
- php: ^8.3
- ext-dom: *
- ext-libxml: *
- illuminate/collections: ^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.24
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.0
README
Package allows you to query, create, update and delete DOM Documents in Laravel style
using functions like where, orWhere, whereHas etc.
You can get the first queried Element/Node or Collection of Elements/Nodes.
Requirements
| Version | Laravel | PHP | Supported |
|---|---|---|---|
| 2.x | 12.x - 13.x | 8.3 - 8.5 | ✅ |
| 1.x | 12.x | 8.2 - 8.5 | ✅ |
Installation
composer require krzar/laravel-dom
Documentation
Look here for every class detailed documentation, also to see how to add and manipulate DOM elements: Documentation
Examples
Create new Document
use KrZar\LaravelDom\Document; $htmlDocument = Document::loadHtml($html); $xmlDocument = Document::loadXml($xml);
Basic query example
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; $document = Document::loadHtml($html); $elements = $document->query('div', function(Query $query) { $query->where('class', 'searched-class'); })->get();
Available selectors
Caution
Using string values instead enum is deprecated and will be removed in the next major release.
equals (default)
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; use KrZar\LaravelDom\Query\Operator; $document = Document::loadHtml($html); $elements = $document->query('div', function(Query $query) { $query->where('class', Operator::EQUALS, 'searched-class'); })->get(); // OR $elements = $document->query('div', function(Query $query) { $query->whereEquals('class', 'searched-class'); })->get();
contains
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; use KrZar\LaravelDom\Query\Operator; $document = Document::loadHtml($html); $elements = $document->query('div', function(Query $query) { $query->where('class', Operator::CONTAINS, 'searched-class'); })->get(); // OR $elements = $document->query('div', function(Query $query) { $query->whereContains('class', 'searched-class'); })->get();
not equals
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; use KrZar\LaravelDom\Query\Operator; $document = Document::loadHtml($html); $elements = $document->query('div', function(Query $query) { $query->where('class', Operator::NOT_EQUALS, 'searched-class'); })->get(); // OR $elements = $document->query('div', function(Query $query) { $query->whereNotEquals('class', 'searched-class'); })->get();
not contains
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; use KrZar\LaravelDom\Query\Operator; $document = Document::loadHtml($html); $elements = $document->query('div', function(Query $query) { $query->where('class', Operator::NOT_CONTAINS, 'searched-class'); })->get(); // OR $elements = $document->query('div', function(Query $query) { $query->whereNotContains('class', 'searched-class'); })->get();
has
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; use KrZar\LaravelDom\Query\Operator; $document = Document::loadHtml($html); $elements = $document->query('div', function(Query $query) { $query->whereHas('id'); })->get(); // OR $elements = $document->query('div', function(Query $query) { $query->where('id', Operator::HAS); })->get();
not has
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; use KrZar\LaravelDom\Query\Operator; $document = Document::loadHtml($html); $elements = $document->query('div', function(Query $query) { $query->whereNotHas('id'); })->get(); // OR $elements = $document->query('div', function(Query $query) { $query->where('id', Operator::NOT_HAS); })->get();
Advanced examples
orWhere
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; use KrZar\LaravelDom\Query\Operator; $document = Document::loadHtml($html); $elements = $document->query('div', function(Query $query) { $query->where('class', Operator::CONTAINS, 'searched-class') ->orWhereHas('id'); })->query('a', function(Query $query) { $query->whereHas('href') ->whereContains('class', 'link'); })->get();
deep search
By default, a query is not searching deep inside DOM; it looks only for first children (XPath /).
To search deep for any child (XPath //) you need to add true on the end of query.
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; $document = Document::loadHtml($html); $elements = $document->query('a', function(Query $query) { $query->where('class', 'searched-class'); }, true)->get();
You can also use queryDeep method.
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; $document = Document::loadHtml($html); $elements = $document->queryDeep('a', function(Query $query) { $query->where('class', 'searched-class'); })->get();
Look for any
You can also look for any element just using *
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; $document = Document::loadHtml($html); $elements = $document->query('*', function(Query $query) { $query->where('class', 'searched-class'); })->get();
Nested conditions
If you want to search for condition like a || (b && c). You can make it using subqueries.
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; $document = Document::loadHtml($html); $elements = $document->query('span', function(Query $query) { $query->whereContains('class', 'searched-class') ->orWhere(function (Query $subQuery) { $subQuery->whereNotContains('class', 'another-class') ->whereEquals('title', 'some-title'); }); })->get();
Query text content
You can also query text content of an element.
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; use KrZar\LaravelDom\Query\Operator; $document = Document::loadHtml($html); $elements = $document->query('div', function(Query $query) { $query->where('class', Operator::CONTAINS, 'searched-class') ->whereText('Some text'); } )->get();
Available text methods
whereTextwhereTextEqualswhereTextNotEqualswhereTextContainswhereTextNotContainsorWhereTextorWhereTextEqualsorWhereTextNotEqualsorWhereTextContainsorWhereTextNotContains
By default these methods search only for text content of an element, not for element children.
To search deep for any child (XPath //) you need to add true on the end of the method.
For example:
use KrZar\LaravelDom\Document; use KrZar\LaravelDom\Query\Query; use KrZar\LaravelDom\Query\Operator; $document = Document::loadHtml($html); $elements = $document->query('div', function(Query $query) { $query->where('class', Operator::CONTAINS, 'searched-class') ->whereTextContains('Some text', true); } )->get();