PHP Error: Base class function calls derived class -
i writing api in php. have got base class implemets magic function __call
:
class controller { public function __call($name, $arguments) { if(!method_exists($this,$name)) return false; else if(!$arguments) return call_user_func(array($this,$name)); else return call_user_func_array(array($this,$name),$array); } }
and child class this:
class child extends controller { private function test() { echo 'test called'; } }
so when this:
$child = new child(); $child->test();
and load page takes lot of time , after while web browser prints page can't requested. no output given php, web browser error.
apache error log (last part only):
... [tue sep 24 12:33:14.276867 2013] [mpm_winnt:notice] [pid 1600:tid 452] ah00418: parent: created child process 3928 [tue sep 24 12:33:15.198920 2013] [ssl:warn] [pid 3928:tid 464] ah01873: init: session cache not configured [hint: sslsessioncache] [tue sep 24 12:33:15.287925 2013] [mpm_winnt:notice] [pid 3928:tid 464] ah00354: child: starting 150 worker threads. [tue sep 24 12:38:43.366426 2013] [mpm_winnt:notice] [pid 1600:tid 452] ah00428: parent: child process exited status 3221225725 -- restarting. [tue sep 24 12:38:43.522426 2013] [ssl:warn] [pid 1600:tid 452] ah01873: init: session cache not configured [hint: sslsessioncache]
i can't find mistake, if function test protected works fine.
solution found:
public function __call($name, $arguments) { if(!method_exists($this,$name)) return false; $meth = new reflectionmethod($this,$name); $meth->setaccessible(true); if(!$arguments) return $meth->invoke($this); else return $meth->invokeargs($this,$arguments); }
this behavior issue (bug?) documented in documentation of method_exists()
: method_exists()
returns true if method private/protected , thus, not accessible outside class. leads infinite recursion in case, child->test()
call invokes child::__call()
, checks whether test()
exists (it does, can't called), tries call it, again leeds __call()
being invoked. comments suggest using get_class_methods()
might resolve issue. i'm not sure why changing visibility of test()
private
changes behavior stated.
Comments
Post a Comment