Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

call_user_func and object context 1

Status
Not open for further replies.

ThomasJSmart

Programmer
Sep 16, 2002
634
What i am trying to do is the following:

i have a class A which instantiates another class then calls a function in that class with a param for the processing function.
This second class runs a complicated script that calls the passed processing function a few times.

the processing function in class A needs to store the result in a param in class A. once the function in class B is done, class A should continue and be able to access the result.

storing the var in the param is proving to be difficult though.

this doesnt work

Code:
class B{
 public function do_something($something){
  $data = 123;
  call_user_func($something, $data);
 }
}

class A{
 public $result = 0;
 
 public function start(){
  $b = new B();
  $b->do_something('A::process');
  
  echo $this->result;
 }
 
 public function process($data){
  $this->result = $data;
 }
 
}

$a = new A();
$a->start();

returns the error:
Fatal error: Using $this when not in object context on line 19


This doesnt work
Code:
class B{
 public function do_something($something){
  $data = 123;
  call_user_func($something, $data);
 }
}

class A{
 static public $result = 0;
 
 public function start(){
  $b = new B();
  $b->do_something('A::process');
  
  echo $this->result;
 }
 
 public function process($data){
  A::$result = $data;
 }
 
}

$a = new A();
$a->start();

the echo in start() doesnt print out anything

making all the functions in class A static works in this example but breaks in the actual application because of A being extended from other classes (and i'd rather not have to make the whole tree static... )

am i missing something here or do i need to find a completely different way of achieving what i want?

Thomas


site | / blog |
 
if you want to pass a public method of an object as a call back, usually I would do this

Code:
$b->do_something(array($this, 'process'));

the callback will automatically sort out the receiving array. you don't need to change the call_user_func at all.

i'm rarely comfortable with mixing static and dynamic methods. i prefer to use static methods only for factory classes or singletons. for other design patterns I think it's fair to say I will always explicitly instantiate an object as a variable before calling its class methods.
 
no probs.

you can also use call backs with uninstantiated objects
Code:
array('classname','method');
(this will implicitly create a new object. e.g. new A)

and (which was news to me) you can also call a method of a static class as from php 5.2.3.
Code:
array('classname','::method');

and from 5.3.0 you can use call_user_func with lambda functions too. not sure I see an immediate need for that, but might be useful someday.

 
does class::method work in a call back? I would not have thought that would be interpreted as a valid callback.

type 1 does this implicitly
Code:
$a = new a;
$a->method();

type 2 does this implicitly
Code:
a::method();

if you use type 1, the class constructors will fire and self referencing with $this etc will work. the same is not true of static classes of course.

note also that the classname can be passed as a string variable for these two methods.
 
by the way, in your post here:
i'd recommend testing for the file before including it. I can't remember the exact use case that hit me when I first started always including this test in my autoloaders. At a guess it could have been related to pear classes which typically use the include path to navigate themselves.

you may also have to clearstatcache() if there is a possibility that the file was created dynamically.

Code:
if(!is_file($file)) clearstatcache();
if(is_file($file)) require_once($file);
 
good points, in the app i was using this autoloader in i knew the files existed so didnt want to add overhead for file checking but for a more generic use that would indeed be a good idea.

i needed clearstatcache() the other day when doing unit tests >.< couldnt figure out why the next step of the test couldnt read the document the previous test just made!


site | / blog |
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top