PHP Conference Japan 2024

isset

(PHP 4, PHP 5, PHP 7, PHP 8)

isset判斷變數是否已宣告且與 null 不同

說明

isset(mixed $var, mixed ...$vars): bool

判斷變數是否被視為已設定,這表示變數是否已宣告且與 null 不同。

如果變數已使用 unset() 函式取消設定,則它不再被視為已設定。

當檢查一個被賦值為 null 的變數時,isset() 會回傳 false。另外請注意,空字元 ("\0") 並不等同於 PHP 的 null 常數。

如果提供了多個參數,則只有當所有參數都被視為已設定時,isset() 才會回傳 true。 評估順序是從左到右,並在遇到未設定的變數時停止。

參數

var

要檢查的變數。

vars

其他變數。

回傳值

如果 var 存在且具有 null 以外的任何值,則回傳 true。否則回傳 false

範例

範例 #1 isset() 範例

<?php

$var
= '';

// 這個會評估為 TRUE,所以文字會被印出。
if (isset($var)) {
echo
"這個變數已設定,所以我會印出。";
}

// 在接下來的例子中,我們將使用 var_dump 來輸出
// isset() 的回傳值。

$a = "test";
$b = "anothertest";

var_dump(isset($a)); // TRUE
var_dump(isset($a, $b)); // TRUE

unset ($a);

var_dump(isset($a)); // FALSE
var_dump(isset($a, $b)); // FALSE

$foo = NULL;
var_dump(isset($foo)); // FALSE

?>

這也適用於陣列中的元素

<?php

$a
= array ('test' => 1, 'hello' => NULL, 'pie' => array('a' => 'apple'));

var_dump(isset($a['test'])); // TRUE 真
var_dump(isset($a['foo'])); // FALSE 假
var_dump(isset($a['hello'])); // FALSE 假

// 鍵值 'hello' 等於 NULL,所以被視為未設定
// 如果要檢查 NULL 鍵值,請嘗試:
var_dump(array_key_exists('hello', $a)); // TRUE 真

// 檢查更深層的陣列值
var_dump(isset($a['pie']['a'])); // TRUE 真
var_dump(isset($a['pie']['b'])); // FALSE 假
var_dump(isset($a['cake']['a']['b'])); // FALSE 假

?>

範例 #2 使用 isset() 檢查字串的偏移量

<?php
$expected_array_got_string
= 'somestring';
var_dump(isset($expected_array_got_string['some_key']));
var_dump(isset($expected_array_got_string[0]));
var_dump(isset($expected_array_got_string['0']));
var_dump(isset($expected_array_got_string[0.5]));
var_dump(isset($expected_array_got_string['0.5']));
var_dump(isset($expected_array_got_string['0 Mostel']));
?>

上述範例將輸出:

bool(false)
bool(true)
bool(true)
bool(true)
bool(false)
bool(false)

注意事項

警告

isset() 只適用於變數,傳入任何其他值都會導致剖析錯誤。要檢查 常數 是否已設定,請使用 defined() 函式。

注意因為這是一個語言結構而不是函式,所以它不能使用 可變函式具名引數 來呼叫。

注意:

當在不可存取的物件屬性上使用 isset() 時,如果已宣告,則會呼叫 __isset() 重載方法。

另請參閱

新增註釋

使用者貢獻的註釋 17 則註釋

p_ignorethis_lbowers at gmail dot com
8 年前
我也很沮喪地發現,如果 ($foo == null),isset($foo) 會返回 false。以下是一種(笨拙的)解決方法。

unset($foo);
if (compact('foo') != array()) {
do_your_thing();
}

當然,這非常不直觀、冗長、難以理解且笨拙。最好設計你的程式碼,讓你不用依賴未設定的變數和值為 null 的變數之間的差異。但「更好」只是因為 PHP 做了這個奇怪的開發選擇。

在我看來,這是 PHP 開發中的一個錯誤。名稱(「isset」)應該描述函式,而不是描述為「已設定且不為 null」。如果做得正確,程式設計師可以很容易地執行 (isset($var) || is_null($var)),如果他們想要檢查這個!

設定為 null 的變數與未設定的變數是不同的狀態 - 應該有一些簡單的方法來區分。只是我(毫無意義的)$0.02。
kurdtpage at gmail dot com
7 年前
新的(從 PHP7 開始)「null 聯合運算子」允許 isset 的簡寫。您可以像這樣使用它

<?php
// 擷取 $_GET['user'] 的值,如果不存在則返回 'nobody'
//。
$username = $_GET['user'] ?? 'nobody';
// 這等同於:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// 空值合併運算子可以串接:這將返回 $_GET['user']、$_POST['user'] 和
// 'nobody' 中第一個已定義的值。
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>

