Something I was reminded of during the discussion of replacing pear with
composer that I thought was worthy of it's own thread. Most PHP apps I've
seen that use composer are
single point of entry apps - that is there's one front controller, usually
index.php, and .htaccess rules are put in place that route all requests to
that file.
These apps then go through the process of initializing themselves and
sometimes there are thousands of lines of code that get parsed through
before the app is in ready state, the router finally loaded and a decision
is made concerning the user's request.
This is extremely inefficient
What can be done in PHP core to more effectively embrace this paradigm
without disturbing the current one? That's what this thread is to
discuss. Here's my stab at it.
Create an .htaccess directive that allows a php file to be a directory
handler. When that directive is set the webserver will pass any
non-existent file request to PHP (in effect becoming a one line replacement
for a very common usage of mod_rewrite).
When this directive is used two statements will be looked for by the
runtime - first a ready statement (not necessarily named "ready"). When it
is reached PHP will save the application state, clone it and continue
working from the clone. On all all subsequent requests to the directory PHP
will start by creating a new clone and working from there.
The second statement instructs PHP to drop the saved state and load a new
one starting with the next request (graceful) or to kill any concurrent
workers (panic)
This isn't the same as opcode caching - this would be caching of the entire
application state including any data harvested from config file reads or
database calls.
It is possible to create this setup now using some PHP worker process
trickery, but it isn't easy.
Again, the above may not be a possible solution - but there's got to be a
better way than the current approach which amounts to installing the
application on every single request.
Thank you all for your time.
Something I was reminded of during the discussion of replacing pear with
composer that I thought was worthy of it's own thread. Most PHP apps I've
seen that use composer are
single point of entry apps - that is there's one front controller, usually
index.php, and .htaccess rules are put in place that route all requests to
that file.These apps then go through the process of initializing themselves and
sometimes there are thousands of lines of code that get parsed through
before the app is in ready state, the router finally loaded and a decision
is made concerning the user's request.This is extremely inefficient
What can be done in PHP core to more effectively embrace this paradigm
without disturbing the current one? That's what this thread is to
discuss. Here's my stab at it.Create an .htaccess directive that allows a php file to be a directory
handler. When that directive is set the webserver will pass any
non-existent file request to PHP (in effect becoming a one line replacement
for a very common usage of mod_rewrite).When this directive is used two statements will be looked for by the
runtime - first a ready statement (not necessarily named "ready"). When it
is reached PHP will save the application state, clone it and continue
working from the clone. On all all subsequent requests to the directory PHP
will start by creating a new clone and working from there.The second statement instructs PHP to drop the saved state and load a new
one starting with the next request (graceful) or to kill any concurrent
workers (panic)This isn't the same as opcode caching - this would be caching of the entire
application state including any data harvested from config file reads or
database calls.It is possible to create this setup now using some PHP worker process
trickery, but it isn't easy.Again, the above may not be a possible solution - but there's got to be a
better way than the current approach which amounts to installing the
application on every single request.Thank you all for your time.
Not long ago (something like) this has already been proposed, see
http://news.php.net/php.internals/92249ff.
--
Christoph M. Becker
Hi Michael,
Have you looked into PHP application servers, where the PHP code itself
acts as the web (or FastCGI) server, and so can keep the whole framework
etc. initialised in memory between requests?
This is how other (non-PHP) web stacks avoid “installing the application
on every single request”, and it can also be applied to PHP, it's just
not very common.
One example is Aerys (https://github.com/amphp/aerys), but it's hardly
the first or the last example of this approach.
Thanks.
--
Andrea Faulds
https://ajf.me/
Hi Michael,
Have you looked into PHP application servers, where the PHP code itself
acts as the web (or FastCGI) server, and so can keep the whole framework
etc. initialised in memory between requests?
I have - it's what I was referring to when I mentioned PHP worker process
trickery. I know it can be done, but it isn't straightforward and it can't
be quickly applied to existing applications like Wordpress or Drupal.
This is how other (non-PHP) web stacks avoid “installing the application
on every single request”, and it can also be applied to PHP, it's just not
very common.
I know. What I'm wondering though is, could there be a way to do this on
the PHP engine level that would avoid massive rewrites of existing PHP code.
Here's my current draft of a way to implement this using two statements.
require_bootstrap( [FILE] );
This statement loads and executes the code in question just as require
does. It saves the execution state before moving to the next code line
after this statement is called. If called without a file it saves the
execution state immediately.
The saved execution state is hostname aware for sites that use a multisite
configuration. So if the statement is reached from
www.onesite.com/index.php and from www.twosite.com/index.php two different
bootstraps will be created. This is done on the assumption that the booting
process is going to make one or more decisions based on the hostname.
Drupal loads entirely different setting files, module lists, uses a
different Dependency Injector, all according to the hostname.
unload_bootstrap( [PATH] );
This unloads the bootstrap associated with the webpath given. If no
argument is given the current bootstrap image is dropped. Question - should
passing boolean TRUE
unload all the bootstraps at once, or should that be
it's own function, or is it necessary?
Note that bootstraps will be unloaded automatically if the opcode cache for
the associated files changes.
Thoughts, suggestions, questions, complains, or flames?
Hi Michael,
Have you looked into PHP application servers, where the PHP code itself
acts as the web (or FastCGI) server, and so can keep the whole framework
etc. initialised in memory between requests?This is how other (non-PHP) web stacks avoid “installing the application
on every single request”, and it can also be applied to PHP, it's just
not very common.One example is Aerys (https://github.com/amphp/aerys), but it's hardly
the first or the last example of this approach.Thanks.
I'm sure I remember reading somewhere that fabpot was working on one in
Golang? Something similar to Unicorn or Puma from the Ruby ecosystem
would be a boon.
--
Daniel Morris
daniel@honestempire.com