【PHP8.x】createFromStringメソッドの使い方

createFromStringメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

createFromStringメソッドは、Dom\XMLDocumentクラスのメソッドであり、文字列から新しいDom\DocumentFragmentノードを作成します。このメソッドは、XML形式の文字列を解析し、その内容をDom\DocumentFragmentとしてDom\XMLDocumentにインポートします。

具体的には、引数としてXML形式の文字列を受け取り、その文字列を解析してXMLドキュメントのフラグメントを生成します。生成されたフラグメントは、Dom\XMLDocumentオブジェクトのドキュメントフラグメントとして扱えるようになります。

このメソッドは、XMLドキュメントの一部を動的に生成したり、外部ソースから取得したXMLデータを既存のXMLドキュメントに組み込んだりする場合に非常に役立ちます。例えば、データベースから取得したXMLデータをWebページに表示する際に、このメソッドを使用してDom\DocumentFragmentを作成し、それをDom\XMLDocumentに追加することで、簡単にXMLデータを操作できます。

createFromStringメソッドを使用する際には、引数として渡すXML文字列が正しい形式である必要があります。不正な形式のXML文字列を渡すと、解析エラーが発生し、メソッドの実行が失敗する可能性があります。また、文字コードの問題も考慮する必要があります。XML文字列の文字コードとDom\XMLDocumentオブジェクトの文字コードが異なる場合、文字化けが発生する可能性があります。必要に応じて、文字コード変換を行うなどの対策を講じる必要があります。

このメソッドは、XML文書を効率的に操作するための強力なツールであり、システム開発においてXMLデータを扱う際に非常に重要な役割を果たします。適切に使用することで、XMLデータの処理を簡素化し、開発効率を向上させることができます。

構文(syntax)

1<?php
2$xmlContent = ''; // XML文字列
3$document = Dom\XMLDocument::createFromString($xmlContent);
4?>

引数(parameters)

string $source, int $options = 0, ?string $overrideEncoding = null

  • string $source: XMLまたはHTMLのソースコードを表す文字列
  • int $options = 0: DOMDocument::loadXML() または DOMDocument::loadHTML() に渡されるオプション。デフォルトは0
  • ?string $overrideEncoding = null: ソースコードのエンコーディングを上書きするための文字列。指定しない場合は自動検出される

戻り値(return)

Dom\XMLDocument

Dom\XMLDocument クラスの createFromString メソッドは、XML 文字列を解析して Dom\XMLDocument オブジェクトを生成し、それを返します。このオブジェクトは、XML ドキュメントの構造を操作するために使用できます。

サンプルコード

PHP Dom\XMLDocument::createFromString でHTML/XMLをパースする

1<?php
2
3/**
4 * HTML/XML文字列を Dom\XMLDocument オブジェクトとしてパースするサンプル関数。
5 *
6 * Dom\XMLDocument::createFromString メソッドは、指定された文字列をXMLドキュメントとして解析します。
7 * このメソッドはPHP 8.3以降で導入された新しいDom拡張のクラスです。
8 * HTML文字列を渡す場合、XMLとして整形式である必要があります。
9 *
10 * @param string $source パース対象のHTML/XML文字列。
11 * @return void
12 */
13function parseHtmlOrXmlString(string $source): void
14{
15    // PHPのデフォルトのエラーハンドラがDOMエラーを例外としてスローするように設定
16    // これにより、パースエラーが発生した場合にtry-catchで捕捉できます。
17    // Dom\XMLDocument::createFromString は内部的にエラーが発生した場合に Dom\DomException をスローすることがあります。
18    libxml_use_internal_errors(true);
19
20    try {
21        // Dom\XMLDocument::createFromString は静的ファクトリメソッドです。
22        // 指定された文字列から新しい Dom\XMLDocument インスタンスを作成します。
23        // 第2引数 $options は、LIBXML_PARSE_MNSなど、LibXMLのパースオプションを指定できますが、
24        // 0 (デフォルト) でほとんどの場合問題ありません。
25        $document = Dom\XMLDocument::createFromString($source);
26
27        echo "--- ドキュメントのパース結果 ---\n";
28
29        // パースが成功した場合
30        echo "ドキュメントが正常にパースされました。\n";
31
32        // ドキュメントのルート要素が存在するか確認し、その情報を表示
33        $documentElement = $document->documentElement;
34        if ($documentElement) {
35            echo "ルート要素名: " . $documentElement->nodeName . "\n";
36            echo "ルート要素のテキストコンテンツの最初の50文字: " . substr($documentElement->textContent, 0, 50) . "...\n";
37        } else {
38            echo "ドキュメントにルート要素が見つかりません。\n";
39        }
40
41        // XPathを使用して特定の要素を検索する例
42        // Dom\XPath クラスも新しいDom拡張の一部です。
43        $xpath = new Dom\XPath($document);
44        $paragraphs = $xpath->query('//p'); // ドキュメント内のすべての <p> 要素を検索
45
46        if ($paragraphs->count() > 0) {
47            echo "\n--- 見つかった <p> 要素 ---\n";
48            foreach ($paragraphs as $index => $paragraph) {
49                echo ($index + 1) . "番目の <p> の内容: " . $paragraph->textContent . "\n";
50            }
51        } else {
52            echo "\n<p> 要素は見つかりませんでした。\n";
53        }
54
55    } catch (Dom\DomException $e) {
56        // Dom拡張によってスローされた例外(パースエラーなど)を捕捉
57        echo "DOM操作中にエラーが発生しました: " . $e->getMessage() . "\n";
58        foreach (libxml_get_errors() as $error) {
59            echo "  LibXMLエラー: " . $error->message;
60        }
61        libxml_clear_errors(); // エラーをクリア
62    } catch (Throwable $e) {
63        // その他の一般的な例外を捕捉
64        echo "予期せぬエラーが発生しました: " . $e->getMessage() . "\n";
65    } finally {
66        libxml_use_internal_errors(false); // エラーハンドラを元に戻す
67    }
68    echo "\n";
69}
70
71// サンプルとして、シンプルでXMLとして整形式なHTML文字列を用意します。
72// Dom\XMLDocument はHTMLをXMLとして扱おうとするため、閉じタグの省略などはエラーとなる可能性があります。
73$htmlSource = <<<HTML
74<!DOCTYPE html>
75<html>
76<head>
77    <title>サンプルタイトル</title>
78</head>
79<body>
80    <h1>Dom\\XMLDocument::createFromString の使用例</h1>
81    <p>この段落は、PHP 8 の新しい Dom 拡張を使ってパースされます。</p>
82    <p>これは2番目の段落です。</p>
83    <div class="footer">
84        <p>Copyright &copy; 2023</p>
85    </div>
86</body>
87</html>
88HTML;
89
90// 正常なHTML/XML文字列のパースを試行
91echo "=== 正常なHTML文字列のパース ===\n";
92parseHtmlOrXmlString($htmlSource);
93
94// XMLとして不正な文字列の例(意図的に閉じタグを省略)
95$invalidXmlSource = <<<XML
96<root>
97    <item>最初のアイテム
98    <item>2番目のアイテム</item>
99</root>
100XML;
101
102// 不正なXML文字列のパースを試行
103echo "=== 不正なXML文字列のパース ===\n";
104parseHtmlOrXmlString($invalidXmlSource);