引用自 https://php.dev.org.tw/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op
a dot schaffhirt at sedna-soft dot de
16 年前
您可以安全地使用 isset 直接檢查物件的屬性和子屬性。因此,不必寫成

isset($abc) && isset($abc->def) && isset($abc->def->ghi)

或是簡寫成

isset($abc, $abc->def, $abc->def->ghi)

您可以直接寫成

isset ($abc->def->ghi)

而不會引發任何錯誤、警告或注意事項。

範例
<?php
$abc
= (object) array("def" => 123);
var_dump(isset($abc)); // bool(true) // 布林值(true)
var_dump(isset($abc->def)); // bool(true) // 布林值(true)
var_dump(isset($abc->def->ghi)); // bool(false) // 布林值(false)
var_dump(isset($abc->def->ghi->jkl)); // bool(false) // 布林值(false)
var_dump(isset($def)); // bool(false) // 布林值(false)
var_dump(isset($def->ghi)); // bool(false) // 布林值(false)
var_dump(isset($def->ghi->jkl)); // bool(false) // 布林值(false)

var_dump($abc); // object(stdClass)#1 (1) { ["def"] => int(123) } // 物件(stdClass)#1 (1) { ["def"] => 整數(123) }
var_dump($abc->def); // int(123) // 整數(123)
var_dump($abc->def->ghi); // null / E_NOTICE: Trying to get property of non-object // null / E_NOTICE:嘗試取得非物件的屬性
var_dump($abc->def->ghi->jkl); // null / E_NOTICE: Trying to get property of non-object // null / E_NOTICE:嘗試取得非物件的屬性
var_dump($def); // null / E_NOTICE: Trying to get property of non-object // null / E_NOTICE:嘗試取得非物件的屬性
var_dump($def->ghi); // null / E_NOTICE: Trying to get property of non-object // null / E_NOTICE:嘗試取得非物件的屬性
var_dump($def->ghi->jkl); // null / E_NOTICE: Trying to get property of non-object // null / E_NOTICE:嘗試取得非物件的屬性
?>
yaogzhan at gmail dot com
19 年前
如果您有

<?PHP
類別 Foo
{
protected
$data = 陣列('bar' => null);

函式
__get($p)
{
if( isset(
$this->data[$p]) ) return $this->data[$p];
}
}
?>

以及
<?PHP
$foo
= new Foo;
echo isset(
$foo->bar);
?>
永遠會輸出 'false'。因為 isset() 接受變數作為參數,但在這種情況下,$foo->bar 不是一個變數。它是類別 Foo 的 __get() 方法返回的值。因此 isset($foo->bar) 表達式永遠等於 'false'。
beuc at beuc dot net
17 年前
「empty() 與 (boolean) var 相反,除了在變數未設定時不會產生警告。」

所以基本上
<?php
if (isset($var) && $var)
?>
等同於
<?php
if (!empty($var))
?>
不是嗎? :)

!empty() 模擬了之前發布的 chk() 函式。
mandos78 AT mail from google
16 年前
小心使用 soapergem 的這個函式 "ifsetfor",傳遞引用意味著如果參數像範例 $_GET['id'] 那樣是一個陣列索引,它將會在原始陣列中被建立(值為 null),從而導致後續程式碼可能出現問題。至少在 PHP 5 中是這樣。

例如

<?php
$a
= 陣列();
print_r($a);
ifsetor($a["unsetindex"], 'default');
print_r($a);
?>

會印出

陣列
(
)
陣列
(
[unsetindex] =>
)

任何 foreach 或類似的迴圈在呼叫前後都會有所不同。
soywiz at php dot net
18 年前
有時您必須檢查陣列是否有一些鍵值。要做到這一點,您可以像這樣使用 "isset":isset($array['key1'], $array['key2'], $array['key3'], $array['key4'])
您每次都必須寫 $array,如果您每次都使用相同的陣列,就會很重複。

使用這個簡單的函式,您可以檢查一個陣列是否有一些鍵值

<?php
function isset_array() {
if (
func_num_args() < 2) return true;
$args = func_get_args();
$array = array_shift($args);
if (!
is_array($array)) return false;
foreach (
$args as $n) if (!isset($array[$n])) return false;
return
true;
}
?>

用法:isset_array($array, 'key1', 'key2', 'key3', 'key4')
第一個參數是陣列;後續的參數是要檢查的鍵值。
ayyappan dot ashok at gmail dot com
8 年前
回傳值
如果變數存在且值不為 NULL,則回傳 TRUE,否則回傳 FALSE。

