10

Apparently $pid is out of scope here. Shouldn't it be "closed" in with the function? I'm fairly sure that is how closures work in javascript for example.

According to some articles php closures are broken, so I cannot access this?

So how can $pid be accessed from this closure function?

class MyClass {
  static function getHdvdsCol($pid) {
    $col = new PointColumn();
    $col->key = $pid;
    $col->parser = function($row) {
        print $pid; // Undefined variable: pid
    };
    return $col;
  }
}

$func = MyClass::getHdvdsCol(45);
call_user_func($func, $row);

Edit I have gotten around it with use: $col->parser = function($row) use($pid). However I feel this is ugly.

5
  • 4
    It is not ugly, it is how closures work in php Commented Jul 1, 2011 at 3:56
  • that's just how it is in php so.. Commented Jul 1, 2011 at 3:57
  • It's an ugly language, but I'm stuck with it. :( Commented Jul 1, 2011 at 4:00
  • It becomes less and less ugly every day. (: Commented Aug 7, 2011 at 6:09
  • 1
    From PHP 5.4 you can access $this within the closure. Commented Jun 28, 2012 at 21:41

3 Answers 3

24

You need to specify which variables should be closed in this way:

function($row) use ($pid) { ... }
Sign up to request clarification or add additional context in comments.

4 Comments

If this closure is saved in a variable and then passed to another scope where $pid does not exist, will pid be wrapped in the closure somehow, or not accessible?
@Josh Nankin: actually use($var,...) is how closures are implemented in php. So if you pass the anonymous function to another variable scope - the $pid variable will contain the last defined value.
Does this "use" thingy feel just weird or is it just me? I just can't get over it after using closures in other languages. :/
@Matjaz Muhic: yep, it's weird for everyone not just you
0

You can use the bindTo method.

class MyClass {
  static function getHdvdsCol($pid) {
    $col = new PointColumn();
    $col->key = $pid;
    $parser = function($row) {
        print $this->key;
    };
    $col->parser = $parser->bindTo($parser, $parser);
    return $col;
  }
}

$func = MyClass::getHdvdsCol(45);
call_user_func($func, $row);

Comments

-4

I think PHP is very consistent in scoping of variables. The rule is, if a variable is defined outside a function, you must specify it explicitly. For lexical scope 'use' is used, for globals 'global' is used.

For example, you can't also use a global variable directly:

$n = 5;

function f()
{
    echo $n; // Undefined variable
}

You must use the global keyword:

$n = 5;

function f()
{
    global $n;
    echo $n;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.