1

I was looking into implementing a collection class into my PHP application, however, I had some questions about using the class.

I am basing some of my methods on the Laravel Collection Class (https://laravel.com/docs/5.2/collections).

If I am using the .each method:

public function each($callback)
{
    foreach ($this->items as $key => $item) {
        if ($callback($item, $key) === false) {
            break;
        }
    }

    return $this;
}

How can I use non-local variables in the callback? For example, I have a courses collection and a users collection.

$courses = new Collection($this->getCourses());
$users = new Collection($this->getUsers());

// I need to loop through all courses and within each course, loop through   
// all users
$courses->each(function($course, $courseKey) {

    // How can I make it so $users is available here?

    $users->each(function($user, $userKey) {

        // How can I make it so $course is available here?

        // ...
    });
});

Is what I am trying to accomplish a bad practice? Should I use the global keyword or is that also bad practice?

Sean
  • 1,758
  • 3
  • 20
  • 34

1 Answers1

1

Look into this manual entry. What you are looking to do is to create a closure around your variables (the manual uses the phrase 'inherit variables from the parent scope'). Something like this ought to work for you:

$courses = new Collection($this->getCourses());
$users = new Collection($this->getUsers());

$courses->each(function($course, $courseKey) use($users) {

    // $users is now available in this scope

    $users->each(function($user, $userKey) use($course) {

        // $course is now available in this scope

    });
});

You do not need to use the global keyword, because it will specifically refer to variables that exist in the global scope, which I doubt your variables actually are (if they're declared within a function, or class, they aren't global). Relevant quote from the manual:

Inheriting variables from the parent scope is not the same as using global variables. Global variables exist in the global scope, which is the same no matter what function is executing. The parent scope of a closure is the function in which the closure was declared (not necessarily the function it was called from).

Jeff Lambert
  • 24,395
  • 4
  • 69
  • 96
  • That's what I was looking for. What versions of PHP is the use() syntax available. For this specific application, I am stuck on PHP 5.3.3 so I just wanted to make sure. – Sean May 18 '16 at 17:53
  • Not quite sure offhand, but I believe anonymous functions became available in 5.3, so I think this should be as well. I'll try and double check – Jeff Lambert May 18 '16 at 17:55
  • I tested it in PHP 5.3.3 and it worked. – Sean May 18 '16 at 18:41
  • @Sean the manual isn't specific about `use` itself, but the two different areas that keyword is meaningful (namespaces and anonymous functions) were both introduced in 5.3. Glad you got it working. – Jeff Lambert May 18 '16 at 18:54