<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML ><HEAD ><TITLE >Calling User Functions</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" TITLE="Manual PHP" HREF="index.html"><LINK REL="UP" TITLE="Zend API" HREF="zend.html"><LINK REL="PREVIOUS" TITLE="Startup and Shutdown Functions" HREF="zend.startup-and-shutdown.html"><LINK REL="NEXT" TITLE="Initialization File Support" HREF="zend.ini-file-support.html"><META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=ISO-8859-2"></HEAD ><BODY CLASS="chapter" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#840084" ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" >Manual PHP</TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="zend.startup-and-shutdown.html" ACCESSKEY="P" >Înapoi</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" ></TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="zend.ini-file-support.html" ACCESSKEY="N" >Înainte</A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="chapter" ><H1 ><A NAME="zend.calling-user-functions" >Cap. 40. Calling User Functions</A ></H1 ><P > You can call user functions from your own modules, which is very handy when implementing callbacks; for example, for array walking, searching, or simply for event-based programs. </P ><P > User functions can be called with the function <B CLASS="function" >call_user_function_ex()</B >. It requires a hash value for the function table you want to access, a pointer to an object (if you want to call a method), the function name, return value, number of arguments, argument array, and a flag indicating whether you want to perform zval separation. </P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" CELLPADDING="5" ><TR ><TD ><PRE CLASS="programlisting" >ZEND_API int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval **retval_ptr_ptr, int param_count, zval **params[], int no_separation);</PRE ></TD ></TR ></TABLE ><P > Note that you don't have to specify both <VAR CLASS="envar" >function_table</VAR > and <VAR CLASS="envar" >object</VAR >; either will do. If you want to call a method, you have to supply the object that contains this method, in which case <B CLASS="function" >call_user_function()</B >automatically sets the function table to this object's function table. Otherwise, you only need to specify <VAR CLASS="envar" >function_table</VAR > and can set <VAR CLASS="envar" >object</VAR > to <VAR CLASS="literal" >NULL</VAR >. </P ><P > Usually, the default function table is the "root" function table containing all function entries. This function table is part of the compiler globals and can be accessed using the macro <VAR CLASS="literal" >CG</VAR >. To introduce the compiler globals to your function, call the macro <VAR CLASS="literal" >TSRMLS_FETCH</VAR > once. </P ><P > The function name is specified in a <VAR CLASS="envar" >zval</VAR > container. This might be a bit surprising at first, but is quite a logical step, since most of the time you'll accept function names as parameters from calling functions within your script, which in turn are contained in <VAR CLASS="envar" >zval</VAR > containers again. Thus, you only have to pass your arguments through to this function. This <VAR CLASS="envar" >zval</VAR > must be of type <VAR CLASS="literal" >IS_STRING</VAR >. </P ><P > The next argument consists of a pointer to the return value. You don't have to allocate memory for this container; the function will do so by itself. However, you have to destroy this container (using <B CLASS="function" >zval_dtor()</B >) afterward! </P ><P > Next is the parameter count as integer and an array containing all necessary parameters. The last argument specifies whether the function should perform zval separation - this should always be set to <VAR CLASS="literal" >0</VAR >. If set to <VAR CLASS="literal" >1</VAR >, the function consumes less memory but fails if any of the parameters need separation. </P ><P > <A HREF="zend.calling-user-functions.html#example.call-user-func" >Exemplu 40-1</A > shows a small demonstration of calling a user function. The code calls a function that's supplied to it as argument and directly passes this function's return value through as its own return value. Note the use of the constructor and destructor calls at the end - it might not be necessary to do it this way here (since they should be separate values, the assignment might be safe), but this is bulletproof. </P ><TABLE WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" CLASS="EXAMPLE" ><TR ><TD ><DIV CLASS="example" ><A NAME="example.call-user-func" ></A ><P ><B >Exemplu 40-1. Calling user functions.</B ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" CELLPADDING="5" ><TR ><TD ><PRE CLASS="programlisting" >zval **function_name; zval *retval; if((ZEND_NUM_ARGS() != 1) || (zend_get_parameters_ex(1, &function_name) != SUCCESS)) { WRONG_PARAM_COUNT; } if((*function_name)->type != IS_STRING) { zend_error(E_ERROR, "Function requires string argument"); } TSRMSLS_FETCH(); if(call_user_function_ex(CG(function_table), NULL, *function_name, &retval, 0, NULL, 0) != SUCCESS) { zend_error(E_ERROR, "Function call failed"); } zend_printf("We have %i as type<br>", retval->type); *return_value = *retval; zval_copy_ctor(return_value); zval_ptr_dtor(&retval);</PRE ></TD ></TR ></TABLE ></DIV ></TD ></TR ></TABLE ><P ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" CELLPADDING="5" ><TR ><TD ><PRE CLASS="programlisting" ><?php dl("call_userland.so"); function test_function() { print("We are in the test function!<br>"); return("hello"); } $return_value = call_userland("test_function"); print("Return value: \"$return_value\"<br>"); ?></PRE ></TD ></TR ></TABLE ><P ><IMG SRC="figures/Extending_Zend_11_userland.png"></P ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="zend.startup-and-shutdown.html" ACCESSKEY="P" >Înapoi</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="index.html" ACCESSKEY="H" >Acasã</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="zend.ini-file-support.html" ACCESSKEY="N" >Înainte</A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Startup and Shutdown Functions</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="zend.html" ACCESSKEY="U" >Sus</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >Initialization File Support</TD ></TR ></TABLE ></DIV ></BODY ></HTML >