1. 程式人生 > >php empty 函式判斷結果為空但實際值卻為非空的原因解析

php empty 函式判斷結果為空但實際值卻為非空的原因解析

最近我在一個專案中使用 empty 時獲取到了一些意料之外的結果。下面是我處理後的除錯記錄,在這裡與你分享了。

var_dump(
  $user->uid,
  empty($user->uid)
);

它的結果是:

string(5) "2955"
bool(true)

結果出人意料。為什麼變數的值為字串,但同時會是空值呢?讓我們在 $user->uid 變數上嘗試使用其它一些函式來進行判斷吧:

var_dump(
  $user->uid,
  empty($user->uid),
  isset($user->uid),
  is_null
($user->uid) );

以上結果為:

string(5) "2955"
bool(true) // empty
bool(false) // isset
bool(false) // is_null

is_null 函式執行結果符合預期判斷,empty和isset函式返回了錯誤結果。

這裡讓我們來看看 user類的實現程式碼吧:

class User
{  protected $attributes = [];
  public function __construct(array $attributes)
  {
    $this->attributes = $attributes
; } public function __get($name) { return $this->attributes[$name] ?? null; } }
 

從上述程式碼我們可以看到 Person 物件的成員變數是通過 __get 魔術方法從 $attributes 陣列中檢索出來的。

當將變數傳入一個普通函式時,$person->firstName 會先進行取值處理,然後再將獲取到的結果作為引數傳入函式內。

但是 empty 不是一個函式,而是一種語言結構。所以當將 $user->uid

傳入 empty時,並不會先進行取值處理。而是會先判斷 $user物件成員變數 uid的內容,由於這個變數並未真實存在,所以返回 false。

在正中應用場景下,如果你希望 empty 函式能夠正常處理變數,我們需要在類中實現 __isset 魔術方法。

class User
{
  protected $attributes = [];
  public function __construct(array $attributes)
  {
    $this->attributes = $attributes;
  }
  public function __get($name)
  {
    return $this->attributes[$name] ?? null;
  }
  public function __isset($name)
  {
    $attribute = $this->$name;
    return !empty($attribute);
  }
}
 

這是當 empty 進行控制判斷時,會使用這個魔術方法來判斷最終的結果。

再讓我們看看輸出結果:

var_dump(
  $user->uid,
  empty($user->uid)
);
 

新的檢測結果:

string(5) "2955"
bool(false)

 

1.什麼是語言結構
語言結構:就是PHP語言的關鍵詞,語言語法的一部分;它不可以被使用者定義或者新增到語言擴充套件或者庫中;它可以有也可以沒有變數和返回值。
2.語言結構執行速度快的原因
函式都要先被PHP解析器(Zend引擎)分解成語言結構,所以,函式比語言結構多了一層解析器解析,速度就相對慢了
3.php中語言結構有哪些

echo() 
print() 
die() 
isset() 
unset() 
include(),注意,include_once()是函式 
require(),注意,require_once()是函式 
array() 
list() 
empty() 

4.怎樣判斷是語言結構還是函式
使用function_exists
eg:

function check($name){
    if(function_exists($name)){
        echo $name.'為函式';
    }else{
        echo $name.'為語言結構';
    }
}
5.語言結構與函式的區別 
1.語言結構比對應功能的函式快 
2.語言結構在錯誤處理上比較魯棒,由於是語言關鍵詞,所以不具備再處理的環節 
3.語言結構不能在配置項(php.ini)中禁用,函式則可以。 
4.語言結構不能被用做回撥函式