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

PHP 存取控制與運算子優先級陷阱:從類屬性可見性到賦值運算子短路求值

     編輯:PHP 相關知識

一、存取控制:public、protected、private 實戰差異

PHP 類成員的可見性控制嚴格遵循「封裝」原則:

  • public:任何位置可存取 (物件外部、子類、父類、自身)。
  • protected:僅限類本身、繼承的子類、父類 存取。外部物件不可直接存取。
  • private:嚴格限定於定義該屬性/方法的類內部。子類不可存取父類的 private 成員,甚至子類定義同名屬性也不會覆寫,而是各自獨立存在。

經典案例:private 不參與繼承覆寫

<?php
class Foo {
    private $name = 'hdj';
    public function getName() { return $this->name; }
}

class Bar extends Foo {
    public $name = 'deeka'; // 這是 Bar 自己的 public 屬性,非覆寫
}

$bar = new Bar;
var_dump($bar->name);      // string(5) "deeka"  -> 存取 Bar::\$name (public)
var_dump($bar->getName()); // string(3) "hdj"    -> Foo::getName() 內部存取 Foo::\$name (private)
?>

輸出結果證明:Foo::$name (private) 與 Bar::$name (public) 是兩個獨立儲存空間。getName() 定義在 Foo 中,其 $this->name 永遠綁定 Foo::$name,不受子類同名屬性影響。

二、運算子優先級陷阱:賦值 (=) vs 邏輯運算 (||, &&)

PHP 運算子優先級 (高到低) 關鍵片段:

&& (邏輯與)  >  || (邏輯或)  >  = (賦值)  >  and / or / xor

核心規則:$a = 5 || $b = 7 等價於 $a = (5 || $b = 7)。賦值運算子優先級 低於 邏輯運算子。

案例逐步推演

案例 1:單一 ||

<?php
$a = 3; $b = 6;
if ($a = 5 || $b = 7) { // 解析:$a = (5 || ($b = 7))
    // 5 為 truthy,短路求值,\$b=7 不執行
    echo $b . '<br/>'; // 輸出 6 (原值)
    $a++; $b++;
}
var_dump($a, $b); // int(2) int(7)
// 解析:\$a = (true) -> \$a=1 (bool true 轉 int) -> \$a++ -> 2
// \$b 未在 if 內賦值,僅 \$b++ -> 7
?>

案例 2:&& 優先於 ||

<?php
$a = 3; $b = 6; $c = 1;
if ($a = 5 || $b = 7 && $c = 10) { // 解析:$a = (5 || (($b = 7) && ($c = 10)))
    // 5 為 truthy,短路,&& 右側不執行
    $a++; $b++;
}
var_dump($a, $b, $c); // int(2) int(7) int(1)
// \$a = true -> 1 -> ++ -> 2
// \$b, \$c 均未賦值,僅 \$b++ -> 7
?>

案例 3:左側為 false 觸發右側鏈

<?php
$a = 3; $b = 6; $c = 1;
if ($a = 0 || $b = 7 && $c = 10) { // 解析:$a = (0 || (($b = 7) && ($c = 10)))
    // 0 為 falsy,執行右側:\$b=7 (truthy) -> 執行 \$c=10 (truthy) -> 整體 true
    $a++; $b++;
}
var_dump($a, $b, $c); // int(2) int(8) int(10)
// \$a = true -> 1 -> ++ -> 2
// \$b = 7 -> ++ -> 8
// \$c = 10
?>

三、避坑黃金法則

  1. 條件判斷嚴禁使用賦值運算子:改用比較運算子 ==/===。if (($a = 5) || ...) 雖合法但極易誤讀。
  2. 必要時用括號明確分組:if (($a = foo()) || ($b = bar())) 明確表達意圖。
  3. 利用 and/or 低優先級特性 (慎用):$a = 5 or $b = 7 等價 ($a = 5) or ($b = 7)。但此寫法違反主流編碼規範 (PSR-12 等),不推薦。
  4. 靜態分析工具輔助:PHPStan / Psalm 會針對「條件中的賦值」發出警告。

總結

  • 存取控制:private 實現「類級封裝」,子類擁有同名屬性屬「遮蔽」而非「覆寫」。
  • 運算子優先級:&& > || > =。條件表達式中混用賦值與邏輯運算極高風險,堅決杜絕,改用明確比較與括號。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved