17

I have Repository class with a method as follows:

public function GetOne($id){
    $method = __METHOD__;
    $post = null;


    $post = $this->CacheManager($method, function($id) {
        return DB::select("select * from posts where id = ?", [$id]);
    });

    return $post;
}

I want to cache the result, but in the closure/callback function the $id parameter is not working. The CacheManager is a trait where I'm using it in my repository.

public function CacheManager($method, $fn) {
  $obj = null;

  if(!$this->HasCache($method)){
    $obj = $fn();
  }else {
    $obj = $this->GetCache($method);
  }

  return $obj;
}

I have some other methods without parameters and they're working as intended.

1
  • Well, you never passed the $id to CacheManager nor did you pass it to $fn();. You need to pass the arguments as well. Commented Jan 27, 2016 at 10:57

2 Answers 2

51

Use use. :D

With the use clause, you can import variables from the parent scope into the scope of the function.

public function GetOne($id){
    $method = __METHOD__;
    $post = null;


    $post = $this->CacheManager($method, function() use ($id) {
        return DB::select("select * from posts where id = ?", [$id]);
    });

    return $post;
}

Just a side note. Since it looks you are building a caching mechanism, you will need to include the ID in the cache as well. Currently you only check by $method, but for each id you will probably have a different cache entry which may or may not exist. So I think in your function you need to do something like the line below to make the cache key more unique. I would also call the parameter $method something like $cacheKey instead, since to the cache it shouldn't be linked to a method name per se.

$method = __METHOD__ . ";$id";

Update for PHP 7.4: arrow functions

The RFC for arrow functions (AKA 'short closures') has passed voting.

With these you don't specify the parameters you want to close in, because they can only have a single expression anyway, so any expression/value they use can (and will) be taken from the parent function scope.

Since in this case the anonymous function just has a single statement, it can be rewritten into an arrow function. The call to the cache manager will then look like this:

public function GetOne($id){
    $method = __METHOD__;
    $post = null;

    $post = $this->CacheManager($method, fn() => DB::select("select * from posts where id = ?", [$id]));

    return $post;
}
Sign up to request clarification or add additional context in comments.

Comments

0

$fn() needs an argument ...

if(!$this->HasCache($method)){
    $obj = $fn($id);
}

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.