Calling PHP functions from an extension

php.internals

John Lim

22 years ago
Hi, I am using call_user_function_ex() to call mysql_fetch_array, ocifetchinto, etc. error = call_user_function_ex(EG(function_table), NULL, &function_name_zval, &retval, 2, &params[1], 0, NULL TSRMLS_CC); This is not giving me the performance I am looking for because the Zend Engine still has to search for the function to call. Is there any way to get a function pointer to mysql_fetch_array/ocifetchinto etc., and call the function directly ? Thanks in advance.

George Schlossnagle

22 years ago
On Jul 22, 2004, at 7:17 AM, John Lim wrote:
> Hi, > > I am using call_user_function_ex() to call mysql_fetch_array, > ocifetchinto, > etc. > > error = call_user_function_ex(EG(function_table), > NULL, > &function_name_zval, > &retval, 2, &params[1], 0, NULL TSRMLS_CC); > > This is not giving me the performance I am looking for because the Zend > Engine > still has to search for the function to call. Is there any way to get > a > function > pointer to mysql_fetch_array/ocifetchinto etc., and call the function > directly ?
If performance is your concern, why not simply call the various RDBMS API functions directly? George

John Lim

22 years ago
Hi George, 2 reasons. High learning curve to learn all client API's. Secondly because of linking issues with the client. E.g. oracle might not be installed on the server. John

George Schlossnagle

22 years ago
On Jul 22, 2004, at 9:39 AM, John Lim wrote:
> Hi George, > > 2 reasons. > > High learning curve to learn all client API's.
All the APIs have worked examples in the PHP sources. :)
> Secondly because of linking > issues with the client. E.g. oracle might not be installed on the > server.
Of course you create a new runtime dependency your way. Are you doing this for PHP5 or PHP4? There's a worked example in the new xsl extension for PHP5 that does most of what you want (where PHP functions are registered as XSLT extension functions.) George

Wez Furlong

22 years ago
Doesn't ext/dbx already do what you're doing? To answer your original question, no, there isn't really a way to call it directly without duplicating a lot of ugly code. IIRC, PHP 5 adds a cache to reduce the lookup overhead for call_user_function; you probably won't be able to get it to go much faster than it does already. --Wez. On Thu, 22 Jul 2004 21:39:58 +0800, John Lim <jlim@natsoft.com.my> wrote:

Lester Caine

22 years ago
Wez Furlong wrote:
> Doesn't ext/dbx already do what you're doing? > To answer your original question, no, there isn't really a way to call > it directly without duplicating a lot of ugly code.
John wrote ADOdb so he is looking to speed it up.
> IIRC, PHP 5 adds a cache to reduce the lookup overhead for > call_user_function; you probably won't be able to get it to go much > faster than it does already.
I'm not seeing any bottleneck there John. My bottleneck seems to come with the result set, rather than the call, but none of it is causing a problem yet. (Running on PHP5 of cause)
-- Lester Caine ----------------------------- L.S.Caine Electronic Services

Andi Gutmans

22 years ago
Check out zend_call_function(). It allows you to cache the function lookup in the fci_cache parameter. Andi At 07:17 PM 7/22/2004 +0800, John Lim wrote:

Lester Caine

22 years ago
Andi Gutmans wrote:
> Check out zend_call_function(). It allows you to cache the function > lookup in the fci_cache parameter.
Where is the best place to find zend_call_function details, nothing in the manual and google gives some spurious results.
-- Lester Caine ----------------------------- L.S.Caine Electronic Services

Wez Furlong

22 years ago
Use the source, Luke. On Fri, 23 Jul 2004 08:08:00 +0100, Lester Caine <lester@lsces.co.uk> wrote:

Andrey Hristov

22 years ago
You can find some usage of this function in ext/standard/array.c hth, andrey Quoting Lester Caine <lester@lsces.co.uk>:

Lester Caine

22 years ago
Andrey Hristov wrote:
> You can find some usage of this function in ext/standard/array.c
>>Where is the best place to find zend_call_function details, nothing in >>the manual and google gives some spurious results.
Ta - but I'll leave this to John :) It's a level below where I can usefully help at the moment, but since John can't support all the database types, I may need to delve deeper in the future. At present I don't have the tools in place to do my own builds of PHP, so I'll stick to areas where I can ;)
-- Lester Caine ----------------------------- L.S.Caine Electronic Services

Andi Gutmans

22 years ago
php5/Zend/zend_execute_API.c. It's quite simple. If you can't figure it out yourself, let me know. At 08:08 AM 7/23/2004 +0100, Lester Caine wrote:

John Lim

