simplexml_load_stringの中身はstringじゃなくてobject

製作 プログラム

最終更新日:2021/03/16

ラムネグから一言:寝る前に読むとくだらなすぎて逆に寝れると好評なすごい適当なブログをこっちではじめてます.

simplexml_load_string()っていうPHPの関数、これを使うとよそのサイトのRSSフィードなんかをPHPで読み取ったりできます。

ただsimplexml_load_string()で取得できるXMLの一群(DOMみたいなやつたち)は取り扱いに注意が必要!というのを書きたい。

  1. そのままDBに保存できなかった
  2. 原因はSimpleXMLElement
  3. 解決方法
  4. まとめ

そのままDBに保存できなかった

今回simplexml_load_string()でRSSフィードを取得、RSSフィードの中から必要な情報だけ抜き出してそれをデータベースにシリアライズして保存、というのをしていました。最後のDB保存のトコロはワードプレスの関数に任せて保存にしていましたが、やってることは同じはずです。

すると何度やってもこのデータベースに保存のところでつまづく。

具体的にはワードプレスが落ちる。

そう、エラーを吐くとかじゃなくてそのワードプレスサイトが完全に落ちるという致命的な状態に。

原因はSimpleXMLElement

もしかしてワードプレスがシリアライズしてくれてないのかな?とかいろいろ試しましたが、原因はsimplexml_load_string()が作るSimpleXMLElementでした。

完全に不勉強だったし、もっと早めにダンプしておけばよかったんですが、とりあえず下をみてください。

一般的な配列

array(3) {
  [0]=>
  array(2) {
    ["name"]=>
    string(6) "次郎"
    ["miyoji"]=>
    string(6) "田中"
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(6) "太郎"
    ["miyoji"]=>
    string(6) "木村"
  }
  [2]=>
  array(2) {
    ["name"]=>
    string(6) "三郎"
    ["miyoji"]=>
    string(6) "鈴木"
  }
}

simplexml_load_stringから代入した配列

array(3) {
  [0]=>
  array(2) {
    ["name"]=>
    object(SimpleXMLElement)#5027 (1) {
      [0]=>
      string(6) "次郎"
    }
    ["miyoji"]=>
    object(SimpleXMLElement)#5091 (1) {
      [0]=>
      string(6) "田中"
    }
  }
  [1]=>
  array(2) {
    ["name"]=>
    object(SimpleXMLElement)#5025 (1) {
      [0]=>
      string(6) "太郎"
    }
    ["miyoji"]=>
    object(SimpleXMLElement)#5093 (1) {
      [0]=>
      string(6) "木村"
    }
  }
  [2]=>
  array(2) {
    ["name"]=>
    object(SimpleXMLElement)#5092 (1) {
      [0]=>
      string(6) "三郎"
    }
    ["miyoji"]=>
    object(SimpleXMLElement)#5095 (1) {
      [0]=>
      string(6) "鈴木"
    }
  }
}

という風に直にStringが入るんじゃなくて、SimpleXMLElementていうobjectにラップされてるのが分かります。

このSimpleXMLElementていうのが勝手に入ってくるのが今回のつまづきポイントでした。

勝手に入ってくるっていうのは例えばこんな風に代入してるとSimpleXMLElementがぬるっと入ってきます。

すごい普通の代入だけど…

$name = $item->name;

解決方法

別にSimpleXMLElementも一緒に代入されたとしても出力する分には問題ない…と思います。

ただデータベースに保存しようとすると今回みたいにワードプレスが落ちたりとけっこう深刻な動きになるので、対策しておきましょう。

たぶん一番楽なのがsimplexml_load_string()した後、すぐにjson_encode()してXMLじゃなくしちゃうやり方。

$xml = simplexml_load_string("https://○○/feed");
$json = json_encode($xml);

あとはSimpleXMLElementをString型にキャストしてやる方法もOK。今回こっちでやりました。

代入するときにキャストしちゃう

$name = (string)$item->name;

まとめ

simplexml_load_string()を使ってPHPでRSSフィードなんかを素得するときの罠ポイントを紹介しました。

まとめると、simplexml_load_string()を使って作られるXML群(と呼ぶのかは知らないけど…)はStringがぜんぶSimpleXMLElementていうのにラップされてる。そして普通に代入してるとこのSimpleXMLElementまで含めてしまうから、データベースに保存するときとかに謎の挙動をすることがある。

という事っぽいです。…アルファベット多すぎて読みづらいですね。

とりあえずjson_encode()ですぐにXMLからおさらばさせるか、代入するときにstring型にキャストしちゃえばOK。試してみてください。

【おしらせ、というか完全なる宣伝】

文体がもうぜんぜん適当すぎてあれだけどものすごい自由に書いてるブログ「檸檬だくだく」もよろしく.寝る前に読める恐ろしくくだらないやつです.

こんなにも一ミリも目を引かれないタイトルを取り扱ってます: ココア20g / ハイチュウとかってさ / なぜ米と小麦を食べようと思ったのかの謎 /