はじめに
PHPは標準でDOMが使えますが、とても使いにくく、あまり使われていません。
機能が不足していたり、冗長な書き回しになったり、とにかく不便です。
そこで、PHPのDOMを使いやすくするために、自作のプログラムを作りました。
Web標準であるDOMに慣れ親しんだ人なら、簡単に使えるものを目標としています。
技術的には、PHPの DOMDocument と DOMElement を拡張したものになっています。
HTMLの入力
最初にベースとなるHTML文字列を渡して document オブジェクトを作成します。
$document = new document('<!DOCTYPE html><html lang="ja"><head><meta charset="utf-8"><title></title></head><body></body></html>');
- 引数省略時は内蔵テンプレートが使用されます。上記サンプルと同じHTMLです
- HTMLは、全体を1つのタグで囲っておく必要があります
HTMLの出力
documentオブジェクトは自動的に文字列に変換されるので、出力するだけでHTMLを表示できます。
$document = new document();
print $document; // HTMLを表示する
file_put_contents('example.html', $document); // HTMLをファイルに保存する
$html = "$document"; // 文字列としてコピーする
DOM要素も同様に、自動的に文字列に変換されます
print $document->body; // <body></body> が表示される
主要タグの短縮形
主要タグの<html>
<head>
<title>
<body>
には短縮形があり、$document->タグ名
でアクセスできます。
$document->body // $document->getElementsByTagName('body')[0] の短縮形
$document->title->textContent = 'タイトル名'; //titleはweb標準と異なるので注意
この値はDOM要素です。
id付タグの短縮形
idが付いているタグには$document->id名
でアクセスできます。
$document->exapmle // $document->getElementById('example') の短縮形
この値はDOM要素です。存在しなければnull
操作したいタグにはあらかじめidを付けておくと、綺麗なコードが書けます。
属性アクセスの短縮形
属性へのアクセスは短縮形があり、$el->属性名
と書けます。
$body = $document->body;
$body->id // $body->getAttribute('id') の短縮形
$body->id = 'value' // $body->setAttribute('id', 'value') の短縮形
unset($body->id) // $body->removeAttribute('id') の短縮形
isset($body->id) // $body->hasAttribute('id') の短縮形
タグの検索
セレクタで検索
documentオブジェクトには、JavaScriptでお馴染みのquerySelector
があります。
CSSセレクタを使用して、ドキュメント全体からタグを検索できます。
//単数検索
$document->querySelector('CSSセレクタ') //戻り値はDOM要素またはnull
//複数検索
$document->querySelectorAll('CSSセレクタ') //戻り値は常に配列
対応セレクタ
検索対象 | セレクタ |
---|---|
タグ名 | a |
id | #a |
class | .a |
属性名 | [a] |
属性名と値 | [a="b"] |
and | ab |
子孫 | a b |
子 | a > b |
弟 | a + b |
弟全て | a ~ b |
全て | * |
querySelector()の短縮形
querySelector()
には短縮形が用意されていて、jQuery風に書けます。$document('セレクタ')
$document('.example') // $document->querySelector('.example') の短縮形
デフォルト動作は単数検索です。複数検索するには、セレクタの頭に*
を付けます。
$document('*.example') // $document->querySelectorAll('.example') の短縮形
タグの作成
タグを1つ作成する短縮形
タグの作成には短縮形があり$document(<タグ名>, 本文, [属性名=>属性値])
で1つタグが作成できます。
戻り値はDOM要素で、本文と属性は省略できます。
// <div class="example">sample</div> を作る
$document('<div>', 'sample', ['class'=>'example']);
// 次のコードの短縮形
// $div = $document->createElement('div');
// $div->textContent = 'sample';
// $div->setAttribute('class', 'example');
子タグも一括作成
<ul>
<ol>
<select>
<table>
のタグは、本文を配列で渡すと、子タグも一括して作成できます。
$document('<ul>', [1,2], ['id'=>'example']);
//<ul id="example">
// <li>1</li>
// <li>2</li>
//</ul>
$document('<select>', [1,2]);
//<select>
// <option value="1">1</option>
// <option value="2">2</option>
//</select>
$document('<table>', [1,2]);
//<table>
// <tr><td>1</td></tr>
// <tr><td>2</td></tr>
//</table>
$document('<table>', [[1,2], [3,4]]);
//<table>
// <tr><td>1</td><td>2</td></tr>
// <tr><td>3</td><td>4</td></tr>
//</table>
HTML文字列をDOM化
HTML文字列を一括してDOM化するには$document('HTML文字列')
で可能です。
コンポーネントの読み込みに適しています。
$component = $document('<nav><a id="nav_link">Home</a></nav>'); // コンポーネントの読み込み
$component->nav_link->href = 'http://example.jp/'; // id短縮形が使える。querySelectorもある
$document->body->appendChild($component); // <body>の最後に<nav>を挿入する
他の方法として$el->innerHTML
でHTML文字列を代入することもできます。
[付録] DOM操作の早見表
DOMの代表的な操作をまとめてみました。
DOMに不慣れな人でも次の早見表を使えば大丈夫👍
//タグを検索する
$document->querySelector('セレクタ'); // 戻り値はDOM要素またはnull
$document->querySelectorAll('セレクタ'); // 戻り値は配列
//タグを作成する
$el = $document->createElement('タグ名');// 戻り値はDOM要素
//中身を取得する
$el->textContent; //戻り値はタグを含まない文字列
//中身を取得する
$el->innerHTML; //戻り値はタグを含む文字列
//中身を変更する
$el->textContent = '文字列はエスケープされる';
//中身を変更する
$el->innerHTML = '文字列はエスケープされない';
//中身を全て削除する
$el->textContent = '';
//タグ名を取得する
$el->tagName; //戻り値は小文字
//属性を取得する
$el->getAttribute('属性名'); //戻り値は文字列
//属性を設定する
$el->setAttribute('属性名', '属性値');
//属性を削除する
$el->removeAttribute('属性名');
//※タグを子の最後に追加する
$el->append($new_el);
//※タグを子の最初に追加する
$el->prepend($new_el);
//※タグを前に追加する
$el->before($new_el);
//※タグを後ろに追加する
$el->after($new_el);
//※タグを置換する
$el->replaceWith($new_el);
//※タグを削除する
$el->remove();
//タグをコピーする
$el->cloneNode(true); //戻り値はDOM要素
//タグの子孫からタグを検索する
$el->querySelector('セレクタ'); //戻り値はDOM要素またはnull
$el->querySelectorAll('セレクタ'); //戻り値は配列
上記のコードで※マークが付いているものはPHP8.0~向けの書き方です。
PHP7以下では次のように書きます。
//タグを子の最後に追加する
$el->appendChild($new_el);
//タグを子の最初に追加する
$el->insertBefore($new_el, $el->firstChild);
//タグを前に追加する
$el->parentNode->insertBefore($new_el, $el);
//タグを後ろに追加する
$el->parentNode->insertBefore($new_el, $el->nextSibling);
//タグを置換する
$el->parentNode->replaceChild($new_el, $el);
//タグを削除する
$el->parentNode->removeChild($el);
ソースコード
PHPファイルをinclude
するだけで使えます。ご自由にお使いください。