<?php
$a
=NULL;
$b=FALSE; //輸出為 TRUE。
$c=TRUE;
$d='';
$e="";
if(isset(
$b)):
echo
"TRUE";
else:
echo
"FALSE";
endif;
?>
有人可以清楚地解釋一下嗎?
Hayley Watson
7 年前
如果你將 isset() 視為指示給定變數是否有值,並記得 NULL 的目的是指示值_不存在_(如其手冊頁面所述,有點拗口),那麼它的行為就一點也不矛盾或令人困惑。

它不只是用來檢查未初始化的變數——很多時候這些只是草率編碼造成的。還有其他原因可能導致變數沒有值(例如,它應該保存從函式呼叫返回的值,但函式沒有要返回的值),在這些情況下,未初始化變數是不可行的,甚至沒有意義(例如,取決於要如何處理返回的值)。
Cuong Huy To
13 年前
1) 請注意,isset($var) 無法區分 $var 未定義或為 null 這兩種情況。以下程式碼可以證明這一點。

<?php
unset($undefined);
$null = null;
if (
true === isset($undefined)){echo 'isset($undefined) === true'} else {echo 'isset($undefined) === false'); // 'isset($undefined) === false'
if (true === isset($null)){echo 'isset($null) === true'} else {echo 'isset($null) === false'); // 'isset($null) === false'
?>

2) 如果你想區分未定義的變數和已定義但值為 null 的變數,請使用 array_key_exist

<?php
unset($undefined);
$null = null;

if (
true !== array_key_exists('undefined', get_defined_vars())) {echo '$undefined 不存在';} else {echo '$undefined 存在';} // '$undefined 不存在'
if (true === array_key_exists('null', get_defined_vars())) {echo '$null 存在';} else {echo '$null 不存在';} // '$null 存在'
?>
packard_bell_nec at hotmail dot com
16 年前
注意:isset() 只檢查變數,其他任何東西都會導致解析錯誤。換句話說,以下寫法將無法運作:isset(trim($name))。

isset() 與 is_null($var) 的作用相反,差別在於當變數未設定時,isset() 不會產生警告。
Ashus
15 年前
請注意,陣列鍵值區分大小寫。

<?php
$ar
['w'] = true;

var_dump(isset($ar['w']),
isset(
$ar['W']));
?>

將會回傳
bool(true) bool(false)
Andrew Penry
19 年前
以下是如何測試一個變數是否已設定的範例,無論其值是否為 NULL。它利用了未設定的變數會拋出 E_NOTICE 錯誤,而初始化為 NULL 的變數則不會拋出錯誤的事實。

<?php

函數 var_exists($var){
if (empty(
$GLOBALS['var_exists_err'])) {
return
true;
} else {
unset(
$GLOBALS['var_exists_err']);
return
false;
}
}

函數
var_existsHandler($errno, $errstr, $errfile, $errline) {
$GLOBALS['var_exists_err'] = true;
}

$l = NULL;
set_error_handler("var_existsHandler", E_NOTICE);
echo (
var_exists($l)) ? "True " : "False ";
echo (
var_exists($k)) ? "True " : "False ";
restore_error_handler();

?>

輸出
True False

問題在於,`set_error_handler` 和 `restore_error_handler` 的呼叫不能放在函式內,這表示每次測試時都需要額外兩行程式碼。而且,如果在 `set_error_handler` 和 `restore_error_handler` 之間有任何其他程式碼造成 `E_NOTICE` 錯誤,它們將無法被正確處理。一種解決方案…

<?php

函數 var_exists($var){
if (empty(
$GLOBALS['var_exists_err'])) {
return
true;
} else {
unset(
$GLOBALS['var_exists_err']);
return
false;
}
}

函數
var_existsHandler($errno, $errstr, $errfile, $errline) {
$filearr = file($errfile);
if (
strpos($filearr[$errline-1], 'var_exists') !== false) {
$GLOBALS['var_exists_err'] = true;
return
true;
} else {
return
false;
}
}

$l = NULL;
set_error_handler("var_existsHandler", E_NOTICE);
echo (
var_exists($l)) ? "True " : "False ";
echo (
var_exists($k)) ? "True " : "False ";
is_null($j);
restore_error_handler();

?>

輸出
True False
注意:未定義的變數:j,檔案 filename.php 中,第 26 行

這樣會讓處理器只處理 var_exists,但會增加很多額外負擔。每次發生 E_NOTICE 錯誤時,都會將錯誤發生的檔案載入到陣列中。
francois vespa
13 年前
現在,以下是如何對物件和陣列實現相同的效果(即,即使變數已設定為 null,isset() 也會返回 true)

<?php

// array

