プロが教える店舗&オフィスのセキュリティ対策術

SimpleXMLにて特定のノードを検索し、検索結果を削除しようとしています。

まず、下記ソースコードの「削除1」を行っていたのですが、
$xmlから検索結果が削除されず「削除2」に修正したところ正常に削除されるようになりました。

「削除1」と「削除2」は検索結果をforeachで直接使用しているか、
一度変数にセットして利用するかの違いなのですが、
なぜ変数に検索結果をセットするとunsetで削除されなくなるのかわかりません。

PHP初心者でして、初歩的な質問かと思いますが、どなたか教えていただけないでしょうか?
宜しくお願い致します。

--------------------------------------------
$xml = new SimpleXMLElement($filepath, null, true);

// 削除1
$items = $xml->xpath($name . '[' . $column . '="' . $value . '"]');
foreach( $items as $item ) {
unset($item);
$ret ++;
}

// 削除2
foreach( $xml->xpath($name . '[' . $column . '="' . $value . '"]') as $item ) {
unset($item[0]);
$ret ++;
}

file_put_contents($filepath, $xml->asXML());

A 回答 (2件)

削除1は、



$items = $xml->xpath($name . '[' . $column . '="' . $value . '"]');
foreach( $items as $item ) {
unset($item); //ここがunset($item[0]);になるのではないでしょうか。
$ret ++;
}

これで多分同じ動作になると思いますがいかがでしょう。

尚、
foreachで$itemに参照コピーされたオブジェクトを、unsetしても、参照から外れるだけなので、
値そのものは消えません。
$itemにコピーされて、その$itemにある「0」という要素をunsetすると、$itemの参照元からは「0」という要素が消えます。

<?php

//適当なクラスがあったとして
class Example{
public $value = "";
}

//変数$dataでインスタンスを作成
$data = new Example();

//ソレを変数$data2にコピー
$data2 = $data;

//コピーされた$data2でクラスのメンバ変数に値を代入
$data2->value = "test";

echo $data->value .PHP_EOL; //出力は、「test」
echo $data2->value .PHP_EOL; //出力は「test」

//変数$data2をunsetした!
unset($data2);

//でも$data2が参照しなくなっただけで
//もとは生きているので
echo $data->value; //出力は「test」

?>
    • good
    • 0
この回答へのお礼

ありがとうございます。
おっしゃるとおり$item[0]で削除できました。
よくよく見ると「削除2」も同じ事をやっていました(^^;)
ありがとうございます。

ただ、なぜ参照コピーされた$itemを$item[0]と
指定すると参照元を指定できるのが不明です。

ちなみにデバックして$item[100]などを指定しても
エラーとはならず、$itemと同じ物を参照しているようです。

$itemは配列ではないと、私は思っているので
$item[0]や$item[100]など使用するとエラーに
なると思っていたのですがなぜこのようになるのでしょうか?

たびたび質問で申し訳ありません。
宜しくお願い致します。

お礼日時:2010/12/23 22:25

PHPには、インターフェイスという物があって、自前のクラスなどにそのインターフェイスを実装することで、色々なことが出来ます。


・Iterator
クラスオブジェクトを、foreachに突っ込んでやると配列のようにループさせることが出来る
http://jp2.php.net/manual/ja/class.iterator.php

・ArrayAccess
クラスオブジェクトに、配列のようにアクセスすることが出来る。
http://jp2.php.net/manual/ja/class.arrayaccess.php

他にも色々ありますが、このSimpleXMLElementという組み込みクラスには、恐らく、上記の二つが実装されているのではないかなぁと思います。(マニュアルには、Traversableのみの実装のようですが)

その為、帰ってきたクラスオブジェクトを、配列のようにアクセスし操作することが出来るのだと思います。
    • good
    • 0
この回答へのお礼

ありがとうございます。

おそらく私が理解していないのは、「ArrayAccess」なのかと思われます。
教えていただいたURLのマニュアルで、なぞは解けませんでしたが、
「ArrayAccess」か「SimpleXMLElement」を調べていけば、
なぞも解けていきそうです。

ありがとうございましたm(_ _)m

お礼日時:2010/12/25 09:43

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!