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());
No.1ベストアンサー
- 回答日時:
削除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」
?>
ありがとうございます。
おっしゃるとおり$item[0]で削除できました。
よくよく見ると「削除2」も同じ事をやっていました(^^;)
ありがとうございます。
ただ、なぜ参照コピーされた$itemを$item[0]と
指定すると参照元を指定できるのが不明です。
ちなみにデバックして$item[100]などを指定しても
エラーとはならず、$itemと同じ物を参照しているようです。
$itemは配列ではないと、私は思っているので
$item[0]や$item[100]など使用するとエラーに
なると思っていたのですがなぜこのようになるのでしょうか?
たびたび質問で申し訳ありません。
宜しくお願い致します。
No.2
- 回答日時:
PHPには、インターフェイスという物があって、自前のクラスなどにそのインターフェイスを実装することで、色々なことが出来ます。
・Iterator
クラスオブジェクトを、foreachに突っ込んでやると配列のようにループさせることが出来る
http://jp2.php.net/manual/ja/class.iterator.php
・ArrayAccess
クラスオブジェクトに、配列のようにアクセスすることが出来る。
http://jp2.php.net/manual/ja/class.arrayaccess.php
他にも色々ありますが、このSimpleXMLElementという組み込みクラスには、恐らく、上記の二つが実装されているのではないかなぁと思います。(マニュアルには、Traversableのみの実装のようですが)
その為、帰ってきたクラスオブジェクトを、配列のようにアクセスし操作することが出来るのだと思います。
ありがとうございます。
おそらく私が理解していないのは、「ArrayAccess」なのかと思われます。
教えていただいたURLのマニュアルで、なぞは解けませんでしたが、
「ArrayAccess」か「SimpleXMLElement」を調べていけば、
なぞも解けていきそうです。
ありがとうございましたm(_ _)m
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- SEO 検索エンジン反映遅い 1 2022/06/04 07:35
- Visual Basic(VBA) Excelで下記のようにマクロを作ったところ、一回目は実行できたのですが、二回目以降「実行時エラー1 1 2022/03/25 08:08
- Visual Basic(VBA) vba 重複データ合算 5 2023/07/05 18:55
- au(KDDI) Android Gmail で検索して消す方法 1 2022/11/10 16:10
- X(旧Twitter) 削除したアカウントやツイートのグーグルの検索結果を削除するにはどうしたらいいですか? 3 2023/01/10 18:05
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- X(旧Twitter) カギをかけているツイッターの検索について教えてください。 2 2022/11/07 17:22
- Visual Basic(VBA) エクセルのマクロについて教えてください。 1 2023/08/10 11:34
- ハッキング・フィッシング詐欺 ネット検索で出る自分の名前を削除したい 3 2022/05/07 13:44
- Visual Basic(VBA) 3つの条件を指定してVBAで行を削除したい 条件1:分類1が重複 条件2:分類2が重複 条件3:個数 6 2022/06/24 11:07
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列同士の足し算のループ処理
-
doxygenを使用する環境について
-
mysqlと出力側PHPの文字コード...
-
複数行のデータのPOST処理に関して
-
エラーメッセージ(無効な間接...
-
別ファイルの構造体の値を読み...
-
VBAでcsvファイルもシートもあ...
-
2次元配列から1次元配列へのデ...
-
Resource id #3 と表示されま...
-
クラスで使用する「参照渡し」...
-
FortranのOPEN文
-
CSVファイルの最終行のデー...
-
行数が30万件ほどあるCSVから、...
-
fgetc関数について
-
php 1桁になるまでの和 スマー...
-
$_SESSIONに二次元配列を使える...
-
Smartyの自作プラグインで配列...
-
スカラーのベクトル微分
-
配列をループでたくさん宣言し...
-
配列にある文字列を1つの変数に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
複数行のデータのPOST処理に関して
-
Resource id #3 と表示されま...
-
別ファイルの構造体の値を読み...
-
バイナリファイルの内容を、そ...
-
PHPでCSVの一部の行を編集したい
-
CSVファイルの最終行のデー...
-
ヒアドキュメントの中のfor文
-
stdClass Objectを連想配列のよ...
-
◆速い、ファイル読み込みは?
-
C言語でCSVファイルの行数を読...
-
phpでCSVファイルの中身を多次...
-
rubyで複数列のデータを一行に...
-
多次元配列の一次元目の最大値...
-
行数が30万件ほどあるCSVから、...
-
配列同士の足し算のループ処理
-
FortranのOPEN文
-
自動で番号を振りたい
-
csvの内容を行単位で削除したい
-
CSVデータの行数カウントをした...
-
While文を使って配列の中身を全...
おすすめ情報