$array=array('foo'=>null);

return isset(
$array['foo']) || array_key_exists('foo',$array)
?
true : false ; // return true

return isset($array['inexistent']) || array_key_exists('inexistent',$array)
?
true : false ; // return false

// static class

class bar

{
static
$foo=null;
}

return isset(
bar::$foo) || array_key_exists('foo',get_class_vars('bar'))
?
true : false ; // return true

return isset(bar::$inexistent) || array_key_exists('inexistent',get_class_vars('bar'))
?
true : false ; // return false

// object

class bar
{
public
$foo=null;
}

$bar=new bar();

return isset(
$bar->foo) || array_key_exists('foo',get_object_vars($bar))
?
true : false ; // return true

return isset($bar->inexistent) || array_key_exists('inexistent',get_object_vars($bar))
?
true : false ; // return true

// stdClass

$bar=new stdClass;
$bar->foo=null;

return isset(
$bar->foo) || array_key_exists('foo',get_object_vars($bar))
?
true : false ; // return true

return isset($bar->inexistent) || array_key_exists('inexistent',get_object_vars($bar))
?
true : false ; // return true

?>
andreasonny83 at gmail dot com
9 年前
以下是用多個參數提供的範例

<?php
$var
= array();
$var['val1'] = 'test';
$var['val2'] = 'on';

if ( isset(
$var['val1'], $var['val2'] ) && $var['val2'] === 'on' ) {
unset(
$var['val1'] );
}
print_r( $var );
?>

這將輸出
陣列
(
[val2] => on
)

以下程式碼執行相同的「isset」兩次

<?php
$var
= array();
$var['val1'] = 'test';
$var['val2'] = 'on';

if ( isset(
$var['val1'] ) && isset( $var['val2'] ) && $var['val2'] === 'on' ) {
unset(
$var['val1'] );
}
print_r( $var );
?>
eckoson at gmail dot com
1 年前
如果您對 isset() 處理 null 值的行為感到困擾,這裡有一個方便的函式提供給您。它類似於 array_key_exists,但它更加靈活,可以檢查跨多個陣列的多個陣列鍵值是否存在。
非遞迴!
在 php 8.1.6, linux 上測試
<?php
/**
* is_set
* @author DJ Eckoson
* @link @eckosongh Facebook Page
* checks whether variable names are set within the global space or they exists as an key and return if they are set (even if their values are null)
* @param string $var_name
* name of the first variable to check
* @param array|null|string
* optional array to check for key (if null, checks from $GLOBALS) OR
* other variable names to check OR
* other variable names and their associated arrays to their right (use null for global variables, optional if its the last parameter)
* check examples below
*/
function is_set(string $var_name, array|null|string ... $args): bool {
$vars[$var_name] = null;
if (
array_key_exists(0, $args)) {
if (
is_array($args[0])) {
$vars[$var_name] = $args[0];
} elseif (
is_string($args[0])) {
goto
main;
}
unset(
$args[0]);
}
main:
if (
$args) {
$args = array_reverse($args);
$cur_array = null;
array_walk($args, function ($value) use (&$cur_array, &$vars): void {
if (!
is_string($value)) {
$cur_array = $value;
} else {
$vars[$value] = $cur_array;
}
});
}
foreach (
$vars as $name => $array) {
if (!
array_key_exists($name, $array??$GLOBALS)) return false;
}
return
true;
}

// Examples
$arr1 = range(0, 5);
$arr2 = [
'a' => 1,
'b' => 2,
'c' => 'hELLO wORLD!'
];
$gender = 'male';
$age = 12;
var_dump(is_set('age')); // true
var_dump(is_set('age', null)); // true
var_dump(is_set('age', $arr1)); // false
var_dump(is_set('age', array())); // false
var_dump(is_set('age', array('age' => 48))); // true
var_dump(is_set('age', 'arr1', null, 'b', $arr2, 0, 3, 4, $arr1, 'gender')); // true
var_dump(is_set('age', 'arr1', null, 'b', $arr2, 0, 3, 4, $arr1, 'gender', null)); // true

$c=$d=$e=$a=2;
$arr = [1,4];
var_dump(is_set('a', 'c', null, 0, 1, $arr)); // true
var_dump(is_set('a', 'c', null, 0, 4, $arr)); // false
?>
Note
它不適用於在函式內部區域宣告的變數;
但是您可以使用它來檢查函式內部是否存在陣列鍵值
Anl zselgin
15 年前
注意:因為這是一個語言結構而不是一個函式,所以它不能使用可變函式來呼叫。

那麼為什麼它在「變數處理函式」之下呢?也許應該有一些好的文件欄位用於語言結構。
To Top