0

I've written my own ORM that returns user objects from an MySQL DB.

I've got this weird glitch with empty to check a returned value. Essentially, I need to print 'Yes' or 'No' based on the value. Very simple.

<?=( empty($user->flagOnUnemploymentStatusAllowance) ) ? 'No' : 'Yes' ?>

Nothing crazy there. However, regardless of the value returned from DB, it always prints 'No'. Turns out empty() is always returning TRUE, even though the variable is NOT empty :

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

// returns string(1) "1" bool(true)

The possible returned values are "0" or "1", as strings. What am I doing wrong here ? I can always change my empty() with a test flagOnUnemploymentStatusAllowance == '0', but find this stupid when empty() should do it, and catch nulls as well.

Thanks.

EDIT 1: Solution ? Since the properties are fetched with magic getters : I added the following function to my ORM Base class (where my magic lives):

public function __isset(string $property){
  return empty($this->entity[$property]['value']) ? 'true' : 'false';
}

For some reasons, I must be tired, I had to use a ternary operator to force a STRING value of true / false ... It now seems to work if I try empty($user->flagOnUnemploymentStatusAllowance), BUT I don't understand it at all here! Can anyone shed a light on this one!?

Pat
  • 449
  • 1
  • 4
  • 14
  • For the empty() function 0 was an empty value – Inazo Sep 16 '20 at 09:30
  • You shouldn't needlessly use `empty` if you expect your variable/attribute to be defined in the first place. Is your `$user` object something special, perhaps using magic getters…? – deceze Sep 16 '20 at 09:31
  • Yes, it's using magic getters. – Pat Sep 16 '20 at 09:32
  • Well, there's your issue. You should read the manual page for magic methods again in detail: https://www.php.net/manual/en/language.oop5.overloading.php#object.get – deceze Sep 16 '20 at 09:34
  • and that's the thing, my test case had a value of "1", which means empty() should return FALSE. But regardless, its always returning TRUE. I had based myself on the doc from : https://www.php.net/manual/en/function.empty.php, and this should work for what I needed.... – Pat Sep 16 '20 at 09:34
  • Because the property doesn't "really" exist per say (it's fetched through a magic getter), then empty thinks it's empty, since it doesn't "really" exists ? – Pat Sep 16 '20 at 09:37
  • [Yes.](https://stackoverflow.com/a/6241155/476) – deceze Sep 16 '20 at 09:38
  • You want `return !empty(...);` in your `__isset`…!? But really, you shouldn't evaluate the "emptiness" of the value in `__isset`, you should just return whether the value itself exists. So something like `return array_key_exists($property, $this->entity)`. – deceze Sep 16 '20 at 10:05
  • 1
    Why do you want to use `empty` on a flag? Shouldn't that return a **clear** `true` or `false` state? – Nico Haase Sep 16 '20 at 15:56
  • Essentially, when I do a `empty($tableObject->someMagicColumn)`, I needed to check if VALUE inside my column is neither NULL, 0, "0", "" or FALSE. So, make it act as empty() itself! To do so, my final __isset() function has only this : `return ( empty($this->entity[$property]['value'] ) == false );`, where $property is a column name. Cheers. – Pat Sep 17 '20 at 12:40
  • You're doing it wrong. When using `empty` on a magic getter, it will first call `__isset` to determine if the property supposedly exists at all, and then do another call to `__get` to evaluate its value truthy or falsey. Your `__isset` call must *not* include both those steps. `__isset` must only return `true` or `false` based on whether that attribute exists at all. I assume in your case that would mean `return array_key_exists($property, $this->entity)`, nothing more. If you're not sticking to that expectation, you will get weird problems down the line (e.g. failing `isset` checks). – deceze Sep 17 '20 at 12:48

0 Answers0