[PHP] unsetのちょっと不思議な動き

中身をクリアしておく上でちょくちょく使うunset

しかし、こいつにはちょっとクセがある。

Global

以下のようにglobal変数を関数の中で変更する。

そうするとunsetした時点で、$g_dummyはローカル変数になり、それ以降はすべてローカル変数として振舞われる。

header('Content-type: text/plain; charset=utf-8');
function echoLine($line){ echo $line . "\r\n"; }

$g_dummy = 0;

unsetTest();
echoLine($g_dummy);

function unsetTest(){
	global $g_dummy;
	$g_dummy++;
	echoLine($g_dummy);
	
	unset($g_dummy);	//この時点で$g_dummyがグローバルでなくなる。
	$g_dummy = 3;
	echoLine($g_dummy);
}

結果:

1
3
1

参照渡し

global変数はめったに使わないし、「へ~」で済んでたのだが、以下を見ると。

header('Content-type: text/plain; charset=utf-8'); 
function echoLine($line){ echo $line . "\r\n"; }

$dummy = 0;

unsetTest($dummy);
echoLine($dummy);

function unsetTest(&$argument){
	$argument++;
	echoLine($argument);
	
	unset($argument);	//この時点でローカル変数に置き換わる。
	$argument = 3;
	echoLine($argument);
}

結果

1
3
1

なんだと・・・!?

配列の場合

header('Content-type: text/plain; charset=utf-8');

$dummy = [ 1, 2, 3 ];

unsetTest($dummy);
print_r($dummy);

function unsetTest(&$argument){
	$argument[0]++;
	print_r($argument);
	
	unset($argument[0]);	//配列の一部をunsetしても置き換わらず、反映される。
	print_r($argument);
	
	unset($argument);	//この時点でローカル変数に置き換わる。以降の$argumentは別物になる。
	$argument[0] = 5;
	print_r($argument);
	
}

結果:

Array
(
    [0] => 2
    [1] => 2
    [2] => 3
)
Array
(
    [1] => 2
    [2] => 3
)
Array
(
    [0] => 5
)
Array
(
    [1] => 2
    [2] => 3
)

ん~、配列の中身はunsetしても置き換わらない模様。

 

クラスの場合

header('Content-type: text/plain; charset=utf-8');

$myClass = new MyClass();

unsetTest($myClass);
print_r($myClass);

function unsetTest($argument){
	$argument->dummy = 2;
	print_r($argument);
	
	unset($argument->dummy);	//配列の一部をunsetしても置き換わらず、反映される。
	print_r($argument);
	
	$argument->dummy = -1;
	
}

class MyClass{
	public $dummy = 0;
	public $dummyArray = [1,2,3];
}

結果:

MyClass Object
(
    [dummy] => 2
)
MyClass Object
(
)
MyClass Object
(
    [dummy] => -1
)

ん~、特に違和感なし。

 

引数字体をunsetすると、その時点でアドレスがクリアされるから、別物になるってことですね。

まぁ、ちょっと気になって調べたけど普通の動きだった。

ただ、Globalをunsetしても元のGlobalの値が保持されるってのは特殊かも。

 

 

 

 

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>