phpd Copyright (C) 2007, 2008 Andrew Rose (rose.andrew@gmail.com) For upto date information / support, try: http://andrew-rose.blogspot.com/search/label/phpd http://phpd.googlecode.com phpd-general@googlegroups.com http://groups.google.com/group/phpd-general Install information is located on the homepage at googlecode. ***The rest of this README is just a placeholder for now and contains nothing more than my wandering thoughts*** phpd uses the APLC Daemon stack. This allows phpd to spawn multiple child instances to handle http(s) requests and is like Apaches prefork MPM except no threading goes on because PHP does not support it. phpd revolves around the APLC Registry which is the central point of call for storing all stateful information. Think of it as $_SESSION on steroids. The modules are loaded in the child instance instead of being preloaded in the parent for two reasons: 1. Resources like MySQL connections won't work as expected when forked and used in the child processes. This is due to the fact the child processes will use the same connection id as the parent. 2. Sending a `killall -HUP phpd` will not work as expected. Because the parent image will already have source files loaded and new instances will not pick up changes in the modules, applications etc.. The transport will remain the same irregardless. Some downsides. 1. Because the modules have to be loaded for each child instance (preforks), errors / log messages will appear 1*preFork times. There is / will be code in place to suppress this. 2. Will take a little longer to startup but unless your superman or your machine is from pre 80186 period, you will not notice. Developing Applications Always create new database connections in Phpd_Application::init(). Never reuse the _phpd.database.local instance and change the database for example as this will break the backend. Never, ever use dynamicly generated registry paths. Always use static paths and static path / variable or static key combinations to access members. e.g. $this->reg->get('path.'.$_GET['somevar']); // BAD $this->reg->kget('path', $_GET['somevar']); // GOOD $this->reg->get('path.to.some.var'); // GOOD $this->reg->kget('path.to.some.var', 'key'); // GOOD Performance thoughts on preforking vs threads From the tests I've done so far it seems that threads and forking when looked at from a performance point of view are merely different ways of cutting the same cake (/me ducks). With preforking you have a set number of processes handling requests. With threading you tend to answer everyone you can which increases server load and slows down earlier requests. With phpd requests are handled more or less on a first come first served basis. At the end of the day the server can only process so many connections and the more you service at once the slower the responses to the clients becomes. Application directory structure. In the root phpd directory there is an applications directory. In this directory are the different applications and moving into one should show the following directories: classes/ This is used to store any application specific class that is not a business object(model). contexts/ The contexts directory is where the main user groups are defined. i.e. guest/ staff/ clients/ controllers/ All module controllers are defined here in there seperate context directories, for example taking the above contexts into account we have: controllers/guest/ controllers/staff/ controllers/clients/ entrypoint.php The main entry point for the application a.k.a front controller. models/ All business objects here. templates/ All re-usable templates (views) here. An actual page is stored in the context. So for example the login page for the login app is stored as: contexts/guest/login/controller.php contexts/guest/login/template.tpl Because phpd is persistent every page controller class must have a unique name. There are a few ways to handle this automatically. 1. Allow the class to be called Controller for all pages. When loading the source file(controller.php), tokenize and rewrite the controller name to something unique and pass in via eval. 2. Write controller classes (in controller.php) without the class definition, i.e. public function init() { } instead of: class Controller { public function init() { } } We simply read in the controller.php and wrap the contents with a unique controller class definition and load via eval. 3. Write a patch for PHP that allows redeclaration of classes. For now I'm sticking with number 2.
AndrewRose/phpd
The Pre-Forked Persistent PHP 5 Web/Application Server - Automatically exported from code.google.com/p/phpd
PHP