Hello herrwitten,

  now i see your problem (at least i think i do).

the engine supports the following function types:
#define ZEND_INTERNAL_FUNCTION                          1
#define ZEND_USER_FUNCTION                                      2
#define ZEND_OVERLOADED_FUNCTION                        3
#define ZEND_EVAL_CODE                                          4
#define ZEND_OVERLOADED_FUNCTION_TEMPORARY      5

Only in case the function table holds an entry for ZEND_OVERLOADED_FUNCTION
or ZEND_OVERLOADED_FUNCTION_TEMPORARY the engine will call your call_method
handler. This allows for example to write an extension that wraps around
external (non php/zend) objects for which all methods can use the same
method call wrapper.

In case you want to implement things like handling non existing functions,
dynamic functions or handling aggregation or multiple inheritance and such
you should always use the get_method handler. If you look through the
extensions especially new ones like spl, pdo and language binding extensions
you'll find enough examples on how to use it.

regards
marcus
 
Saturday, July 2, 2005, 6:36:57 PM, you wrote:

> On Jul 2, 2005, at 12:07 PM, Marcus Boerger wrote:

>> i am quite sure your code is being called but it doesn't return a  
>> function
>> pointer but instead return 0. To the engine that means the function  
>> is not
>> available and hence it issues an error message. Maybe you want to  
>> provide
>> and empty function and execute that instead?

> To which function do you refer?

> By default, zend_std_get_method is called, and my understanding is  
> that if no method exists, the zend_class_entry is then checked for a  
> __call method, and if that doesn't exist, then NULL is returned, and  
> if NULL is returned, then the call_method handler is called.

> My tests show that indeed NULL is returned:

> zend_object_handles.c line 650:

> zobj = Z_OBJ_P(object);
> if (zend_hash_find(&zobj->ce->function_table, lc_method_name,  
> method_len+1, (void **)&fbc) == FAILURE) {
>      free_alloca(lc_method_name);
>      if (zobj->ce->__call) {
>          zend_internal_function *call_user_call = emalloc(sizeof 
> (zend_internal_function));
>          call_user_call->type = ZEND_INTERNAL_FUNCTION;
>          call_user_call->handler = zend_std_call_user_call;
>          call_user_call->arg_info = NULL;
>          call_user_call->num_args = 0;
>          call_user_call->scope = zobj->ce;
>          call_user_call->fn_flags = 0;
>          call_user_call->function_name = estrndup(method_name,  
> method_len);
>          call_user_call->pass_rest_by_reference = 0;
>          call_user_call->return_reference = ZEND_RETURN_VALUE;

>          return (union _zend_function *)call_user_call;
>      } else {
>          printf("get1\n");
>          return NULL;
>      }
> }

> "get1" is printed, however, nothing in my call_method function is  
> executed, even though other tests show it is indeed apart of the  
> handler array.

> This could only be because of the code I posted earlier, which makes  
> no use of the call_method handler:

> zend_vm_execute.h line 20655:

> EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object),  
> function_name_strval, function_name_strlen TSRMLS_CC);
> if (!EX(fbc)) {
>      zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s 
> ()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
> }

> If I am wrong, please excuse my misunderstanding.

> Herr Witten



-- 
Best regards,
 Marcus                            mailto:[EMAIL PROTECTED]

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to