Benbob
Benbob

Reputation: 14254

PHP closure scope problem

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.

Upvotes: 10

Views: 6482

Answers (3)

Savas Alp
Savas Alp

Reputation: 194

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;
}

Upvotes: -4

Knarf
Knarf

Reputation: 1273

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);

Upvotes: 0

zerkms
zerkms

Reputation: 254926

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

function($row) use ($pid) { ... }

Upvotes: 24

Related Questions