Dear list,
My web application (an online classifieds server) requires a set of fairly large global arrays which contain vital information that most all the page scripts rely upon for information such as the category list, which fields belong to each category, and so on. Additionally, there are a large number of function definitions (more than 13,000 lines of code in all just for these global definitions).
These global arrays and functions never change between requests. However, the PHP engine destroys and recreates them every time. After having spent some serious time doing benchmarking (using Apache Bench), I have found that this code takes at least 7ms to parse per request on my dual Xeon 2.4ghz server (Zend Accelerator in use*). This seriously cuts into my server's peak capacity, reducing it by more than half.
My question is: is there a way to define a global set of variables and functions ONCE per Apache process, allowing each incoming hit to run a handler function that runs within a persistent namespace? OR, is it possible to create some form of shared variable and function namespace that each script can tap?
AFAIK, mod_python, mod_perl, Java, etc. all allow you to create a persistent, long-running application with hooks/handlers for individual Apache requests. I'm surprised I haven't found a similar solution for PHP.
In fact, according to my work in the past few days, if an application has a large set of global functions and variable definitions, mod_python FAR exceeds the performance of mod_php, even though Python code runs significantly slower than PHP code (because in mod_python you can put all these definitions in a module that is loaded only once per Apache process).
The most promising prospect I've come across is FastCGI, which for Perl and other languages, allows you to run a while loop that sits and receives incoming requests (e.g. "while(FCGI::accept() >= 0) {..}"). However, the PHP/FastCGI modality seems to basically compare to mod_php: every request still creates and destroys the entire application (although the PHP interpreter itself does persist).
Essentially I want to go beyond a persistent PHP *interpreter* (mod_php, PHP/FastCGI) and create a persistent PHP *application*... any suggestions?
PHP's model is to be completely sandboxed such that every request is completely separate from every other. Having a persistent interpreter as you describe would break that rule and break the infinite horizontal scalability model of PHP.
Of course, there is nothing that prevents you from storing persistent data somewhere more permanent. If it is just simple read-only data you have a lot of options. For example, you could put them in a .ini file that is only loaded on Apache startup and use get_cfg_var() to fetch them. If you compile PHP with the --with-config-file-scan-dir switch to configure a configuration scan directory you can just drop your own ini file in that directory and it will be read on startup. This is just key=value pairs and not PHP code, of course.
If you need to do something fancier you can stick things in shared memory. Many of the accelerators give you access to their shared memory segments. For example, the CVS version of pecl/apc provides apc_store() and apc_fetch() which lets you store PHP datatypes in shared memory directly without needing to serialize/unserialize them.
And finally, the big hammer is to write your own PHP extension. This is a lot easier than people think and for people who are really looking for performance this is the only way to go. You can write whatever code you want in your MINIT hook which only gets called on server startup and in that hook you can create whatever persistent variables you need, pull stuff from a DB, etc. At the same time you will likely want to pull some of your heavier business logic identified by your profiling into the extension as well. This combination of C and PHP is extremely hard to beat performance-wise regardless of what you compare it to.
-Rasmus
-- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php