| 檢測目標 | 函式 | 參數 | 回傳值 | 注意事項 |
|---|---|---|---|---|
| 常數 | defined() | 字串 (常數名稱) | bool | 必須加引號:defined('MY_CONST') |
| 變數 | isset() | 變數 (可多個) | bool | 未宣告或 null 回傳 false;empty() 檢測「空值」 |
| 函式 | function_exists() | 字串 (函式名稱) | bool | 必須加引號;內建/使用者/擴充函式皆可檢測 |
<?php
// 1. 常數
if (defined('MY_CONSTANT')) {
echo MY_CONSTANT;
}
// 2. 變數
if (isset($myVar)) {
echo "變數存在: $myVar";
}
// 多變數同時檢測
if (isset($a, $b, $c)) { /* 全部存在 */ }
// 3. 函式
if (function_exists('imap_open')) {
imap_open(...);
} else {
echo "imap 擴充未安裝";
}
?>
filter_has_var() — 檢測特定輸入來源變數<?php
// 來源常數:INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV
if (filter_has_var(INPUT_GET, 'id')) {
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
}
?>
優點:同時驗證來源與過濾,比 isset($_GET['id']) 更安全。
property_exists() / method_exists() — 類別成員檢測<?php
class User {
public $name;
protected $email;
public function getName() {}
}
$obj = new User();
var_dump(property_exists($obj, 'name')); // true
var_dump(property_exists($obj, 'email')); // true (不受 visibility 影響)
var_dump(method_exists($obj, 'getName')); // true
var_dump(method_exists('User', 'getName')); // true (類別名也可)
?>
class_exists() / interface_exists() / trait_exists()<?php
if (class_exists('PDO')) {
$db = new PDO($dsn);
}
// 第三參數 $autoload = true (預設) 會觸發自動載入
// 僅檢測已載入類別:class_exists('MyClass', false)
?>
extension_loaded() — 擴充模組檢測<?php
if (extension_loaded('gd')) {
// 使用 GD 函式
}
?>
| 情境 | 錯誤寫法 | 正確寫法 | 原因 |
|---|---|---|---|
| 檢測常數 | if (MY_CONST) | if (defined('MY_CONST')) | 未定義常數會拋出 Warning 並視為字串 |
| 檢測變數是否為 0 | if (isset($var)) | if (isset($var) && $var !== '') 或 !empty($var) | isset(0) 為 true,empty(0) 為 true |
| 檢測函式 | if (my_func) | if (function_exists('my_func')) | 裸寫函式名會被視為常數 |
| 檢測類別方法 | method_exists($obj, 'method') | 同左 (正確) | 支援物件或類別名字串 |
<?php
function getConfig($key, $default = null) {
// 1. 環境變數
if (($val = getenv($key)) !== false) return $val;
// 2. 常數
if (defined($key)) return constant($key);
// 3. $_SERVER / $_ENV
if (isset($_SERVER[$key])) return $_SERVER[$key];
if (isset($_ENV[$key])) return $_ENV[$key];
return $default;
}
// 使用
$dbHost = getConfig('DB_HOST', 'localhost');
?>
<?php
// 常數
print_r(get_defined_constants(true)['user'] ?? []); // 僅使用者定義
// 函式
$funcs = get_defined_functions();
print_r($funcs['user']); // 使用者定義函式
// 類別
print_r(get_declared_classes());
?>
defined('NAME') — 必須加引號。isset($var) 存在且非 null;empty($var) 為空值 (0, '', null, false, [])。function_exists('name') — 必須加引號。class_exists(), interface_exists(), trait_exists()。filter_has_var(INPUT_TYPE, 'name') 搭配 filter_input() 更安全。extension_loaded('name')。掌握這組檢測函式,即可撰寫健壯的相容性判斷、優雅降級、條件載入邏輯。