Dom\XMLDocument::createFromStringは、PHP 8.3以降で導入された新しいDOM拡張の一部として提供されるメソッドです。このメソッドは、HTMLやXML形式の文字列を解析し、プログラムで操作できるDom\XMLDocumentオブジェクトに変換する役割を持ちます。ウェブページの内容や設定ファイルなど、文字列として扱われる構造化されたデータをPHPプログラムで読み込み、その内容を解析したり加工したりする際に非常に便利です。

引数として、まずパース対象となるHTMLまたはXMLの文字列を$sourceに指定します。次に、LibXMLのパースオプションを整数値で指定する$optionsがありますが、通常はデフォルト値の0で問題なく動作します。必要に応じて、エンコーディングを上書きするための$overrideEncodingも指定できます。メソッドが成功すると、解析されたXMLドキュメントを表すDom\XMLDocumentのインスタンスが戻り値として返されます。

サンプルコードでは、libxml_use_internal_errors(true)でDOMパース中のエラーを例外として捕捉できるように設定し、try-catchブロック内でDom\XMLDocument::createFromStringを呼び出して文字列を解析しています。正常にパースされた場合、生成されたドキュメントオブジェクトからルート要素の名前を取得したり、XPathを使って特定の<p>要素を検索してその内容を表示したりと、オブジェクトを通じてドキュメントの内容にアクセスできることを示しています。

もしXMLとして不正な文字列(例えば、閉じタグが不足しているHTMLなど)を渡すと、Dom\DomExceptionがスローされ、catchブロックでエラーメッセージとLibXMLの詳細なエラー情報が表示されます。これは、HTML文字列を解析する場合でも、XMLとして整形式である必要があるという重要な点を示しています。最後に、エラーハンドリング設定を元に戻すことで、プログラムの他の部分に影響が出ないように配慮されています。この一連の処理を理解することで、文字列から構造化されたデータを安全に抽出し、利用する基本的な方法を学ぶことができます。

このメソッドはPHP 8.3以降の新しいDom拡張機能です。HTML文字列を扱う場合でも、入力がXMLとして整形式である必要があるため注意が必要です。HTML5のような閉じタグの省略はパースエラーの原因となります。インスタンスはDom\XMLDocument::createFromString()のように、クラス名から直接呼び出して作成する静的ファクトリメソッドです。パースエラーに備え、libxml_use_internal_errors(true)でDOMエラーを例外として扱い、try-catchブロックでDom\DomExceptionを適切に処理することが重要です。エラー処理後にはlibxml_clear_errors()でエラーをクリアし、finallyブロックでlibxml_use_internal_errors(false)によりエラーハンドラ設定を元に戻す配慮が安全なコード利用につながります。