calling protected PHP_METHOD via call_user_function; missing context ??

From: Date: Tue, 30 Dec 2008 20:11:26 +0000
Subject: calling protected PHP_METHOD via call_user_function; missing context ??
Groups: php.pecl.dev 
Request: Send a blank email to pecl-dev+get-6026@lists.php.net to get a copy of this message
hi all, im new to php extension writing; but ive been working through my first one, which is completely object oriented, and ive hit a snag. normally, i can just grep through the other extensions to find the answer, but ive been unable to find anything similar. heres the grep cmd, where the directory is ext in the php source egrep -rn '^PHP_METHOD.*__construct\)$' ../ heres what im trying to replicate from userspace, public function __construct() { $this->subCommands = array(); $this->initializeMacroCommand(); } protected function initializeMacroCommand() { } and heres what ive got in the extension /* MacroCommand */ /* {{{ proto public void MacroCommand::__construct() Constructor. */ PHP_METHOD(MacroCommand, __construct) { zval *this, retval, *callback; zend_class_entry *this_ce; ZVAL_STRING(&method, "initializeMacroCommand", 0); this = getThis(); this_ce = zend_get_class_entry(this); array_init(return_value); /* create a callback so we have some context - still doesnt work =/ */ MAKE_STD_ZVAL(callback); array_init(callback); add_next_index_zval(callback, this); zval_add_ref(&this); add_next_index_string(callback, "initializeMacroCommand", 1); zend_update_property(this_ce, this, "subCommands", sizeof("subCommands")-1, return_value TSRMLS_CC); call_user_function(&this_ce->function_table, &this, callback, &retval, 0, (zval**)NULL TSRMLS_CC); zval_dtor(callback); } /* }}} */ /* {{{ proto protected void MacroCommand::initializeMacroCommand this is a hook method to be overriden by subclasses, which will be called by the constructor */ PHP_METHOD(MacroCommand, initializeMacroCommand) { } ... static function_entry puremvc_macrocommand_class_methods[] = { PHP_ME(MacroCommand, __construct, NULL, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC) * PHP_ME(MacroCommand, initializeMacroCommand, NULL, ZEND_ACC_PROTECTED)* { NULL, NULL, NULL } }; heres the phpt test --TEST-- MacroCommand::execute(), ensure calls to each commands execute methods are invokded --SKIPIF-- <?php if (!extension_loaded("pure_mvc")) print "skip"; ?> --FILE-- <?php class SubCommand { var $id = -1; public function __construct($id) { $this->id = $id; } public function execute() { echo $id . PHP_EOL; } } class MyNotification implements INotification { public function getName() {} public function getType() {} public function getBody() {} public function setName($name) {} public function setBody($body) {} public function setType($type) {} public function toString() {} } $subCmd1 = new SubCommand(1); $subCmd2 = new SubCommand(2); $macroCmd = new MacroCommand(); // < FATAL HERE /* $macroCmd->addSubCommand($subCmd1); $macroCmd->addSubCommand($subCmd2); $macroCmd->execute(new MyNotification()); */ echo '12'; ?> --EXPECT-- 12 which is encountering a fatal error, bash-3.2$ cat tests/testMacroCommandExecute.out Fatal error: Call to protected method MacroCommand::initializeMacroCommand() from context '' if i change the declaration of iniitializeMacroCommand to be public, it works. PHP_ME(MacroCommand, initializeMacroCommand, NULL, ZEND_ACC_PUBLIC) at first i was just passing a zval containing the string initializeMacroCommand, but then i switched to an array containing the zval from getThis() and another w/ the string initializeMacroCommand, but that didnt seem to have any effect. can someone steer me in the right direction, or give me some pointers on how to determine what im doing wrong? sorry for the long winded post, btw, i thought it best to be thorough. tia, -nathan

« previous php.pecl.dev (#6026) next »