22 years ago
Thanks to everyone. I will have a look. I'm porting the adodb extension to php5, so i thought i might as well ask this question that's been bugging me for some time. "Andi Gutmans" <andi@zend.com> wrote in message news:5.1.0.14.2.20040723085747.034ff738@127.0.0.1...
> php5/Zend/zend_execute_API.c. > It's quite simple. If you can't figure it out yourself, let me know. > > At 08:08 AM 7/23/2004 +0100, Lester Caine wrote: > >Andi Gutmans wrote: > > > >>Check out zend_call_function(). It allows you to cache the function > >>lookup in the fci_cache parameter. > > > >Where is the best place to find zend_call_function details, nothing in
the

John Lim

22 years ago
Andi, Just a few quick questions. What is the BG macro for? Eg. if (zend_call_function(&fci, &BG(fci_cache) TSRMLS_CC) == SUCCESS) Secondly, I think i need to initialize the fci_cache structure first with fci_cache = empty_fcall_info_cache; Can I do so in my PHP_MINIT_FUNCTION? Thx. "Andi Gutmans" <andi@zend.com> wrote in message news:5.1.0.14.2.20040723085747.034ff738@127.0.0.1...
> php5/Zend/zend_execute_API.c. > It's quite simple. If you can't figure it out yourself, let me know. > > At 08:08 AM 7/23/2004 +0100, Lester Caine wrote: > >Andi Gutmans wrote: > > > >>Check out zend_call_function(). It allows you to cache the function > >>lookup in the fci_cache parameter. > > > >Where is the best place to find zend_call_function details, nothing in
the

Andrey Hristov

22 years ago
G usually comes from Globals and I have seen BG in ext/standard so maybe BG means Basic functions Globals. andrey John Lim wrote:

John Lim

22 years ago
"Andrey Hristov" <php@hristov.com> wrote in message news:4102471A.70405@hristov.com...
> G usually comes from Globals and I have seen BG in ext/standard > so maybe BG means Basic functions Globals. > > andrey > > John Lim wrote: > > Andi, > > > > Just a few quick questions. What is the BG macro for? Eg. > > if (zend_call_function(&fci, &BG(fci_cache) TSRMLS_CC) == SUCCESS) > >
Thanks for the info. I get a error with the following (BG is undefined function): if (zend_call_function(&fci, &BG(fci_cache) TSRMLS_CC) == SUCCESS) So I tested with if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS) and it works fine. So do i need to use BG(), and how do i so ?

Andrey Hristov

22 years ago
John Lim wrote:
> "Andrey Hristov" <php@hristov.com> wrote in message > news:4102471A.70405@hristov.com... > >>G usually comes from Globals and I have seen BG in ext/standard >>so maybe BG means Basic functions Globals. >> >>andrey >> >>John Lim wrote: >> >>>Andi, >>> >>>Just a few quick questions. What is the BG macro for? Eg. >>> if (zend_call_function(&fci, &BG(fci_cache) TSRMLS_CC) == SUCCESS) >>> > > > Thanks for the info. I get a error with the following (BG is undefined > function): > > if (zend_call_function(&fci, &BG(fci_cache) TSRMLS_CC) == SUCCESS) > > > So I tested with > > if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS) > > and it works fine. > > So do i need to use BG(), and how do i so ? >
It is for thread safety access of globals. Defined in basic_functions.h : #ifdef ZTS #define BG(v) TSRMG(basic_globals_id, php_basic_globals *, v) extern int basic_globals_id; #else #define BG(v) (basic_globals.v) extern php_basic_globals basic_globals; #endif andrey

John Lim

22 years ago
A bulb lights up! Now i understand. I hand-coded the extension source code based on Rasmus' PHP book, and did not use the skeleton. Thx Andrey "Andrey Hristov" <php@hristov.com> wrote in message news:410253F1.7030905@hristov.com...

Andrey Hristov

22 years ago
John Lim wrote:
> "Andrey Hristov" <php@hristov.com> wrote in message > news:4102471A.70405@hristov.com... > >>G usually comes from Globals and I have seen BG in ext/standard >>so maybe BG means Basic functions Globals. >> >>andrey >> >>John Lim wrote: >> >>>Andi, >>> >>>Just a few quick questions. What is the BG macro for? Eg. >>> if (zend_call_function(&fci, &BG(fci_cache) TSRMLS_CC) == SUCCESS) >>> > > > Thanks for the info. I get a error with the following (BG is undefined > function): > > if (zend_call_function(&fci, &BG(fci_cache) TSRMLS_CC) == SUCCESS) > > > So I tested with > > if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS) > > and it works fine. > > So do i need to use BG(), and how do i so ? >
So, you write your own extension, right? In this case BG is not defined since it is defined only for functions in ext/standard. However there is such macro already created for your extension (if you have used ext_skel script). You can find it in php_yourextname.h . You should use it to have your extension be thread safe when accessing globals variables of your extension. This is the case in multithreaded environment where you have the call cache as global variable but multiple threads will to use it, so YOUREXTG() prevents from corruption. hope this helps, andrey