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ランキング
-
pythonのファイルの並びでの読...
-
ログファイルの古い日付の行を...
-
curlをPHPで書く方法
-
別ファイルの構造体の値を読み...
-
配列をファイルに書き込む方法
-
エラーメッセージ(無効な間接...
-
PHPでサーバー上の書き換えたht...
-
PHPで、CSVファイルを、指定し...
-
CSVデータの行数カウントをした...
-
stdClass Objectを連想配列のよ...
-
CSVでアップロードしたデータの...
-
多次元配列の一次元目の最大値...
-
C言語でCSVファイルの行数を読...
-
phpを実行するとファイルダウン...
-
スカラーのベクトル微分
-
ファイルの書き込みについて教...
-
プルダウンメニューにDBの内容...
-
String だと「 ByRef引数の型が...
-
file_existsでファイル名の部分...
-
漢字のソートについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
別ファイルの構造体の値を読み...
-
Resource id #3 と表示されま...
-
C言語でCSVファイルの行数を読...
-
ヒアドキュメントの中のfor文
-
stdClass Objectを連想配列のよ...
-
複数行のデータのPOST処理に関して
-
配列をファイルに書き込む方法
-
PHP: 未定義エラーの回避方法を...
-
自動で番号を振りたい
-
phpを実行するとファイルダウン...
-
PHP SimpleXml unsetについて
-
FortranのOPEN文
-
複数ファイルで、それぞれの行...
-
行数が30万件ほどあるCSVから、...
-
While文を使って配列の中身を全...
-
配列同士の足し算のループ処理
-
phpメールフォームから送信され...
-
テキストデータから指定行の削除
-
phpで日本語の文字列を抽出した...
-
バイナリファイルの内容を、そ...
おすすめ情報