I am not sure that I correctly understand how php works in general.
I will explain how I understand it.
When you are making request to webpage for example http://supersite.com/index.php firstly PHP interpreter runs through whole index.php file and all dependencies checking it for errors, after that it is executed from the beginning of the index.php to the end.
How all frameworks work ?
They are doing something named bootstrap, on the first lines of index.php can some method that direct execution flow into another way (to another file) doing a lot of stuff there. Loading classes into memory...
But if there no exit command execution will end at the end of index.php file anyway.
If I understand correctly, this means that for each request PHP start interpretation without previous state, so when PHP responses user request it clears all objects in memory and finishes. For the user it seems that he is working with one program but for the server and PHP each request is stateless, so PHP interpreter have to load all classes required for execution into memory each request?
Am I correct , or PHP stores in memory last loaded classes declaration (permanent generation in java) and static variables?
Related
In my website I had a process which needs to create a file (executed with cronjob). However, I removed both the script and the cronjob, but the file is still created and the process from the cronjob executed. I know this sounds really unbelievable, but is there any way a process can stack in the memory of the server and loop? Can you think of any other reason causing this problem?
I had same issue. Process is executed infinity times and code changes, code removal does not help as it seems that process is "caching" your code.
What I have done:
Log in to SSH to server, use top command and search for PHP process PID, than use kill to terminate this process. (some source about it).
To prevent this:
I have created some file on server and inside every loop and just before starting function (I had recursive function) check if file exists (or check for valid content). If not found - do not execute process.
I am used to using application_start event in c# in glocal.ascx.
I need to create something similar in php so when the application first loads i can cache all data first time round.
Does anyone know a good way of me doing this.
PHP does not have something like an AppDomain in ASP.NET.
In ASP.NET the webserver spawns once an AppDomain process and (synchronous) requests are handled as "HttpContext threads" inside this process. Asynchronous IHttpHandlers may be handled over multiple threads, but are also sharing the same AppDomain process.
In PHP each request is a single process (as of FastCGI a thread), but you don't have a static shared scope. A script executes and then dies. To share data in-memory, you need helpers like memcache.
In php each script sequentially runs through all code and then dies. So, if I understand your question properly you basically want to build the caching system into the top of your script.
On my simpler projects I simply include a file (I called it assign.inc) which handles all my site wide/global tasks. It loads first on every page and sets up my session/db connection etc.
On my bigger projects I wrote all traffic through index.php (via .htaccess) this initiates my CMS class which does everything though __construct.
Does that help?
I want to have my own variable that would be (most likely an array) storing what my php application is up to right now.
The application can trigger few processes that are in background (like downloading files) and I want to have a list what is being currently processed.
For example
if php calls exec() that will be downloading for 15mins
and then another download starts
and another download starts
then if I access my application I want to be able to see that 3 downloads are in process. If none of them finished yet.
Can do that? Only in memory, not storing anything on the disk?
I thought that the solution would be a some kind of server variable.
PHP doesn't have knowledge of previous processes. As soon has a php process is finished everything it knows about itself goes with it.
I can think of two options. Write knowledge about spawned processes to a file or database and use it to sync all your php request, (store the PID of each spawned process)
Or
Create an Daemon. The people behind PHP have worked hard to clean up PHP memory handling and such to make this more feasible. Take a look at their PEAR package - http://pear.php.net/package/System_Daemon
Off the top of my head, a quick architecture would compose of 3 peices
Part A) The web app that will take in request for downloads, and report back the progress of all request
Part B) You daemon, which accepts requests for downloads, spawns process, and will report back status of all spawned reqeust
Part C) The spawn request that will perform the download you need.
Anyone for shared memory?
Obviously you would have to have some sort of daemon, but you could use the inbuilt semaphore functions to easily have contact between each of the scripts. You need to be careful though because sometimes if you're not closing the memory block properly, you could risk ending up with no blocks left.
You can't store your own variables in $_SERVER. The best method would be to store your data in a database where and query/update it as required.
How long do PHP static variables persist, i.e. how long does a "PHP run" persist? With say a command line program there is a defined start and end, but in web w/ AJAX I don't know how to define this.
Here are 3 ways I've seen a PHP script started.
User (Requesing a PHP page)
Javacript calling PHP (AJAX)
PHP calling more PHP via a header()
In my actual application I have javascript call a php script via AJAX that script uses the header() to reload the site. This would be consideredt two different runs. Each has their own static variables that do not relate.
PHP variables persist for the lifetime of the script running through the interpreter. In the case of a web request, this is the lifetime of handling the requests. Your three cases are all requests to a server, and thus are handled the same: the static variables survive until the script terminates after handling the request.
The life span of PHP (and its variables) over a request:
Request is sent to server, whether by user, ajax, curl through PHP or what-have-you
Relevant PHP script is executed, whether as a module on your web server, a CGI worker process, or other options
Script is executed, response to the request (if any) is created and sent
(optional) script continues to execute some other job until eventual termination, at which time all its variables die with it.
The "PHP run" is always from start of execution untill the end of the script. So, if you call a PHP script with ajax or a PHP calls another PHP via a header(), each call is a single run. The static variables instantiated earlier do not have a persistant state and will be redefined.
Either static variables or not...if you want to have a persistent state of data throughout those requests you will either have to save it in the session, cookie, database, or in a cache.
It depends on the server setup. Typically, when you make a request, the PHP interpreter is loaded, parses the script, your server spits out the results and the interpreter is destroyed. This happens for each request, regardless of whether it originates from a user browsing or AJAX. What this means is that "static" variables are only valid until the interpreter is destroyed, which again, is at the end of every request. (HTTP is stateless)
What do you mean by "PHP calling more PHP via a header()"? Are you referring to a redirect? In that case, it's a new request. If you meant "PHP calling more PHP via an include", it's typically not a new request (the edge case being you are including a PHP script from a 3rd party.. dangerous and not recommended). With an include, PHP simply loads and executes the file in the same context as the originating script.
The PHP static (that could be considered "global" in a procedural way) doesn't persist in any of your cases.
In each of them a new HTTP request is performed and the Php variables state is lost.
In the command line there is a defined start and end.
There is no difference in PHP running on a server. When a web request is made to the script, the script runs till the end of the script, or until it crashes or has a time-out (and possibly other similar issues).
AJAX doesn't run server side. AJAX is another client side asynchronous call to a server resource. Everything that's done for the first request as far as authentication, validation, input checking, etc has to be done with every subsequent request. The difference in an AJAX response is that the PHP script is likely to return only the content that's requested.
The only time a program will "persist" is if it has been told to keep going. PHP can be told to wait, and perform actions via web sockets, but that seems to be outside the scope of your question.
All three are the same.
In each case, the user's browser is making an http request for the url. The runtime is from the time the server receives the request to the time it is fullfilled.
The PHP scripts stops when you exit, reaches the end of the script or fails.
I've noticed many times where some php scripts exit. It seems to me that this will force an exit of the httpd/apache child (of course another will be started if required for the next request).
But in the CMS, that next request will require the entire init.php initialization, and of course just cleaning up and starting php in the first place.
It seems that the php files usually start with
if ( !defined( 'SMARTY_DIR' ) ) {
include_once( 'init.php' );
}
which suggests that somebody was imagining that one php process would serve multiple requests. But if every script exits, then each php/apache process will serve one request only.
Any thoughts on the performance and security implications of removing many of the exit calls (especially from the most-frequently-called scripts like index.php etc) to allow one process to serve multiple requests?
Thanks, Peter
--ADDENDUM --
Thank you for the answers. That (php will never serve more than one request) is what I thought originally until last week, when I was debugging a config variable that could only have been set in one script (because of the way the path was set up) but was still set in another script (this is on a webserver with about 20 hits/sec). In that case, I did not have a php exit call in the one script that set up its config slightly differently. But when I added the php exit call to that one script (in the alternate directory) this solved the misconfiguration I was experiencing in all my main scripts in the main directory (which were due to having a css directory variable set erroneously, in a previous page execution). So now I'm confused again, because with what all the answers so far say, php should never serve more than one request.
exit does nothing to Apache processes (it certainly doesn't kill a worker!). It simply ends the execution of the PHP script and returns execution to the Apache process, which'll send the results to the browser and continue on to the next request.
The Smarty code you've excerpted doesn't have anything to do with a PHP process serving multiple requests. It just insures that Smarty is initialised at all times - useful if a PHP script might be alternatively included in another script or accessed directly.
I think your confusion comes from what include_once is for. PHP is basically a "shared-nothing" system, where there are no real persistent server objects. include_once doesn't mean once per Apache child, but once per web request.
PHP may hack up a hairball if you include the same file twice. For instance a function with a particular name can only be defined once. This led to people implementing a copy of the old C #ifndef-#define-#include idiom once for each included file. include_once was the fix for this.
Even if you do not call exit your PHP script is still going to end execution, at which point any generated HTML will be returned to the web server to send on to your browser.
The exit keyword allows you to signal to the PHP engine that your work is done and no further processing needs to take place.
Also note that exit is typically used for error handling and flow control - removing it from includes will likely break your application.