這可能微不足道,但取消設定不存在的變數不會產生錯誤。
(PHP 4, PHP 5, PHP 7, PHP 8)
unset — 取消設定指定的變數
unset() 會銷毀指定的變數。
unset() 在函式內的行為可能會根據您嘗試銷毀的變數類型而有所不同。
如果在函式內對全域變數使用 unset(),則只會銷毀區域變數。呼叫環境中的變數將保留與呼叫 unset() 之前的相同值。
<?php
function destroy_foo()
{
global $foo;
unset($foo);
}
$foo = 'bar';
destroy_foo();
echo $foo;
?>
以上範例會輸出
bar
要在函式內使用 unset() 刪除全域變數,請使用 $GLOBALS 陣列來執行此操作。
<?php
function foo()
{
unset($GLOBALS['bar']);
}
$bar = "something";
foo();
?>
如果在函式內使用 unset() 刪除以「傳址呼叫」方式傳遞的變數,則只會銷毀區域變數。呼叫環境中的變數將保留與呼叫 unset() 之前的相同值。
<?php
function foo(&$bar)
{
unset($bar);
$bar = "blah";
}
$bar = 'something';
echo "$bar\n";
foo($bar);
echo "$bar\n";
?>
以上範例會輸出
something something
如果在函式內使用 unset() 刪除靜態變數,unset() 只會在函式其餘部分的上下文中銷毀該變數。後續的呼叫將會恢復變數先前的值。
<?php
function foo()
{
static $bar;
$bar++;
echo "unset 之前: $bar, ";
unset($bar);
$bar = 23;
echo "unset 之後: $bar\n";
}
foo();
foo();
foo();
?>
以上範例會輸出
Before unset: 1, after unset: 23 Before unset: 2, after unset: 23 Before unset: 3, after unset: 23
var
要取消設定的變數。
vars
其他變數。
不回傳任何值。
範例 #1 unset() 範例
<?php
// 銷毀單一變數
unset($foo);
// 銷毀陣列中的單一元素
unset($bar['quux']);
// 銷毀多個變數
unset($foo1, $foo2, $foo3);
?>
範例 #2 使用 (unset)
轉型
(unset)
轉型經常與 unset() 函式混淆。(unset)
轉型僅作為 NULL
類型轉型,以求完整性。它不會改變它轉型的變數。(unset) 轉型自 PHP 7.2.0 起已被棄用,並自 8.0.0 起移除。
<?php
$name = 'Felipe';
var_dump((unset) $name);
var_dump($name);
?>
以上範例會輸出
NULL string(6) "Felipe"
注意事項:
可以取消設定在目前環境下可見的物件屬性。
注意事項:
無法在物件方法內取消設定
$this
。
注意事項:
當對不可存取的物件屬性使用 unset() 時,如果已宣告,則會呼叫 __unset() 重載方法。
您不需要在使用 unset() 之前檢查變數是否已設定。
<?php
unset($a);
?>
這樣做是無害的。
<?php
if(isset($a)) {
unset($a);
}
?>
這樣做是多此一舉。
這不適用於具有 __isset() 方法(會明顯改變物件狀態)或 __unset() 方法(沒有正確檢查其參數或有額外副作用)的物件屬性。
後一種情況意味著 __unset 不應該做超出其名稱所示範疇的事情,並且也有責任檢查(可能使用 __isset())它被要求做的事情是否有意義。
前一種情況則根本就是糟糕的設計。
如果您嘗試 unset 一個物件,請注意參考 (reference)。
只有在*所有*參考都被 unset 時,物件才會釋放其資源並觸發其 __destruct 方法。
即使它們*在*物件內部... 唉!
<?php
class A {
function __destruct() {
echo "cYa later!!\n";
}
}
$a = new A();
$a -> a = $a;
#unset($a); # 只要取消註釋,您就會看到
echo "沒有訊息 ... 嗯,現在怎麼辦?\n";
unset($a -> a);
unset($a);
echo "終於擺脫那東西了\n";
?>
當然,物件會在腳本結束時完全消失。
由於 unset() 是一個語言結構,因此除了變數之外,不能傳遞任何其他內容給它。它的唯一目的是「取消設定」這個變數,即將其從目前的範圍中移除並銷毀其相關的資料。這尤其適用於參考變數,其中銷毀的不是實際值,而是對該值的參考。這就是為什麼您不能將 'unset()' 包裝在使用者定義的函式中的原因:如果參數是傳值,您將取消設定資料的副本;如果參數是傳參考,您將只取消設定函式範圍內的參考變數。沒有辦法解決這個問題,因為您無法在 PHP 中將「範圍」傳遞給函式。這樣的函式只能作用於存在於共同或全域範圍內的變數(比較 'unset($_GLOBALS[variable])')。
我不確定 PHP 內部是如何處理垃圾回收的,但我猜想這種行為可能會導致嚴重的記憶體洩漏:如果一個值變數超出作用範圍,但另一個變數仍然持有對記憶體中該值的引用,那麼取消該引用雖然會釋放該變數,但實際上該值仍然佔據著記憶體空間,而且可能同時也取消了對該記憶體資料的最後一個引用,因此:佔用的記憶體變得無用,因為您再也無法引用它。
以下是一個如何從 mysql 請求返回的陣列結果中取消陣列元素的範例。在此範例中,它會檢查檔案是否存在,如果不存在,則從陣列中移除該列。
<?php
$db->set_query("select * from documents where document_in_user = 0"); //1
$documents = $db->result_to_array($db->get_result()); //1
foreach ($documents as $key => $row) { //2
$file = "uploads/".rawurldecode($row['document_name']);
if ( file_exists ( $file ) == FALSE ) {
unset($documents[$key]); //3
}
}
$documents = array_values($documents); // 重新索引陣列 (4)
?>
變數
mysql 資料表 = documents,
陣列 = $documents
陣列鍵值 (索引) = $key
陣列列 (類似記錄) = $row
說明
1.
它從資料表 (mysql) 中取得陣列
2.
foreach 迴圈會遍歷 $documents 陣列
3.
如果記錄不存在,則取消設定
4.
array_values($documents) 會重新索引 $documents 陣列,否則當您的程式開始預期陣列從鍵值 ($key) 0 (零) 開始時,可能會遇到問題。
以下是另一種在函式內使用 unset 處理 session 變數的方法
<?php
function unsetSessionVariable ($sessionVariableName) {
unset($GLOBALS[_SESSION][$sessionVariableName]);
}
?>
希望對其他人也有用...
F.
只有在 register_globals 設為 'ON' 時,這才會有效。
unset( $_SESSION['variable'] );
以上程式碼在 register_globals 開啟時將無法運作 (只會在函式外運作)。
$variable = $_SESSION['variable'];
unset( $_SESSION['variable'], $variable );
以上程式碼在 register_globals 開啟且位於函式內部時可以正常運作。
補充說明 hugo dot dworak at gmail dot com 提到的關於 unset 不存在的變數的說明。
對陣列中不存在的鍵值使用 unset 並不會產生錯誤。
<?
$array = array();
unset($array[2]);
// 這不會產生錯誤
unset($array[$undefinedVar]);
// 會產生錯誤是因為使用了未定義的變數,而不是因為不存在的鍵值。
?>
補充 bond at noellebond dot com 的說明,如果要移除陣列尾端的索引,使用 unset 的話,下一個索引值仍然會是原本預期的值。
例如:
<?php
$x = array(1, 2);
for ($i = 0; $i < 5; $i++)
{
unset($x[(count($x)-1)]); //移除陣列中最後一個已設定的鍵值
$x[] = $i;
}
?>
你預期會得到
Array([0] => 1, [1] => 4)
因為你想移除最後一個已設定的鍵值…
但實際上你會得到
Array ( [0] => 1 [4] => 2 [5] => 3 [6] => 4 )
這是因為即使最後一個鍵值被移除,自動索引仍然保留其先前的值。
只有在移除尾端的值時,結果才會看起來不對。我想不同的人會有不同的期望。
解決方法是使用 array_pop() 取代 unset(),因為 array_pop() 會重新整理陣列的自動索引。
<?php
$x = array(1, 2);
for ($i = 0; $i < 5; $i++)
{
array_pop($x); // 移除陣列中的最後一個項目
$x[] = $i;
}
?>
這樣會返回預期的值 x = Array([0] => 1, [1] => 4);
希望這能幫助到有類似特殊需求的人,就像我一樣。
儘管經過多方搜尋,我仍然找不到關於如何在 PHP 中手動釋放變數(並非物件)資源的說明。我也看到許多關於 unset() 與將變數設為 null 的優缺點的評論。因此,以下是一些基準測試的結果,比較了 unset() 多個變數與將它們設為 null 在記憶體使用量和處理時間方面的差異。
10 個變數
Unset
記憶體使用量:296
耗時:1.0013580322266E-5
設為 Null
記憶體使用量:1736
耗時:5.9604644775391E-6
50 個變數
Unset
記憶體使用量:296
耗時:3.6001205444336E-5
設為 Null
記憶體使用量:8328
耗時:3.2901763916016E-5
100 個變數
Unset
記憶體使用量:296
耗時:5.6982040405273E-5
設為 Null
記憶體使用量:15928
耗時:5.8174133300781E-5
1000 個變數
Unset
記憶體使用量:296
耗時:0.00041294097900391
設為 Null
記憶體用量:168096
耗時:0.00067591667175293
10000 個變數
Unset
記憶體使用量:296
耗時:0.0042569637298584
設為 Null
記憶體用量:1650848
耗時:0.0076930522918701
100000 個變數
Unset
記憶體使用量:296
耗時:0.042603969573975
設為 Null
記憶體用量:16249080
耗時:0.087724924087524
300000 個變數
Unset
記憶體使用量:296
耗時:0.13177299499512
設為 Null
記憶體用量:49796320
耗時:0.28617882728577
或許我針對空集合的測試程式碼有瑕疵,但即使如此,仍然可以很容易地看出 unset() 對處理時間的影響極小,而且對記憶體用量沒有明顯的影響(除非 memory_get_usage() 返回的值有問題)。如果您真的在意少於 50 個變數時省下的約 4 微秒,那就隨您便。否則,請使用 unset() 來盡量減少腳本對系統的影響。
備註:在 Fedora 14 上透過 RPM 安裝的 PHP 5.3.8 進行測試
至少在 PHP 5.0.4 中,可以透過傳參考的方式將陣列傳入函式,並在函式內 unset 陣列元素。
然而,正如手冊所暗示的,不能透過傳參考的方式 unset 整個陣列。
<?php
function remove_variable (&$variable) // 以傳址方式傳遞變數
{
unset($variable);
}
function remove_element (&$array, $key) // 以傳址方式傳遞陣列
{
unset($array[$key]);
}
$scalar = 'Hello, there';
echo '變數 $scalar 的值是:';
print_r ($scalar); echo '<br />';
// 變數 $scalar 的值是:Hello, there
remove_variable($scalar); // 嘗試取消設定變數
echo '變數 $scalar 的值是:';
print_r ($scalar); echo '<br />';
// 變數 $scalar 的值是:Hello, there
$array = array('one' => 1, 'two' => 2, 'three' => 3);
echo '變數 $array 的值是:';
print_r ($array); echo '<br />';
// 變數 $array 的值是:Array ( [one] => 1 [two] => 2 [three] => 3 )
remove_variable($array); // 嘗試取消設定陣列
echo '變數 $array 的值是:';
print_r ($array); echo '<br />';
// 變數 $array 的值是:Array ( [one] => 1 [two] => 2 [three] => 3 )
remove_element($array, 'two'); // 成功從陣列中移除一個元素
echo '變數 $array 的值是:';
print_r ($array); echo '<br />';
// 變數 $array 的值是:Array ( [one] => 1 [three] => 3 )
?>
請注意,如果您嘗試取消設定一個不存在的陣列索引,且其父索引也不存在,PHP 4 會產生警告。
範例
<?php
$foo = array();
unset($foo['Bar']['Baz']);
?>
結果:「注意:未定義的索引:Bar」
在 PHP 5 上不會引發錯誤,這對我來說像是正確的行為。
請注意,在上述範例中使用 unset($foo['Bar']) 在任何一個版本中都不會產生警告。
(已在 4.4.9 和 5.2.4 上測試)
我在其他註釋中找不到這個說明,但它似乎很重要,所以即使可能重複…
雖然全域變數,例如整個陣列,無法在函式內 unset,但陣列的元素卻可以被 unset。所以
<?
function myfunction(){
global $test;
unset($test[1]);
print_r($test);
unset($test)
}
$test = array(1,2,3);
myfunction();
print_r($test);
?>
會產生
Array ( [0] => 1 [2] => 3 ) # 來自 myfunction 函式內部
Array ( [0] => 1 [2] => 3 ) # 從 myfunction 函式返回後
這是我的 unset 方法變體,稍微無聊的 unset 方法加入了一些 80 年代史特龍動作片的元素。好好享受吧!
<?php
/**
* 函式 rambo (第一滴血)
*
* 完全徹底摧毀一切,返回受害者的擊殺數
*
* @param 沒差,這是藍波寶貝
* @return 整數 屍體數量(但任何少於 500 的都不值得一提)
*/
function rambo() {
// 取得受害者並初始化屍體數量狀態
$victims = func_get_args();
$body_count = 0;
// 殺掉那些該死的混蛋
foreach($victims as $victim) {
if($death_and_suffering = @unset($victim)) {
$body_count++;
}
}
// 藍波在這次任務中累積了多少擊殺數?
return($body_count);
}
?>
只是要確認一下,使用 UNSET 可以摧毀整個陣列。我在任何地方都找不到相關的說明,所以我決定寫下來。
使用 unset 和使用 $myarray=array(); 來 unset 的差別在於,顯然地,陣列只是被覆寫,仍然存在。
<?php
$myarray=array("Hello","World");
echo $myarray[0].$myarray[1];
unset($myarray);
//$myarray=array();
echo $myarray[0].$myarray[1];
echo $myarray;
?>
使用 unset 的輸出是
<?
HelloWorld
注意:未定義的偏移量:0,位於 C:\webpages\dainsider\myarray.php 的第 10 行
注意:未定義的偏移量:1,位於 C:\webpages\dainsider\myarray.php 的第 10 行
使用 $myarray=array(); 的輸出是
?>
<?
HelloWorld
注意:未定義的偏移量:0,位於 C:\webpages\dainsider\myarray.php 的第 10 行
注意:未定義的偏移量:1,位於 C:\webpages\dainsider\myarray.php 的第 10 行
Array
?>
dh at argosign dot de -
可以透過 $GLOBALS 陣列在函式內取消設定全域變數
<?php
$x = 10;
function test() {
// 不需要執行 ' global $x; '
unset ($GLOBALS['x']);
echo 'x: ' . $GLOBALS['x'] . '<br />';
}
test();
echo "x: $x<br />";
// 結果會是
/*
x:
x:
*/
?>
關於靜態變數的說明文件並不是很清楚。它說
如果在函式內使用 unset() 取消設定靜態變數,unset() 會銷毀該變數及其所有參考。
<?php
function foo()
{
static $a;
$a++;
echo "$a\n";
unset($a);
}
foo();
foo();
foo();
?>
以上範例的輸出會是
1
2
3
確實如此!但變數並**沒有**被刪除,這就是為什麼值會持續增加,否則輸出會是
1
1
1
在函式內,參考會被銷毀,這個處理方式與全域變數相同,不同的是靜態變數是區域變數。
使用 unset 和靜態值時要小心,因為輸出可能不是您預期的結果。靜態變數似乎無法被銷毀。您只能銷毀目前執行函式內的參考,後續的 static 聲明會恢復參考。
如果說明文件改成這樣會更好
「如果在函式內使用 unset() 取消設定靜態變數,unset() 會銷毀該變數的所有參考。」
範例:(PHP 4.3.7 測試)
<?php
function foo()
{
static $a;
$a++;
echo "$a\n";
unset($a);
echo "$a\n";
static $a;
echo "$a\n";
}
foo();
foo();
foo();
?>
會輸出
1
1
2
2
3
3
關於陣列的 unset
如果您取消設定最後一個陣列成員
$ar[0]==2
$ar[1]==7
$ar[2]==9
unset ($ar[2])
透過 $ar[]=7 新增一個新成員後,
您會得到
$ar[0]==2
$ar[1]==7
$ar[3]==7,
所以,unset 對內部陣列計數器沒有影響!!!
此外,我發現一個物件在被銷毀時,會銷毀物件空間可見範圍內的變數,但不會銷毀局部可見範圍內的變數,請注意這個發現的模式。
<?php
class release_test{
private $buffer;
private $other_object;
public function __construct(){
$this->other_object=new other_object_class();
}
public function __destruct(){
//請注意,您必須手動清除類別物件,才能釋放資源
unset($this->other_object);
}
public allocate_mem_A(){
$this->buffer=file("/tmp/bigfile");
}
public allocate_mem_B(){
$buffer=file("/tmp/bigfile");
}
public allocate_mem_C(){
$buffer=file("/tmp/bigfile");
unset($buffer);
}
public allocate_mem_D(){
$this->other_buffer=file("/tmp/bigfile");
}
}
//這不會導致資源問題
$A=new release_test();
$A->allocate_mem_A();
$A->__destruct();
unset($A);
//這會導致資源問題
$B=new release_test();
$B->allocate_mem_B();
$B->__destruct();
unset($B);
//這不會導致資源問題
$C=new release_test();
$C->allocate_mem_C();
$C->__destruct();
unset($C);
//這不會導致資源問題
$D=new release_test();
$D->allocate_mem_D();
$D->__destruct();
unset($D);
?>
您可能想要清除所有已定義的變數,以下是一種方法:
<?php
function unset_all_vars($a)
{ foreach($a as $key => $val)
{ unset($GLOBALS[$key]); }
return serialize($a); }
unset_all_vars(get_defined_vars());
?>
您也可以將「記憶體」儲存為一個序列化變數,並將其儲存在一個暫存檔案中。如果您在處理文字檔或檔案上傳時遇到非常大的變數,這將非常有用。
問候
警告!
從陣列中使用 unset() 移除元素時,即使移除所有元素,該陣列仍然存在。
$tab=array('A'=>1,'B'=>2);
unset($tab['A']);
unset($tab['B']);
echo isset($tab)." ".count($tab);
輸出: 1 0
關於先前在這些筆記中,對於 unset() 在移除不存在的變數時觸發通知的原因的一些混淆……
移除不存在的變數,例如
<?php
unset($undefinedVariable);
?>
不會觸發「未定義變數」通知。但是
<?php
unset($undefinedArray[$undefinedKey]);
?>
會觸發兩個通知,因為這段程式碼是用於移除陣列中的元素;$undefinedArray 和 $undefinedKey 本身都沒有被移除,它們僅用於定位應該被移除的元素。畢竟,如果它們確實存在,您仍然會預期它們在之後都還在。您不會希望整個陣列僅僅因為您 unset() 了其中一個元素就消失!
除了使用 unset 函式來取消註冊您的 session 或其他陣列值之外,您也可以使用這個小技巧,只需一行程式碼即可完成此任務。
假設,如果您想要取消註冊您的 session 儲存值。
您可以使用
$_SESSION = array();
這個語法可以節省很多時間,而不用逐個取消設定每個值。
有時您需要在某些迴圈(if、while、foreach 等)中將值賦值給陣列索引,但您希望將起始索引鍵設定為大於零的數字(例如 5)。一種方法如下:
<?php
$values = array(5, 10, 15, 100); //我們希望添加到新陣列的值陣列
$myArray = array(4=>0); //將起始鍵設定為 4 並賦值(例如 0)
unset($myArray[4]); //刪除此索引鍵,但保留後續的編號
foreach($values as $value){
$myArray[] = $value; //將值賦值給我們的陣列
}
print_r($myArray);
/* 輸出:
Array ( [5] => 5 [6] => 10 [7] => 15 [8] => 100 )
*/
?>
兩種移除陣列中值的方法
<?php
# 透過鍵值移除:
function array_remove_key ()
{
$args = func_get_args();
return array_diff_key($args[0],array_flip(array_slice($args,1)));
}
# 透過值移除:
function array_remove_value ()
{
$args = func_get_args();
return array_diff($args[0],array_slice($args,1));
}
$fruit_inventory = array(
'apples' => 52,
'bananas' => 78,
'peaches' => '非產季',
'pears' => '非產季',
'oranges' => '已停售',
'carrots' => 15,
'beets' => 15,
);
echo "<pre>原始陣列:\n",
print_r($fruit_inventory,TRUE),
'</pre>';
# 例如,甜菜根和胡蘿蔔不是水果...
$fruit_inventory = array_remove_key($fruit_inventory,
"beets",
"carrots");
echo "<pre>移除鍵值後的陣列:\n",
print_r($fruit_inventory,TRUE),
'</pre>';
# 我們也移除「非產季」和「已停售」的水果...
$fruit_inventory = array_remove_value($fruit_inventory,
"非產季",
"已停售");
echo "<pre>移除值後的陣列:\n",
print_r($fruit_inventory,TRUE),
'</pre>';
?>
如果鍵值是字串,則無法移除數字鍵值的陣列。請參考以下範例
// 建立一個包含 3 種不同鍵值類型的簡單陣列
$test[1] = array(
10 => array('apples'),
"20" => array('bananas'),
'30' => array('peaches')
);
$test[2] = (array) json_decode(json_encode($test[1]));
$test[3] = (array) (object) $test[1];
// 來自 stdClass 物件的陣列
$testClass = new stdClass();
$testClass->{10} = array('apples');
$testClass->{"20"} = array('bananas');
$test[4] = (array) $testClass[6];
echo "<pre>";
foreach($test as $testNum => $arr) {
echo "\n測試: " . $testNum . " \n";
var_dump($arr);
foreach($arr as $key => $fruit) {
echo "鍵值: " . $key . "\n";
顯示 "鍵值存在: ";
var_dump(array_key_exists(strval($key), $arr));
顯示 "鍵值類型為: " . gettype($key) . "\n";
unset($arr[$key]);
}
var_dump($arr);
顯示 "\n" . str_repeat("-", 80);
}
顯示 "</pre>";
以下是輸出結果
測試: 1
陣列(3) {
[10]=>
陣列(1) {
[0]=>
字串(6) "apples"
}
[20]=>
陣列(1) {
[0]=>
字串(7) "bananas"
}
[30]=>
陣列(1) {
[0]=>
字串(7) "peaches"
}
}
鍵值: 10
鍵值存在: 布林(true)
鍵值類型為: 整數
鍵值: 20
鍵值存在: 布林(true)
鍵值類型為: 整數
鍵值: 30
鍵值存在: 布林(true)
鍵值類型為: 整數
陣列(0) {
}
--------------------------------------------------------------
測試: 2
陣列(3) {
["10"]=>
陣列(1) {
[0]=>
字串(6) "apples"
}
["20"]=>
陣列(1) {
[0]=>
字串(7) "bananas"
}
["30"]=>
陣列(1) {
[0]=>
字串(7) "peaches"
}
}
鍵值: 10
鍵值存在: 布林(false)
鍵值類型為: 字串
鍵值: 20
鍵值存在: 布林(false)
鍵值類型為: 字串
鍵值: 30
鍵值存在: 布林(false)
鍵值類型為: 字串
陣列(3) {
["10"]=>
陣列(1) {
[0]=>
字串(6) "apples"
}
["20"]=>
陣列(1) {
[0]=>
字串(7) "bananas"
}
["30"]=>
陣列(1) {
[0]=>
字串(7) "peaches"
}
}
--------------------------------------------------------------
測試: 3
陣列(3) {
[10]=>
陣列(1) {
[0]=>
字串(6) "apples"
}
[20]=>
陣列(1) {
[0]=>
字串(7) "bananas"
}
[30]=>
陣列(1) {
[0]=>
字串(7) "peaches"
}
}
鍵值: 10
鍵值存在: 布林(true)
鍵值類型為: 整數
鍵值: 20
鍵值存在: 布林(true)
鍵值類型為: 整數
鍵值: 30
鍵值存在: 布林(true)
鍵值類型為: 整數
陣列(0) {
}
--------------------------------------------------------------
測試: 4
陣列(2) {
["10"]=>
陣列(1) {
[0]=>
字串(6) "apples"
}
["20"]=>
陣列(1) {
[0]=>
字串(7) "bananas"
}
}
鍵值: 10
鍵值存在: 布林(false)
鍵值類型為: 字串
鍵值: 20
鍵值存在: 布林(false)
鍵值類型為: 字串
陣列(2) {
["10"]=>
陣列(1) {
[0]=>
字串(6) "apples"
}
["20"]=>
陣列(1) {
[0]=>
字串(7) "bananas"
}
}
--------------------------------------------------------------
透過重建陣列來解決問題
$oldArray = $array();
$array = array();
foreach($oldArray as $key => $item) {
$array[intval($key)] = $item;
}
在 PHP 5.1.6 版本中觀察到,在方法內使用 <?php unset($this); ?> 將會移除該方法中對 $this 的參考。 就 unset() 而言,$this 並不被視為「特殊」變數。
您可以 unset 超全域變數,例如 $GLOBALS、$_GET 等,但會導致異常行為(截至 PHP 5.3.3)。
1) 超全域變數的 unset 是全域性的,也就是在函式內 unset 會影響全域。
2) 可以重新建立 unset 過的超全域變數(重新建立的變數是超全域變數),但原始功能(在 $GLOBALS、$_SESSION ... 中)會遺失。
<?php
function foo(){
unset($GLOBALS);
}
function bar(){
var_dump($GLOBALS);
}
foo();
bar(); //發出 E_NOTICE 警告($GLOBALS 未定義)
$GLOBALS = 3;
bar(); //顯示 int(3)
?>
<?php
$list = ['a', 'b', 'c'];
next($list);
unset($list[1]);
echo current($list); // 結果 : "c"