Analysis of the Reason that the Judgment Result of php empty Function is Null but the Actual Value is Non null

  • 2021-10-15 09:54:56
  • OfStack

Recently, when I used empty in a project, I got some unexpected results. The following is my debugging record after processing, which I share with you here.


var_dump(
  $person->firstName,
  empty($person->firstName)
);

Its result is:

string(5) "Freek"
bool(true)

The result was unexpected. Why is the value of a variable a string, but at the same time it is a null value? Let's go to $person- > firstName variable try to use a few other functions to judge:


var_dump(
  $person->firstName,
  empty($person->firstName),
  isset($person->firstName),
  is_null($person->firstName)
);

The above results are:

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

There may be a problem with the results here. The results of isset are also false. You can run here to see the results.

The isset and is_null functions performed as expected, except that the empty function returned an incorrect result.

Here let's look at the implementation code of the person class:


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

From the above code, we can see that the member variables of the Person object are obtained from the __get magic method $attributes Retrieved from the array.

When a variable is passed into a normal function, $person->firstName The value will be processed first, and then the obtained results will be passed into the function as parameters.

But empty is not a function, but a data structure. So when the $person->firstName ** When **empty** is passed in, the value is not processed first. Instead, the content of the ** $person object member variable firstName is judged first, and since this variable does not really exist, false is returned.

In the middle application scenario, if you want the empty function to handle variables normally, we need to implement the __isset magic method in the class.


class Person
{
  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);
  }
}

This is when empty makes control judgment, it will use this magic method to judge the final result.

Let's look at the output again:


var_dump(
  $person->firstName, 
  empty($person->firstName)
);

New test results:

string(5) "Freek"
bool(false)

Summarize


Related articles: