🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

4回答

24181閲覧

不要になった変数の扱い方

flat

総合スコア617

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

1グッド

3クリップ

投稿2015/07/07 03:26

編集2015/07/07 09:59

不要になった変数をどの様に扱うべきかで悩んでいます。
使わなくなった時点でunsetして削除するべきなのか、そのままにしておくべきなのか、あるいは他の選択肢があるのか、とても気になります。
どの様にするのが適切なのでしょうか。

追記
頂いた回答すべてがとても参考になるもので、ベストアンサーを選ぶのに大変迷いました。
質問にこの様な追記をするのはおかしいかもしれませんが、回答して下さった皆様に改めてお礼申し上げます。
ありがとうございました。

ki_luck_master👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

PHPにはガベージコレクタが備わっているので、関数内のローカル変数は関数を抜ければ全て勝手に処分されます。関数が長すぎるとか、関数外にPHPコードを直に書いているとか、ローカル変数のリスト自体を操作するとか、そういう特別な状況でなければ、それに任せて通常は問題ないでしょう。

ただし、foreachで変数を参照として受けた場合の参照はunsetしておかないと生き残るので、あとあとトラブルになりかねません。

lang

1foreach($arr as &$item){ 2 //$itemへの代入などを行う 3} 4unset($item);

投稿2015/07/07 04:09

maisumakun

総合スコア146011

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

flat

2015/07/07 08:12

回答して下さりありがとうございます。 関数にある限りは仰る様な例外さえなければ気にする必要はないのですね。 foreachに関してはよく見かけるので私も必ず行う様にしています。
guest

0

解放時の速度は,sounsi5011さんの引用記事の通りnull代入のほうが速いみたいですね.
使用メモリ量という点では,unset()の方が小さくなるというデータもあるみたいです.
PHP の array は明示的に消さないと GC 怪しそう
参照を外してしまえばガベージコレクションに回収されるので,
多少適当なプログラムを作ってもメモリリークが抑えられます.
実行速度を気にするのか,使用メモリ量を気にするのか,プログラミングコストを気にするのかで,
判断が分かれそうですね.

投稿2015/07/07 04:17

KenTerada

総合スコア751

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

flat

2015/07/07 09:31

回答して下さりありがとうございます。 リンク先の内容がとても興味深かったです。 メモリも考慮するとまた違う選択肢が見えてくるのですね。 配列はunsetで整数や文字列などはnullで上書きするのが良さそうだと思いました。
guest

0

よほど巨大な変数などでない限り、コード内でわざわざunset()して開放はあまりしないように思います。
ただし、私のこの認識が誤ってる可能性もあります。

なお、パフォーマンスで見るなら、unset()よりnullを代入した方が良いです。
What's better at freeing memory with PHP: unset() or $var = null - Stack Overflow

投稿2015/07/07 04:03

sounisi5011

総合スコア697

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

flat

2015/07/07 08:05

回答して下さりありがとうございます。 基本的には解放しなくとも良いのですね。 あとnullで上書きしてしまうのは目から鱗で大変参考になりました。
guest

0

ほとんどの場合そのまま放置しておいて問題ないと思います。スコープから外れた時に自動的にメモリからも削除されるからです。

とても巨大なデータを格納した変数であれば unset した方がいいこともあるかもしれません。
例えば、次の例だと unset のあるなしでメモリ使用量が全然変わります(とても極端な例ですが)。

lang

1<?php 2function hoge() 3{ 4 $a = str_repeat("超巨大なデータ", 1024*1024*5); 5 6 unset($a); 7 8 $b = str_repeat("超巨大なデータ", 1024*1024*5); 9}

また、大きめのスコープで参照を放置しておくとバグの元になりやすいです。
次のようなものが有名です。

lang

1<?php 2function hoge() 3{ 4 $a = [1, 2, 3]; 5 foreach ($a as &$v) { 6 $v++; 7 } 8 $b = ["a", "b", "c"]; 9 foreach ($b as $v) { 10 11 } 12 var_dump($a[2]); // なぜか "c" になる 13}

このようなケースでは unset が必要です。

lang

1<?php 2function hoge() 3{ 4 $a = [1, 2, 3]; 5 foreach ($a as &$v) { 6 $v++; 7 } 8 unset($v); 9 $b = ["a", "b", "v"]; 10 foreach ($b as $v) { 11 12 } 13 var_dump($a[2]); // 4 14}

また、オブジェクトやリソースの場合、unset でデストラクタやリソースの解放が行われたりします。
さらに PHP にはブロックスコープがないので、次のような状況で unset した方がいいこともあります。

lang

1try { 2 // 例えば Hoge がファイルのロックをつかむ場合 3 $obj = new Hoge(__DIR__ . '/hoge.lock'); 4 5 // いろいろ 6 7} catch (Exception $ex) { 8 // ここで Hoge がファイルをロックしたままだとまずい場合は unset が必要 9 unset($obj); 10 11 // いろいろ 12}

もっとも、PHP でオブジェクトの寿命をプログラムから制御するのは下記のような理由でかなり困難なので、普通はこんなことまでは考えません。
オブジェクトが例外の呼び出し履歴に参照されてデストラクタが呼ばれない - ngの日記

投稿2015/07/07 04:10

編集2015/07/07 04:19
ngyuki

総合スコア4516

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

flat

2015/07/07 08:43

回答して下さりありがとうございます。 基本的に巨大なデータを格納した変数でなければ放置で良いという事なのですね。 foreachに関しては私も気をつける様にしています。 最後にある例は私の知識が追いついておらずにまだ理解が出来ていませんが、理解出来る様になりましたら参考にしたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問