README.md
1# PHP DOM Wrapper
2
3## Intro
4
5PHP DOM Wrapper is a simple DOM wrapper library to manipulate and traverse HTML documents. Based around jQuery's manipulation and traversal methods, largely mimicking the behaviour of it's jQuery counterparts.
6
7## Author
8
9 - Andrew Scott (andrew@andrewscott.net.au)
10
11## Requirements
12
13 - PHP 7.1 or later
14 - PSR-4 compatible autoloader
15
16## Install
17
18Install with [Composer](https://getcomposer.org/doc/).
19
20```
21composer require scotteh/php-dom-wrapper
22```
23
24## Autoloading
25
26This library requires an autoloader, if you aren't already using one you can include [Composers autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading).
27
28``` php
29require 'vendor/autoload.php';
30```
31
32## Methods
33
34### Manipulation
35
36| Method | jQuery Equivalent *(if different)* |
37|--------|------------------------------|
38| [addClass()](#addClass) |
39| [follow()](#follow) | *after()* |
40| [appendWith()](#appendWith) | *append()* |
41| [appendTo()](#appendTo) |
42| [attr()](#attr) |
43| [clone()](#clone) |
44| [destroy()](#destroy) | *remove()* |
45| [detach()](#detach) |
46| [empty()](#empty) |
47| [hasClass()](#hasClass) |
48| [html()](#html) |
49| [precede()](#precede) | *before()* |
50| [prependWith()](#prependWith) | *prepend()* |
51| [prependTo()](#prependTo) |
52| [removeAttr()](#removeAttr) |
53| [removeClass()](#removeClass) |
54| [substituteWith()](#substituteWith) | *replaceWith()* |
55| [text()](#text) |
56| [unwrap()](#unwrap) |
57| [wrap()](#wrap) |
58| [wrapAll()](#wrapAll) |
59| [wrapInner()](#wrapInner) |
60
61### Traversal
62
63| Method | jQuery Equivalent *(if different)* |
64|--------|------------------------------|
65| [add()](#add) |
66| [children()](#children) |
67| [closest()](#closest) |
68| [contents()](#contents) |
69| [eq()](#eq) |
70| [filter()](#filter) |
71| [find()](#find) |
72| [first()](#first) |
73| [has()](#has) |
74| [is()](#is) |
75| [last()](#last) |
76| [map()](#map) |
77| [following()](#following) | *next()* |
78| [followingAll()](#followingAll) | *nextAll()* |
79| [followingUntil()](#followingUntil) | *nextUntil()* |
80| [not()](#not) |
81| [parent()](#parent) |
82| [parents()](#parents) |
83| [parentsUntil()](#parentsUntil) |
84| [preceding()](#preceding) | *prev()* |
85| [precedingAll()](#precedingAll) | *prevAll()* |
86| [precedingUntil()](#precedingUntil) | *prevUntil()* |
87| [siblings()](#siblings) |
88| [slice()](#slice) |
89
90### Other
91
92| Method | jQuery Equivalent *(if different)* |
93|--------|------------------------------|
94| [count()](#count) | *length* (property) |
95| [each()](#each)
96
97## Usage
98
99Example #1:
100``` php
101use DOMWrap\Document;
102
103$html = '<ul><li>First</li><li>Second</li><li>Third</li></ul>';
104
105$doc = new Document();
106$doc->html($html);
107$nodes = $doc->find('li');
108
109// Returns '3'
110var_dump($nodes->count());
111
112// Append as a child node to each <li>
113$nodes->appendWith('<b>!</b>');
114
115// Returns: <html><body><ul><li>First<b>!</b></li><li>Second<b>!</b></li><li>Third<b>!</b></li></ul></body></html>
116var_dump($doc->html());
117```
118
119---
120
121## Methods
122
123### Manipulation
124
125#### addClass
126
127```
128self addClass(string|callable $class)
129```
130
131##### Example
132
133```php
134$doc = (new Document())->html('<p>first paragraph</p><p>second paragraph</p>');
135$doc->find('p')->addClass('text-center');
136```
137
138*Result:*
139
140``` html
141<p class="text-center">first paragraph</p><p class="text-center">second paragraph</p>
142```
143
144---
145
146#### follow
147
148```
149self follow(string|NodeList|\DOMNode|callable $input)
150```
151
152Insert the argument as a sibling directly after each of the nodes operated on.
153
154##### Example
155
156``` php
157$doc = (new Document())->html('<ul><li>first</li><li>second</li></ul>');
158$doc->find('li')->first()->follow('<li>first-and-a-half</li>');
159
160```
161
162*Result:*
163
164``` html
165<ul>
166 <li>first</li>
167 <li>first-and-a-half</li>
168 <li>second</li>
169</ul>
170```
171
172---
173
174#### appendWith
175
176```
177self appendWith(string|NodeList|\DOMNode|callable $input)
178```
179
180##### Example
181
182``` php
183$doc = (new Document())->html('<div>The quick brown fox jumps over the lazy dog</div>');
184$doc->find('div')->appendWith('<strong> Appended!</strong>');
185```
186
187*Result:*
188
189``` html
190<div>The quick brown fox jumps over the lazy dog<strong> Appended!</strong></div>
191```
192
193---
194
195#### appendTo
196
197```
198self appendTo(string|NodeList|\DOMNode $selector)
199```
200
201##### Example
202
203``` php
204$doc = (new Document())->html('<div>The quick brown fox jumps over the lazy dog</div>');
205$doc->create('<strong> Appended!</strong>')->appendTo('div');
206```
207
208*Result:*
209``` html
210<div>The quick brown fox jumps over the lazy dog<strong> Appended!</strong></div>
211```
212
213---
214
215#### attr
216
217```
218self|string attr(string $name[, mixed $value = null])
219```
220
221##### Example #1 (Set)
222
223``` php
224$doc = (new Document())->html('<div class="text-center"></div>');
225$doc->attr('class', 'text-left');
226```
227
228*Result:*
229
230``` html
231<div class="text-left"></div>
232```
233
234##### Example #2 (Get)
235
236``` php
237$doc = (new Document())->html('<div class="text-center"></div>');
238echo $doc->attr('text-center');
239```
240
241*Result:*
242
243``` html
244text-center
245```
246
247---
248
249#### precede
250
251```
252self precede(string|NodeList|\DOMNode|callable $input)
253```
254
255Insert the argument as a sibling just before each of the nodes operated on.
256
257##### Example
258
259``` php
260$doc = (new Document())->html('<ul><li>first</li><li>second</li></ul>');
261doc->find('li')->first()->precede('<li>zeroth</li>');
262```
263
264*Result:*
265
266``` html
267<ul>
268 <li>zeroth</li>
269 <li>first</li>
270 <li>second</li>
271</ul>
272```
273
274---
275
276#### clone
277
278```
279NodeList|\DOMNode clone()
280```
281
282##### Example
283
284``` php
285$doc = (new Document())->html('<ul><li>Item</li></ul>');
286$doc->find('div')->clone()->appendTo('ul');
287```
288
289*Result:*
290
291``` html
292<ul><li>Item</li><li>Item</li></ul>
293```
294
295---
296
297#### destroy
298
299```
300self destroy([string $selector = null])
301```
302
303##### Example
304
305``` php
306$doc = (new Document())->html('<ul><li class="first"></li><li class="second"></li></ul>');
307$doc->find('.first')->destroy();
308```
309
310*Result:*
311``` html
312<ul><li class="second"></li></ul>
313```
314
315---
316
317#### detach
318
319```
320NodeList detach([string $selector = null])
321```
322
323##### Example
324
325``` php
326$doc = (new Document())->html('<ul class="first"><li>Item</li></ul><ul class="second"></ul>');
327$el = $doc->find('ul.first li')->detach();
328$doc->first('ul.second').append($el);
329```
330
331*Result:*
332
333``` html
334<ul class="first"></ul><ul class="second"><li>Item</li></ul>
335```
336
337---
338
339#### empty
340
341```
342self empty()
343```
344
345##### Example
346
347``` php
348$doc = (new Document())->html('<div>The quick brown fox jumps over the lazy dog</div>');
349$doc->find('div')->empty();
350```
351
352*Result:*
353
354``` html
355<div></div>
356```
357
358---
359
360#### hasClass
361
362```
363bool hasClass(string $class)
364```
365
366##### Example
367
368``` php
369$doc = (new Document())->html('<div class="text-center"></div>');
370echo $doc->first('div')->hasClass('text-center');
371```
372
373*Result:*
374
375``` html
376true
377```
378
379---
380
381#### html
382
383```
384string|self html([string|NodeList|\DOMNode|callable $input = null])
385```
386
387##### Example #1 (Set)
388
389``` php
390$doc = (new Document());
391$doc->html('<div class="example"></div>');
392```
393
394*Result:*
395
396``` html
397<div class="example"></div>
398```
399
400##### Example #1 (Get)
401
402``` php
403$doc = (new Document())->html('<div class="example"></div>');
404$doc->find('div')->appendWith('<span>Example!</span>');
405echo $doc->html();
406```
407
408*Result:*
409
410``` html
411<div class="example"><span>Example!</span></div>
412```
413
414---
415
416#### prependWith
417
418```
419self prependWith(string|NodeList|\DOMNode|callable $input)
420```
421
422##### Example
423
424``` php
425$doc = (new Document())->html('<div>The quick brown fox jumps over the lazy dog</div>');
426$doc->find('div')->prependWith('<strong>Prepended! </strong>');
427```
428
429*Result:*
430
431``` html
432<div><strong>Prepended! </strong>The quick brown fox jumps over the lazy dog</div>
433```
434
435---
436
437#### prependTo
438
439```
440self prependTo(string|NodeList|\DOMNode $selector)
441```
442
443##### Example
444
445``` php
446$doc = (new Document())->html('<div>The quick brown fox jumps over the lazy dog</div>');
447$doc->create('<strong>Prepended! </strong>')->appendTo('div');
448```
449
450*Result:*
451``` html
452<div><strong>Prepended! </strong>The quick brown fox jumps over the lazy dog</div>
453```
454
455---
456
457#### removeAttr
458
459```
460self removeAttr(string $name)
461```
462
463##### Example
464
465``` php
466$doc = (new Document())->html('<div class="first second"></div>');
467$doc->find('div').removeAttr('class');
468```
469
470*Result:*
471``` html
472<div></div>
473```
474
475---
476
477#### removeClass
478
479```
480self removeClass(string|callable $class)
481```
482
483##### Example
484
485``` php
486$doc = (new Document())->html('<div class="first second"></div>');
487$doc->find('div').removeClass('first');
488```
489
490*Result:*
491``` html
492<div class="second"></div>
493```
494
495---
496
497#### substituteWith
498
499```
500self substituteWith(string|NodeList|\DOMNode|callable $input)
501```
502
503##### Example
504
505``` php
506```
507
508---
509
510#### text
511
512```
513string|self text([string|NodeList|\DOMNode|callable $input = null])
514```
515
516##### Example
517
518``` php
519```
520
521---
522
523#### unwrap
524
525```
526self unwrap()
527```
528
529Unwrap each current node by removing its parent, replacing the parent
530with its children (i.e. the current node and its siblings).
531
532Note that each node is operated on separately, so when you call
533`unwrap()` on a `NodeList` containing two siblings, *two* parents will
534be removed.
535
536##### Example
537
538``` php
539$doc = (new Document())->html('<div id="outer"><div id="first"/><div id="second"/></div>');
540$doc->find('#first')->unwrap();
541```
542
543*Result:*
544
545``` html
546<div id="first"></div>
547<div id="second"></div>
548```
549
550---
551
552#### wrap
553
554```
555self wrap(string|NodeList|\DOMNode|callable $input)
556```
557
558Wrap the current node or nodes in the given structure.
559
560The wrapping structure can be nested, but should only contain one node
561on each level (any extra siblings are removed). The outermost node
562replaces the node operated on, while the node operated on is put into
563the innermost node.
564
565If called on a `NodeList`, each of nodes in the list will be separately
566wrapped. When such a list contains multiple nodes, the argument to
567wrap() cannot be a `NodeList` or `\DOMNode`, since those can be used
568to wrap a node only once. A string or callable returning a string or a
569unique `NodeList` or `\DomNode` every time can be used in this case.
570
571When a callable is passed, it is called once for each node operated on,
572passing that node and its index. The callable should return either a
573string, or a unique `NodeList` or `\DOMNode` ever time it is called.
574
575Note that this returns the original node like all other methods, not the
576(new) node(s) wrapped around it.
577
578##### Example
579
580``` php
581$doc = (new Document())->html('<span>foo<span><span>bar</span>');
582$doc->find->('span')->wrap('<div><p/></div>');
583```
584
585*Result:*
586
587``` html
588<div><p><span>foo</span></p></div>
589<div><p><span>bar</span></p></div>
590```
591
592
593---
594
595#### wrapAll
596
597```
598self wrapAll(string|NodeList|\DOMNode|callable $input)
599```
600
601Like [wrap()](#wrap), but when operating on multiple nodes, all of them
602will be wrapped together in a single instance of the given structure,
603rather than each of them individually.
604
605Note that the wrapping structure replaces the first node operated on, so
606if the other nodes operated on are not siblings of the first, they will
607be moved inside the document.
608
609##### Example
610
611``` php
612$doc = (new Document())->html('<span>foo<span><span>bar</span>');
613$doc->find->('span')->wrapAll('<div><p/></div>');
614```
615
616*Result:*
617
618``` html
619<div><p>
620 <span>foo</span>
621 <span>bar</span>
622</p></div>
623```
624
625---
626
627#### wrapInner
628
629```
630self wrapInner(string|NodeList|\DOMNode|callable $input)
631```
632
633Like [wrap()](#wrap), but rather than wrapping the nodes that are being
634operated on, this wraps their contents.
635
636##### Example
637
638``` php
639$doc = (new Document())->html('<span>foo<span><span>bar</span>');
640$doc->find('span')->wrapInner('<b><i/></b>');
641```
642
643*Result:*
644
645``` html
646<span><b><i>foo</i></b></span>
647<span><b><i>bar</i></b></span>
648```
649
650---
651
652
653### Traversal
654
655#### add
656
657```
658NodeList add(string|NodeList|\DOMNode $input)
659```
660
661Add additional node(s) to the existing set.
662
663##### Example
664
665``` php
666$nodes = $doc->find('a');
667$nodes->add($doc->find('p'));
668```
669
670---
671
672#### children
673
674```
675NodeList children()
676```
677
678Return all children of each element node in the current set.
679
680##### Example
681
682``` php
683$nodes = $doc->find('p');
684$childrenOfParagraphs = $nodes->children();
685```
686
687---
688
689#### closest
690
691```
692Element|NodeList|null closest(string|NodeList|\DOMNode|callable $input)
693```
694
695Return the first element matching the supplied input by traversing up through the ancestors of each node in the current set.
696
697##### Example
698
699``` php
700$nodes = $doc->find('a');
701$closestAncestors = $nodes->closest('p');
702```
703
704---
705
706#### contents
707
708```
709NodeList contents()
710```
711
712Return all children of each node in the current set.
713
714##### Example
715
716``` php
717$nodes = $doc->find('p');
718$contents = $nodes->contents();
719```
720
721---
722
723#### eq
724
725```
726\DOMNode|null eq(int $index)
727```
728
729Return node in the current set at the specified index.
730
731##### Example
732
733``` php
734$nodes = $doc->find('a');
735$nodeAtIndexOne = $nodes->eq(1);
736```
737
738---
739
740#### filter
741
742```
743NodeList filter(string|NodeList|\DOMNode|callable $input)
744```
745
746Return nodes in the current set that match the input.
747
748##### Example
749
750``` php
751$nodes = $doc->filter('a')
752$exampleATags = $nodes->filter('[href*=https://example.org/]');
753```
754
755---
756
757#### find
758
759```
760NodeList find(string $selector[, string $prefix = 'descendant::'])
761```
762
763Return the decendants of the current set filtered by the selector and optional XPath axes.
764
765##### Example
766
767``` php
768$nodes = $doc->find('a');
769```
770
771---
772
773#### first
774
775```
776mixed first()
777```
778
779Return the first node of the current set.
780
781##### Example
782
783``` php
784$nodes = $doc->find('a');
785$firstNode = $nodes->first();
786```
787
788---
789
790#### has
791
792```
793NodeList has(string|NodeList|\DOMNode|callable $input)
794```
795
796Return nodes with decendants of the current set matching the input.
797
798##### Example
799
800``` php
801$nodes = $doc->find('a');
802$anchorTags = $nodes->has('span');
803```
804
805---
806
807#### is
808
809```
810bool is(string|NodeList|\DOMNode|callable $input)
811```
812
813Test if nodes from the current set match the input.
814
815##### Example
816
817``` php
818$nodes = $doc->find('a');
819$isAnchor = $nodes->is('[anchor]');
820```
821
822---
823
824#### last
825
826```
827mixed last()
828```
829
830Return the last node of the current set.
831
832##### Example
833
834``` php
835$nodes = $doc->find('a');
836$lastNode = $nodes->last();
837```
838
839---
840
841#### map
842
843```
844NodeList map(callable $function)
845```
846
847Apply a callback to nodes in the current set and return a new NodeList.
848
849##### Example
850
851``` php
852$nodes = $doc->find('a');
853$nodeValues = $nodes->map(function($node) {
854 return $node->nodeValue;
855});
856```
857
858---
859
860#### following
861
862```
863\DOMNode|null following([string|NodeList|\DOMNode|callable $selector = null])
864```
865
866Return the sibling immediately following each element node in the current set.
867
868*Optionally filtered by selector.*
869
870##### Example
871
872``` php
873$nodes = $doc->find('a');
874$follwingNodes = $nodes->following();
875```
876
877---
878
879#### followingAll
880
881```
882NodeList followingAll([string|NodeList|\DOMNode|callable $selector = null])
883```
884
885Return all siblings following each element node in the current set.
886
887*Optionally filtered by selector.*
888
889##### Example
890
891``` php
892$nodes = $doc->find('a');
893$follwingAllNodes = $nodes->followingAll('[anchor]');
894```
895
896---
897
898#### followingUntil
899
900```
901NodeList followingUntil([[string|NodeList|\DOMNode|callable $input = null], string|NodeList|\DOMNode|callable $selector = null])
902```
903
904Return all siblings following each element node in the current set upto but not including the node matched by $input.
905
906*Optionally filtered by input.*<br>
907*Optionally filtered by selector.*
908
909##### Example
910
911``` php
912$nodes = $doc->find('a');
913$follwingUntilNodes = $nodes->followingUntil('.submit');
914```
915
916---
917
918#### not
919
920```
921NodeList not(string|NodeList|\DOMNode|callable $input)
922```
923
924Return element nodes from the current set not matching the input.
925
926##### Example
927
928``` php
929$nodes = $doc->find('a');
930$missingHrefAttribute = $nodes->not('[href]');
931```
932
933---
934
935#### parent
936
937```
938Element|NodeList|null parent([string|NodeList|\DOMNode|callable $selector = null])
939```
940
941Return the immediate parent of each element node in the current set.
942
943*Optionally filtered by selector.*
944
945##### Example
946
947``` php
948$nodes = $doc->find('a');
949$parentNodes = $nodes->parent();
950```
951
952---
953
954#### parents
955
956```
957NodeList parent([string $selector = null])
958```
959
960Return the ancestors of each element node in the current set.
961
962*Optionally filtered by selector.*
963
964##### Example
965
966``` php
967$nodes = $doc->find('a');
968$ancestorDivNodes = $nodes->parents('div');
969```
970
971---
972
973#### parentsUntil
974
975```
976NodeList parentsUntil([[string|NodeList|\DOMNode|callable $input, [string|NodeList|\DOMNode|callable $selector = null])
977```
978
979Return the ancestors of each element node in the current set upto but not including the node matched by $selector.
980
981*Optionally filtered by input.*<br>
982*Optionally filtered by selector.*
983
984##### Example
985
986``` php
987$nodes = $doc->find('a');
988$ancestorDivNodes = $nodes->parentsUntil('div');
989```
990
991---
992
993#### preceding
994
995```
996\DOMNode|null preceding([string|NodeList|\DOMNode|callable $selector = null])
997```
998
999Return the sibling immediately preceding each element node in the current set.
1000
1001*Optionally filtered by selector.*
1002
1003##### Example
1004
1005``` php
1006$nodes = $doc->find('a');
1007$precedingNodes = $nodes->preceding();
1008```
1009
1010---
1011
1012#### precedingAll
1013
1014```
1015NodeList precedingAll([string|NodeList|\DOMNode|callable $selector = null])
1016```
1017
1018Return all siblings preceding each element node in the current set.
1019
1020*Optionally filtered by selector.*
1021
1022##### Example
1023
1024``` php
1025$nodes = $doc->find('a');
1026$precedingAllNodes = $nodes->precedingAll('[anchor]');
1027```
1028
1029---
1030#### precedingUntil
1031
1032```
1033NodeList precedingUntil([[string|NodeList|\DOMNode|callable $input = null], string|NodeList|\DOMNode|callable $selector = null])
1034```
1035
1036Return all siblings preceding each element node in the current set upto but not including the node matched by $input.
1037
1038*Optionally filtered by input.*<br>
1039*Optionally filtered by selector.*
1040
1041##### Example
1042
1043``` php
1044$nodes = $doc->find('a');
1045$precedingUntilNodes = $nodes->precedingUntil('.submit');
1046```
1047
1048---
1049
1050#### siblings
1051
1052```
1053NodeList siblings([[string|NodeList|\DOMNode|callable $selector = null])
1054```
1055
1056Return siblings of each element node in the current set.
1057
1058*Optionally filtered by selector.*
1059
1060##### Example
1061
1062``` php
1063$nodes = $doc->find('p');
1064$siblings = $nodes->siblings();
1065```
1066
1067---
1068
1069#### slice
1070
1071```
1072NodeList slice(int $start[, int $end])
1073```
1074
1075Return a subset of the current set based on the start and end indexes.
1076
1077##### Example
1078
1079``` php
1080$nodes = $doc->find('p');
1081// Return nodes 1 through to 3 as a new NodeList
1082$slicedNodes = $nodes->slice(1, 3);
1083```
1084
1085---
1086
1087### Additional Methods
1088
1089#### count
1090
1091```
1092int count()
1093```
1094
1095##### Example
1096
1097``` php
1098$nodes = $doc->find('p');
1099
1100echo $nodes->count();
1101```
1102
1103---
1104
1105#### each
1106
1107```
1108self each(callable $function)
1109```
1110
1111##### Example
1112
1113``` php
1114$nodes = $doc->find('p');
1115
1116$nodes->each(function($node){
1117 echo $node->nodeName . "\n";
1118});
1119```
1120
1121## Licensing
1122
1123PHP DOM Wrapper is licensed by Andrew Scott under the BSD 3-Clause License, see the LICENSE file for more details.
1124