Forum OpenACS Development: Tcl calls from PHP?
From your question I take it PHP does not have a convenient interface for making calls to the Tcl interpreter, but AFAIK every AOLserver connection thread does and must have a Tcl interpreter whether you use it for much of anything or not, so Tcl is there to be called.
I am entirely unfamiliar with PHP and its implementation in AOLserver, but if you are able to extend it in C, worst case you should be able to set up a C function which lets you call arbitrary Tcl commands (via Tcl_Eval). But there may be better or easier ways than that, of course. I'd ask on the AOLserver list before hacking in something like that myself.
What I could envision e.g. for the moment is to use a PHP address book functionality in OpenACS and redirect the Database inserts (and reads, maybe) through Tcl API, so both OpenACS and the PHP address book could add items, but you could view it quickly in a list-builder page (which is easy to generate).
I'm tossing out ideas here at the moment with a huge potential for trouble, but, as a matter of fact, OpenACS lacks functionality in a number of occasions, where (specialized) PHP products are further advanced. It is just a question of how to integrate these best.
So given that PHP already runs adequately in AOLserver, adding bi-directional Tcl/PHP support should be entirely feasible. The AOLserver support currently included with PHP 5.0.0 beta3 definitely doesn't have any such support though, I just looked.
I imagine the first step is to stick in the basic support for Tcl calling PHP and PHP calling Tcl, and start coding up friendly PHP APIs to Tcl functionality and vice-versa. Then probably later once the basics are working, change as many AOLserver/PHP API functions as feasible to call the underlying AOLserver C code directly (just like the Tcl API does), for performance. (Especially the database API!)
I'll bang on it some more, and then try implementing this against the latest stable release of PHP, then make a patch available.
Unlike Tcl and its interpreted script model where a Tcl interp can be fed a Tcl script for evaluation, PHP is more like a stand-alone executable which executes a whole PHP script, like a Unix shell. It creates separate processes as necessary for script processing, and the PHP (Zend) engine is file-based.
Because of this, every call to the proposed "ns_php" command would fork the nsd process and start up a brand new PHP execution process. There would be no cohesion between two calls to ns_php, e.g., setting variables in one won't be visible in the next.
There's a highly experimental "embed" SAPI (server API) module for PHP, but after reviewing the code, it doesn't address the issues I've already mentioned.
In short, there's very little practical value in implementing a ns_php-like command for Tcl the way PHP is implemented today. And, given the design of PHP, I don't expect to see a PHP version that could be embedded considering how deeply rooted these design issues are. Perhaps, it'd be possible to lift the Zend engine and make it a proper embeddable script interpreter, but even with the new Zend 2.0 engine, they haven't gone in that direction.
For now, just be happy to be able to get back to the Tcl interp. from a PHP page -- that alone will make the AOLserver/PHP combo very powerful.
Wow, I hadn't realized the PHP engine design was that brain-dead. Hm, if someone really needed to be able to call PHP from Tcl, would there be some relatively easy way to make that work reasonably efficiently?
Back in 2000, Jim Davidson mentioned Digital City's Proxy, which is basically a separate tclsh helper process, which can send messages back and forth to AOLserver, and which forks on demand so that the main AOLserver process doesn't have to. Seems like that sort of thing would be useful for running PHP commands as well?
The proxy mechanism would only help by not forking the AOLserver process, but it still doesn't address the issue of each PHP script evaluation means getting a fresh PHP interpreter.
However, this just occurred to me: one could write a "PHP server" -- a long-running daemon-like process written in PHP that listened on a socket, where clients would connect to it and feed it a PHP script which PHP would pass through eval() and return the result.
*shudder* I think I'm going to have nightmares now. Maybe I'll implement something like this for shits and giggles, but frankly it's Just Not Right(tm).
Or is there more to it that I'm missing here? In practice, why would a Tcl caller ever care about the fact that PHP has no persistent state at all?
However, what this means is that the cost of a single PHP command is thus the same as a CGI being forked. The php.ini config file must be read, file handles opened, that sort of thing. And you can, in fact, run PHP as a CGI.
I think the idea is not so much that PHP has persistent state, as that the cost of a PHP function be as small as a possible. Having a persistent interpreter being around means no startup time. Think of how having bash's builtin functions around all the time makes it easier and more efficient when you are doing things on the command line.