stop a session from timeouting on PHP - php

I'm making a project on PHP and it pretty much doesn't involve any human intervention, in other words, I'm making a special script that should run for a long time (a user visits my website and the script keeps running until the user exits...). The one problem that is concerning me is:
Won't the sessions expire when the script runs like this for a while? If So how could I bypass that, so it could run for a very a long time?
Oh, And one more question: Could my PHP script start by its own without any user intervention? If so, How could I configure it to do so?

You can run PHP from the command line. Those scripts do not have a timeout like user-called scripts. Otherwise, you can set the timeout with set_time_limit like
set_time_limit(0); // 0 means no limit
See http://php.net/manual/en/function.set-time-limit.php

You can use set_time_limit(0) to avoid the timeout.
For the PHP script to start on its own, you could use a cron

Related

Make PHP script call itself after some time

I have some limitations with my host and my scripts can't run longer than 2 or 3 seconds. But the time it will take to finish will certainly increase as the database gets larger.
So I thought about making the script stop what it is doing and call itself after 2 seconds, for example.
Firstly I tried using cURL and then I made some attempts with wget. But there is always a problem with waiting for the response and timeouts (with cURL, for example, I just need to ping the script, not wait for a response) or permissions with the server (functions that we use to run wget such as exec seems to be disabled on my server, or something like that).
What do you think is the best idea to make a PHP script ping/call itself?
On Unix/LInux systems I would personally recommend to schedule CRON JOBS to keep running the scripts at certain intervals
May be this SO Link will help you
Php scripts generally don't call other php scripts. It is possible to spawn a background process as illustrated here, but I don't think that's what you're after. If, so you'd be better off using cron as was discussed above.
Calling a function every X amount of seconds with the same script is certainly possible, but this does the opposite of what you want since it would only extend the run time of the script in question.
What you seem to be asking is, contrary to your comment, somewhat paradoxical. A process that calls method() every so often is still a long running process and is subject to the same restrictions as any other process on the server, regardless of the fact that it may be sitting idle for short intervals.
As far as I can see your options are:
Extend the php max_execution_time directive, or have your sysadmin do so if they are willing
Revise your script so that it completes within the time limit
Move to a new server

How to make php work forever without cron?

