edwinhuish/domquery

DomQuery 是一个 PHP 库,它允许您轻松地进行类似 jQuery 的 DOM 遍历和操作

v1.1.3 2020-10-15 09:15 UTC

README

英文 | 中文说明

DomQuery 是一个 PHP 库,允许您轻松遍历和修改 DOM (HTML/XML)。作为一个库,它旨在提供类似于 jQuery 的访问方式来操作 PHP DOMDocument 类

安装

使用以下命令安装最新版本

$ composer require edwinhuish/domquery

基本用法

读取属性和属性

$dom = new DomQuery('<div><h1 class="title">Hello</h1></div>');

echo $dom->find('h1')->text(); // output: Hello
echo $dom->find('div')->prop('outerHTML'); // output: <div><h1 class="title">Hello</h1></div>
echo $dom->find('div')->html(); // output: <h1 class="title">Hello</h1>
echo $dom->find('div > h1')->class; // output: title
echo $dom->find('div > h1')->attr('class'); // output: title
echo $dom->find('div > h1')->prop('tagName'); // output: h1
echo $dom->find('div')->children('h1')->prop('tagName'); // output: h1
echo (string) $dom->find('div > h1'); // output: <h1 class="title">Hello</h1>
echo count($dom->find('div, h1')); // output: 2

遍历节点(结果集)

$dom = new DomQuery('<a>1</a> <a>2</a> <a>3</a>');
$links = $dom->children('a');

// foreach
$texts = [];
foreach($links as $key => $dq) { // $dq is DomQuery object
    $texts[] = $dq->text();
}
print_r($texts); // array('1','2','3')

// map 
$result = $links->map(function(DomQuery $dq, int $idx){
    return $dq->text();
});
// map method return Collection object
print_r($result->toArray()); // array('1','2','3')

// each, same as Collection's each method, break traversing if return false.
$links->each(function(DomQuery $dq, int $idx){
    if($idx === 1){
        return false;
    }
    $dq->text('changed');
});
print_r($links->texts()); // array('changed', '2', '3')

echo $links->text(); // output 1, return text of first child, if you need the result of all childs please use texts() or foreach, each, map method
echo $links[0]->text(); // output 1
echo $links->last()->text(); // output 3
echo $links->first()->next()->text(); // output 2
echo $links->last()->prev()->text(); // output 2
echo $links->get(0)->textContent; // output 1
echo $links->get(-1)->textContent; // output 3

工厂方法(创建实例的替代方法)

DomQuery::create('<a title="hello"></a>')->attr('title') // hello

可用的 jQuery 方法

遍历 > 树遍历

  • .find(选择器)
  • .children([选择器])
  • .parent([选择器])
  • .closest([选择器])
  • .next([选择器])
  • .prev([选择器])
  • .nextAll([选择器])
  • .prevAll([选择器])
  • .siblings([选择器])

遍历 > 其他遍历

  • .contents() 获取包括文本节点的子节点
  • .add(选择器, [上下文]) 新结果集,包含匹配选择器的元素

遍历 > 过滤

  • .is(选择器)
  • .filter (选择器) 减少到匹配选择器的元素
  • .not(选择器) 从匹配的元素集中删除元素
  • .has(选择器) 减少到包含匹配选择器的后代的元素
  • .first([选择器])
  • .last([选择器])
  • .slice([偏移量] [, 长度]) 类似于 php 中的 array_slice,而不是 js/jquery
  • .eq(索引)
  • .map(可调用elm,i)

* [选择器] 可以是 CSS 选择器或 DomQuery|DOMNodeList|DOMNode 的实例

操作 > DOM 插入和删除

  • .text([文本])
  • .html([html_string])
  • .append([内容],...)
  • .prepend([内容],...)
  • .after([内容],...)
  • .before([内容],...)
  • .appendTo([目标])
  • .prependTo([目标])
  • .replaceWith([内容])
  • .wrap([内容])
  • .wrapAll([内容])
  • .wrapInner([内容])
  • .remove([选择器])
  • .unwrap()
  • .first()
  • .last()
  • .gt(整型 $索引)
  • .lt(整型 $索引)

* [内容] 可以是 html 或 DomQuery|DOMNodeList|DOMNode 的实例

属性 | 操作

  • .attr(名称[,值])
  • .prop(名称[,值])
  • .css(名称[,值])
  • .removeAttr(名称)
  • .addClass(名称)
  • .hasClass(名称)
  • .toggleClass (名称)
  • .removeClass([名称])

* addClass, removeClass, toggleClass 和 removeAttr 也可以接受数组或空格分隔的 名称

杂项 > DOM 元素方法 | 遍历 | 存储

  • .get(索引)
  • .each (可调用elm,i)
  • .data (键[,值])
  • .removeData ([名称])
  • .index ([选择器])
  • .toArray()
  • .clone()

支持的选择器

  • .class
  • #foo
  • 父 > 子
  • foo, bar 多个选择器
  • prev + next 匹配 "next" 的元素,紧接在兄弟元素 "prev" 之后
  • prev ~ siblings 匹配 "siblings" 的元素,在 "prev" 之后
  • * 所有选择器
  • [name="foo"] 属性值等于 foo
  • [name*="foo"] 属性值包含 foo
  • [name~="foo"] 属性值包含单词 foo
  • [name^="foo"] 属性值以 foo 开头
  • [name$="foo"] 属性值以 foo 结尾
  • [name|="foo"] 属性值等于 foo,或以 foo 开头后跟一个连字符 (-)

伪选择器

  • :empty
  • :even
  • :odd
  • :first-child
  • :last-child
  • :only-child
  • :parent 元素至少有一个子节点
  • :first
  • :last
  • :header 选择 h1, h2, h3 等
  • :not(foo) 不匹配选择器 foo 的元素
  • :has(foo) 包含至少一个匹配选择器 foo 的元素的元素
  • :contains(foo) 包含文本 foo 的元素
  • :root 文档的根元素
  • :nth-child(n)
  • :nth-child(even)
  • :nth-child(odd)
  • :nth-child(3n+8)
  • :nth-child(2n+1)
  • :nth-child(n+4) 相同于 :gt(2)
  • :nth-child(-n+4) 相同于 :lt(4)
  • :nth-child(3)
  • :nth-child(-2)
  • :nth-child(4n)
  • :eq(0)
  • :eq(-1)
  • :lt(3)
  • :gt(2)

其他(非 jQuery)方法

  • findOrFail( selector ) 在当前匹配元素集中查找每个元素的子元素,或抛出异常
  • loadContent(content, encoding='UTF-8') 加载 html/xml 内容
  • xpath(xpath_query) 使用 xpath 在当前匹配元素集中查找子元素
  • getOuterHtml() 获取描述所有元素的最终 html(等同于 (string) $dom,或 $elm->prop('outerHTML')
  • getRoot() 获取根节点

XML 支持

  • 如果找到 XML 声明(属性 xml_mode 将设置为 true),XML 内容将自动被加载为 'XML'
  • 这也会使保存(渲染)发生 '作为 XML'。您可以设置属性 xml_mode 为 false 以阻止此行为。
  • 要防止具有 XML 声明的包含内容以 'XML' 加载,您可以将属性 xml_mode 设置为 false,然后使用 loadContent($content) 方法。
  • 命名空间将自动注册(无需手动进行)

在选择器中转义元字符以查找具有命名空间的元素

$dom->find('namespace\\:h1')->text();

关于

需求

  • 与 PHP 7.0 或更高版本兼容
  • 需要 libxml PHP 扩展(默认启用)

分支自