Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How PHP core is handling client connections?

Tags:

php

As far as I know, for each client connected to the server, PHP generates a new thread for it. But I wonder whether it's true or not, and If it's true, how long does this thread stay alive? Does this thread maintain all the static variables properly? (like a DB connection)

When this thread is destroyed, does it call all the destructors?

like image 625
fritsMaister Avatar asked May 06 '14 17:05

fritsMaister


2 Answers

It all depends upon how PHP is setup with the server. I am More familiar with Apache/PHP combo (rather than say Nginx and FastCGI with PHP setup), so focusing on this area:

  1. PHP is usually integrated into Apache as a DSO (dynamic-shared-object) module.

  2. Now Apache usually under Linux/Unix is usually setup as a 'pre-forked' model - i.e. when it starts up, a bunch of child processes are forked (the exact number can be configured via Apache directives), and they are in a 'pool of processes' ready to handle requests.

  3. When a request arrives, the kernel scheduler picks a Apache process from the pool (if available), and request is handled by the child.

  4. Based on the Apache setup, if it detects that a PHP script needs to be executed, it hands it over the PHP DSO as setup in (1).

  5. Hence no forking or threading is involved on a per-request basis which is efficient. All the request context is passed to the PHP layer which starts compiling and executing the PHP script.

    Note: The compilation step can be bypassed if an opcode cache is enabled - i.e. the first request on a PHP script is complied and its associated opcodes are cached to be reused for subsequent requests (it is a global cache shared by all child processes). As compilation step is expensive (parsing the script etc...), for production systems, it is best to enable an opcode cache.

  6. When the PHP script completes, it goes into a cleanup routine (built-in to the PHP DSO), and it will clean up the per-request memory, close all file descriptions including db handles (based on how it is opened). Some PHP methods have 'persistent' handles (e.g. opening db connections, file handles) which can be held across requests, hence which function you use to open a particular resource matters (which its respective documentation highlights). By default, most resources are held in the lifetime of a PHP request only, and they are destroyed once the PHP request is completed.

    Regarding PHP object dtors, it all depends up on the scope of where the object is created. So for global objects, its dtors will be only called at the end of the request cycle whereas some of them will be invoked when they go out of scope when a function returns.

    Hence you get memory/resource mgmt for free. You can control it via unset() calls by triggering a free immediately. Also starting with PHP 5.3, garbage collection can also be enabled during the request handling phase - see more details here: http://www.php.net/manual/en/features.gc.php

  7. Now this Apache child (which ran the PHP script) is back into the pool of processes ready to handle the next request as in step 3.

What I described above is typical for a Apache/PHP in Linux/Unix environments, but I think something similar is true for Microsoft setups too.

Also with nginx and FastCGI+PHP, I think the same cycle holds true - i.e. things are cleaned up at the end of a request cycle which the PHP+FastCGI module handles. Here too when nginx starts up, it will launch a pool of separate processes handled by the FastCGI+PHP module, and the communication between nginx and FastCGI+PHP occurs in a unix socket.

Hope this helps.

like image 95
jrm Avatar answered Nov 15 '22 16:11

jrm


It is not PHP, but web server, which handles requests. PHP is not running by itself. If web page contains PHP code, such request is delegated to PHP by appropriate PHP SAPI module. There are multi-thread, multi-process web servers and one can even imagine single process web server, so it is purely web server dependent if separate thread or process will be created for a request.

In many places of PHP documentation you can meet lines like this one on umask():

Avoid using this function in multithreaded webservers. It is better to change the file permissions with chmod() after creating the file. Using umask() can lead to unexpected behavior of concurrently running scripts and the webserver itself because they all use the same umask.

...how long does this thread stay alive? Does this thread maintain all the static variables properly? (like a DB connection)

You sound like one with C++ background. You probably mean global variables in PHP. PHP has built-in support for database connections and you should not worry about such things. They are implementation detail. Most SAPIs provide persistent database connections, but this is only for your curiosity. Persistent connections are created one per process, which handles requests. So in this case they are maintained rather by a process than thread.

When this thread is destroyed, does it call all the destructors?

In PHP destructors are being called when script finishes execution. From PHP developer point of view it is irrelevant where script lives.

like image 22
mip Avatar answered Nov 15 '22 17:11

mip