16

Is it possible to access classes/objects reffered as self, static and $this in anonymous callbacks in PHP? Just like this:

class Foo {
    const BAZ = 5;
    public static function bar() {
         echo self::BAZ; // it works OK
         array_filter(array(1,3,5), function($number) /* use(self) */ {
             return $number !== self::BAZ; // I cannot access self from here
         });
    }
}

Is there any way to make it behave as with usual variables, using use(self) clause?

Pavel S.
  • 11,892
  • 18
  • 75
  • 113

3 Answers3

20

With PHP5.4 it will be. For now it's not possible. However, if you only need access to public properties, method

$that = $this;
function () use ($that) { echo $that->doSomething(); }

For constants there is no reason to not use the qualified name

function () { echo Classname::FOO; }
KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • 1
    Thanks for the answer. However, it's not possible to use Classname if I need to substitute static::FOO, i.e late binding. – Pavel S. Feb 25 '12 at 17:55
  • 1
    Sounds you are more looking for class properties (aka static properties), than constants. However, with the first example in my answer you should be able to call the constant like `$that::FOO`. – KingCrunch Feb 25 '12 at 18:09
  • Actually, I think to do what the OP wants with late binding it wouldn't it be: $that=static::FOO; – Tim Seguine Aug 27 '13 at 13:50
  • @Tim Closures are no objects (actually they are, but thats more an implementation detail and shouldn't concern you), so there is no `static` and `self`, but the last one can easily substituted with the concrete class name. `static` has very limited use anyway and you should think twice, if you _really_ need it. – KingCrunch Aug 28 '13 at 21:42
  • I think you misunderstood what I wanted to say. I realise all of the things you are saying. I was pointing out that your response to the OP's request for late static binding won't work. The solution would be to replace the first line of your first codeblock with $that=static::FOO; That will provide late static binding at the closure creation point, which is the best one can do in php 5.3 – Tim Seguine Sep 01 '13 at 16:03
  • @Tim I already understood. Please show me one case for `static::`, that is _not_ related to ORM, ActiveRecord or similar ;) Thats what I want to say: Actually there are no other use-cases, so this workaround does it as well, if you _really_ need it: `$class = get_class($this); $closure = function () use ($class) { echo $class::FOO; }`. Isn't that pretty, but you'll probably never see it anyway :D – KingCrunch Sep 02 '13 at 19:33
  • Ok, I guess I misunderstood your objection then. This is all code I would never write though anyway :) – Tim Seguine Sep 03 '13 at 07:31
4

Just use the standard way:

Foo::BAZ;

or

$baz = self::BAZ;
... function($number) use($baz) {
   $baz;
}
dynamic
  • 46,985
  • 55
  • 154
  • 231
2

What about this:

class Foo {
    const BAZ = 5;
    $self = __class__;
    public static function bar() {
         echo self::BAZ; // it works OK
         array_filter(array(1,3,5), function($number) use($self) {
             return $number !== $self::BAZ; // access to self, just your const must be public
         });
    }
}
Bugs
  • 4,491
  • 9
  • 32
  • 41
Gosha Lem
  • 21
  • 1