Possible to implement object handling of empty()
Asked Answered
U

4

6

I know we can implement PHP's countable interface to determine how the function count() works as well as the Iterator interface for using an object like an array.

Is it possible to implement some kind of interface (or any other way) to change the behavior of empty() on an object?

Essentially, this is what I would like to be able to do:

<?php
class test {
    function __empty() {
        if (count($this->data) > 0) {
            return false;
        }
        return true;
    }
}

Just a nice to have!

Ungotten answered 28/1, 2013 at 18:48 Comment(3)
"change the behavior of empty()" no, write your own function called MY_empty() - yesBroch
I kind of figured there wasn't, but i'm not sure I understand why PHP wouldn't have implemented this. I'd think this would be a pretty simple implementation. All classes have __empty method, extended classes extend this. Especially since PHP revamped it so empty will always be false on an object.Ungotten
well feel free to write your own version of php to do this :-)Broch
H
4

No. PHP does not have it. You can request for such feature on wiki.php.net. In the meantime you can roll your own.

interface Empty_Checkable{
   function isempty();
}

class test implements Empty_Checkable{
    function isempty() {
        if (count($this->data) > 0) {
            return false;
        }
        return true;
    }
}
Hero answered 28/1, 2013 at 18:54 Comment(2)
You need to have access on that page. Find someone who have access or raise the issue in #php-internal irc channel or mailing list.Hero
By the way, proposing such a feature will likely be voted 'no' by the core devs. This is unfortunate as I have a library in-progress that would benefit from this extension.Naphtha
T
5

No there is not. The iterator behavior and count behaviors have no sense over an object; that's why you can override them. The default behavior of empty() applied to an object has a meaning instead: is it an instance of an object or is it NULL?; that's why you can't override it.

You can instead:

  • create a method inside the object called isEmpty() and implement it there
  • create a global function emptyObj() and implement it there
Travail answered 28/1, 2013 at 18:54 Comment(9)
You can also write you own function is_empty() implementing of what is empty or not in your eyes and then use that instead of PHP's version of empty().Feininger
@Feininger The problem is that you will receive warnings for the ones that aren't defined.Ungotten
@Tom, you can always check if it's isset before checking it its empty. Also with the latter solution you can make it so it does not trigger warnings.Travail
@Jeffrey, one of the key points of empty is it checks isset. If I have to call isset then my own empty function... We are making it more difficult for ourselves. Calling isset inside of your user defined function is pointless.Ungotten
@Tom, then why do you want to override it since empty() already does what you are asking for?Travail
@Jeffrey, the point is that all objects according to empty() are not empty. The point of the question is to extend empty() so that objects can be determined using a magic method or interface method. And if you mean to implement it like this: function is_empty($var) { if (!isset($var)) return true; } if (is_empty($object)) echo "empty"; a warning will appear.Ungotten
@Tom Well, either you are clearly not understanding what my idea is or I'm not understanding your problem; in both ways nobody cares if one understands the other since your problem was solved. Have a nice day.Travail
@Jeffrey, if you run the code I posted in the comment, you'll see that you get an undefined error. My goal is to call empty on any variable. If the variable is an object and has a method for example of __empty, it will request that method instead.Ungotten
I would argue that the meaning you're attributing to empty actually is what's isset is for (or is_null). empty has additional/custom meaning depending on what type of variable it is applied to. So, if one is defining their own type, it would make perfect sense to be able to override empty as well.Genic
H
4

No. PHP does not have it. You can request for such feature on wiki.php.net. In the meantime you can roll your own.

interface Empty_Checkable{
   function isempty();
}

class test implements Empty_Checkable{
    function isempty() {
        if (count($this->data) > 0) {
            return false;
        }
        return true;
    }
}
Hero answered 28/1, 2013 at 18:54 Comment(2)
You need to have access on that page. Find someone who have access or raise the issue in #php-internal irc channel or mailing list.Hero
By the way, proposing such a feature will likely be voted 'no' by the core devs. This is unfortunate as I have a library in-progress that would benefit from this extension.Naphtha
P
3

This is not possible on the object directly.

If you need to do it, I would suggest implementing the Countable interface, and then instead of calling empty($foo), call count($foo) == 0...

However, for properties, it is possible using a combination of two magic methods: __isset and __get. For example:

class Foo {
    protected $bar = false;
    protected $baz = true;
    public function __get($key) {
        return $this->$key;
    }
    public function __isset($key) {
        return isset($this->$key);
    }
}

That results in:

empty($foo->abc); // true, isset returns false
empty($foo->bar); // true, isset returns true, but get returns false value
empty($foo->baz); // false, isset returns true, and get returns a true value

So no, it's not possible with a single method handler, but with the combination of the two magic methods, it works fine...

Professionalism answered 28/1, 2013 at 19:48 Comment(1)
This makes sense, but I'm not sure I see the point of implementing __get or __isset for properties since isset or empty works just fine without those methods.Ungotten
L
1

It is possible to implement Countable

class MyCollection extends stdClass implements Serializable, ArrayAccess, Countable, Iterator, JsonSerializable
{
    public function count() {
        return count($this->array);
    }
}

and use !count() instead of empty() like

if (!count($myList)) {
    echo "List is empty!";
}
Leonelleonelle answered 19/10, 2017 at 12:45 Comment(2)
This is exactly how the OP started the question: "I know we can implement PHP's countable interface [...]".Patchy
That's true, but it is still, how I know, the best solution anyway.Leonelleonelle

© 2022 - 2024 — McMap. All rights reserved.