Is there a way to make php work forever without cron.
What I want it for is to unban users after a few hours by running a mysql query, thanks
If you don't have access to cron jobs on your server (I guess you are running on a shared hosting?), the best alternative is to run an "external cron". Have a look at www.setcronjob.com. I have been using this for a couple of months now and it is pretty stable.
You can set it up such that it calls a script on your website every whenever you want. (Example: http://www.yoursite.com/script.xxx)
In the script, you can run a MySQL query to check which users have been banned for a couple of hours and then unban them.
You can start your script from the command line and let it run in the background. You will have to design this script in such a way that it never exits and just loops forever using the sleep() function to avoid unnecessary processor load. Since php scripts invoked from the command line have no max execution time the script will run until you manually kill it off with the kill command.
Once you've written the script you can start it with:
nohup php myscript.php &
nohup makes the script still run once you log out of the console session that you started it from, otherwise it would kill off then. The & symbol at the end starts the script as a new process in the background so that you can continue using the console.

best way to repeat php script after fixed interval

i want my php script to be executed after every 10 seconds until stop button is pressed
Is using an while loop with sleep() the best way or there is a better way of doing it?
And i want to know that if i run that while loop, will it prevent the other scripts on the page from running?
i mean that during the sleep time, as the PHP script is still running, will browser wait for this script to end of will run other scripts simultaneously?
As far as i have understood, cron wont be helpful in this case as i have to run the script between the time when start and stop button are pressed. Please correct me if i am wrong.
Cron would do the job although, with an interval as small as 10 seconds, you'd probably be better off writing a daemon instead (and running from the command line or init.d, not through a web server).
You just need a way to switch it on and off. That could be something as simple as testing to see if a file exists (and then adding or deleting it as desired).
And i want to know that if i run that while loop, will it prevent the other scripts on the page from running?
You need to make the script stand-alone for this to make any sense at all.

Spawning a separate PHP process for a long task

I have an AJAX script that takes about 10 minutes to do its thing. I would like to be able to tell the user 'Hey listen, the task is being completed, we'll let you know how it turns out', but it won't let the user run any other scripts on the server until that one completes (I believe this is a consequence of PHP being single threaded, but I'm not sure). Is there a way to assign that AJAX script to a separate PHP or Apache process, so that the user can continue to click around in the application without having to wait for the task to finish?
You can use database or files to insert some lock mechanism to prevent task from running multiple times simultaneously. Then you need to just spawn PHP process using command nohup (no hang up), for more details look at this article: https://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/ or this question: nohup: run PHP process in background .
I seek for hours, at least, the solution was very easy for me using Cron Jobs. In cPanel you can go to Advanced -> Cron Jobs, and there schedule a task using a PHP script in Command line.
A Command example that execute a script php:
/usr/bin/wget http://www.example.com/miscript.php
or better:
php /home/USER/public_html/miscript.php
Are you using PHP sessions? If so, then a likely cause is that the long-running script keeps the session locked until it finishes. Any other request trying to access that same session will have to wait until the first one is done (usually it'll exceed request timeouts).
To fix that you'll need session_write_close():
Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done.
So simply call that function right around where you tell the user hey ya gotta wait. If you need (read) access to session variables later on in that script, consider storing them in local variables, then close the session immediately afterwards before moving on to whatever's taking a long time. If you need write access you could try re-running session_start() at the end, but if the session is currently locked elsewhere it'll have the same blocking problem. You could work around that by e.g. storing something in the database from the background script and fetching it from the regular user session, for example.

Cron job for php script that requires VERY long execution time

I have a php script run as a cron job that executes a set of simple tasks that loops for each user in the database and takes about 30 mins to complete. This process starts over every hour and needs to be as fast and efficient as possible. The problem Im having, is like with any server script, execution time varies and I need to figure out the best cron time settings.
If I run cron every minute, I need to stop the last loop of the script 20 seconds before the end of the minute to make sure that the current loop finishes in time. Over the course of the hour this adds up to a lot of wasted time.
Im wondering if its a bad idea to simple remove the php execution time limit and run the script once an hour and let it run to completion.... is this a bad idea?
Instead of setting the max_execution_time you could also use set_time_limit() to reset the counter on every loop. This will ensure your script is never running out of time unless there is something serious hanging within the current loop (and taking longer than the max_execution_time).
Basically this should make your script run as long as it needs while giving it a 30 seconds timeout between two set_time_limit() calls.
Assuming you'd like the work done ASAP, don't use cron. Cron is good for things that need to happen at specific times. It's often abused to simulate a background process that would ideally process work as soon as work appears. You should probably write a daemon that runs continuously. (Note: you could also look at a message/work-queue type system, there are nice libraries out there to do this too)
You can write a daemon from scratch using the pcntl functions (since you don't care about multiple worker processes, it's super-easy to get a process running in the background.), or cheat and just make a script that runs forever and run it via screen, or leverage some solid library code like PEAR's System:Daemon or nanoserv
Once the daemonization stuff is taken care of, all you really care about is having a loop that runs forever. You'll want to take care that your script doesn't leak memory, or consume too many resources.
Generally, you can do something like:
<?PHP
// some setup code
while(true){
$todo = figureOutIfIHaveWorkToDo();
foreach($todo as $something){
//do stuff with $something
//remember to clean up resources so you don't leak memory!
usleep(/*some integer*/);
}
usleep(/* some other integer */);
}
And it'll work pretty well.
Setting the time limit to 0 and letting it do its thing is fairly typical of PHP based cronjobs (in my experience), but this is also the point when you should ask yourself a few important questions, such as "Should I rewrite this job in a compiled language?" and "Am I using all of my tools (database, etc) to their maximum efficiency?"
That said, maybe better than completely removing the time limit would be to set it to the upper limit you actually want. If that means 48 minutes, then set_time_limit(48 * 60);
I really think you shouldn't set the time out to 0, that is just looking for trouble. At most, set it to 59*60 seconds, but setting it to 0 might cause security problems, if a script hangs, it will hang almost forever until the server host stops the execution. It is considered bad practice to do so.
I have used the php command-line interface for similar long running tasks in the past. You probably do not want to remove the execution time limit for any request.
Sounds like a great idea if there's little chance that it will take more than an hour. Note, however, that the wrong bug can be a really good way of making it take longer than expected..
To avoid all sorts of nasty problems, you should have a guard file with the process ID of the script. On startup, you should check to make sure the file doesn't exist, or if it does that the process ID in the file doesn't exist (through a kill( pid, 0 ) call). If these conditions are met, create a new file with the script's PID and delete the file when you're done.
This is the same trick that many daemons use to ensure it isn't already running. If the daemon was killed suddenly, the file will still exist but the PID of the process therein is unlikely to be running.
Depending on what your script does, it can lead to problems if you remove the time limit. If per example, you are polling an external server that is unresponsive while the job is running, and that your cron takes 2 hours instead of 30 minutes to complete, you may get a stack of PHP processes being fired up even if the previous ones haven't completed yet. This can cause system instability and crashes.
You probably have two options:
Make sure that no other instance of your script is running beforehand, otherwise exit() on start.
Consider changing your cronjob into a daemon.
Does it have to run hourly like clockwork?
If not split the job (you mentioned it was more than one simple task) do each task every hour?
Or split it per user, do A-M on hour, then N-Z the next?

Categories