首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP Null 合併運算子 (??) 與 ?: 短三元運算子深度解析

     編輯:PHP 綜合知識

痛點:PHP 缺乏 JS 的 || 預設值寫法

// JS 寫法
function setSomething(a){ a = a || 'default'; }

// PHP || 永遠返回 bool,無法直接賦值

PHP 7.0 正式引入 ??(Null Coalescing Operator)

$username = $_GET['user'] ?? 'nobody';
// 等價於
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
  • 僅判斷 isset()(非 null 且已定義)
  • 可鏈式:$x = $_GET['a'] ?? $_POST['a'] ?? 'default';
  • 不會觸發 Undefined index Notice

PHP 5.3+ 替代方案:?:(Elvis Operator / 短三元)

$username = @$_GET['user'] ?: 'nobody';
// 等價於
$username = $_GET['user'] ? $_GET['user'] : 'nobody';

關鍵差異:

運算子判斷條件Notice 風險適用版本
??isset()(非 null 且存在)無PHP 7.0+
?:boolval()(真值)若變數未定義需 @ 抑制PHP 5.3+

陷阱對比

$_GET['user'] = '';
// ?? 視為「已設定但為空字串」 → 返回 ''
// ?: 視為「假值」 → 返回 'nobody'

$_GET['user'] = '0';
// ?? 返回 '0'
// ?: 返回 'nobody'  (因 '0' 在 PHP 中為 false)

最佳實踐建議

  1. PHP 7.1+ 專案:全面使用 ??,語義精確且無 Notice。
  2. PHP 5.6/7.0 維護專案:@$_GET['key'] ?: 'default' 並關閉 E_NOTICE 或統一封裝 helper 函數。
  3. 嚴格區分「未傳遞」與「傳遞空值」:需用 isset() 或 array_key_exists() 顯式判斷,不要依賴 ?:。
  4. 封裝通用獲取函數:
    function input($key, $default = null, $source = 'GET') {
            $arr = $_GET; if($source==='POST') $arr = $_POST;
            return $arr[$key] ?? $default; // PHP 7
            // return @$arr[$key] ?: $default; // PHP 5
        }

原理補充:短三元 expr1 ?: expr3

官方文檔定義:expr1 ?: expr3 在 expr1 為 TRUE 時返回 expr1,否則返回 expr3。本質是 (expr1) ? (expr1) : (expr3) 的語法糖。

總結

?? 是為「預設值」而生的現代運算子,?: 是歷史相容的「真值判斷」縮寫。根據 PHP 版本與業務語義選擇,並統一封裝輸入獲取層,避免分散在業務代碼中產生不一致行為。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved