12

I have a class in PHP like this:

class RandomNumberStorer{

     var $integers = [];

     public function store_number($int){
         array_push($this->integers, $int);
     }

     public function run(){
         generate_number('store_number');
     }
}

...elsewhere I have a function that takes a function as a parameter, say:

function generate_number($thingtoDo){ 
     $thingToDo(rand());
}

So I initialise a RandomNumberStorer and run it:

$rns = new RandomNumberStorer();
$rns->run();

And I get an error stating that there has been a 'Call to undefined function store_number'. Now, I understand that that with store_number's being within the RandomNumberStorer class, it is a more a method but is there any way I can pass a class method into the generate_number function?

I have tried moving the store_number function out of the class, but then I then, of course, I get an error relating to the reference to $this out of the context of a class/ instance.

I would like to avoid passing the instance of RandomNumberStorer to the external generate_number function since I use this function elsewhere.

Can this even be done? I was envisaging something like:

 generate_number('$this->store_number')
Jon
  • 2,280
  • 2
  • 25
  • 33
  • 1
    Try: `generate_number(array($this, 'store_number'))` – elclanrs Sep 09 '13 at 21:49
  • @elclanrs It worked! No idea why. How does `generate_number` know what to do with an array? – Jon Sep 09 '13 at 21:52
  • It's a PHP feature, check answer below, has good explanation. – elclanrs Sep 09 '13 at 21:57
  • Apart from being a dupe, why would a RandomDataStorer have a method run? Either your class stores RandomNumbers, which makes it a Collection/Array data type of thing. Or it generates numbers, which makes it a Service kind of thing. Why would it do both? This seems to be much more a design problem than anything else. – Gordon Sep 09 '13 at 22:00

1 Answers1

16

You need to describe the RandomNumberStore::store_number method of the current instance as a callable. The manual page says to do that as follows:

A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1.

So what you would write is:

generate_number([$this, 'store_number']);

As an aside, you could also do the same in another manner which is worse from a technical perspective, but more intuitive:

generate_number(function($int) { $this->store_number($int); });
Jon
  • 428,835
  • 81
  • 738
  • 806