Can a PHP script abort itself or detect abortion? - php

PHP scripts can continue executing after the HTTP page request, so how do I finally stop it executing when I'm done with it?
Also, is there an event to detect when the OS is going to forcibly abort the script? or how do I keep an internal timer to predict max_execution_time?

exit()/die() will stop a php script.
To know when to stop the script, you'll just have to use microtime as a timer and save as a constant (or fetch from the php.ini file) the maximum execution time.
You can also look at the Connection handling information. Where we have things like connection_aborted() and connection_status()
But what is the problem you're trying to solve?

You can use register_shutdown_function to register a function to be called at the end of script execution. You can use this to detect when the script has been terminated and perform a certain set of actions.

To have a callback at the moment your request is shutting down, use register_shutdown_function( myfunction ).
Much like most POSIX environments, PHP also supports signal handlers. You can register your own handler for the SIGTERM event.
function my_abort_handler( $signo ) {
echo "Aborted";
}
pcntl_signal( SIGTERM, "my_abort_handler" );

You may want to take a look at pcntl-alarm which allows a script to send a signal to itself. Also contains some sample on how to catch the kill signals which can be send by the OS. And die() indeed.

Well, you could start a $start=microtime(true) which will return a timestamp. Then you can just keep checking microtime(true) and subtract that from your start time to get the number of seconds since executing.
But no, you can't "catch" the script as its terminating for the reason of the request being too long. You could try to do some last minute stuff in the shutdown handler, but I'm not sure if PHP will honor that.
It looks like there used to be a function that does exactly what you want, connection_timeout(), but it was deprecated and removed. Don't know if there is any kind of replacement for this, however.

Related

Setting a socket timeout in PHP

I'm writing a script in PHP that uses PEAR's Net_Socket. I want to query servers to see if they have any current information. I send in a command and then use $socket->readLine() to get the response. However, if there is not a response, my script just waits forever. Is there anyway to either tell the socket to close after a specific amount of time or to wrap the whole function in a timeout, that if it hasn't returned by the timeout, it halts its execution?
On the same page you linked is a link to setTimeout(): https://pear.php.net/manual/en/package.networking.net-socket.settimeout.php
Trying calling $socket->setTimeout( $seconds, $milliseconds ); just before calling readLine()

register_shutdown_function Or ignore_user_abort?

Hey i've seen people recommend each of them, One calimed register_shutdown_function to be better but without explination.
I'm talking about which is better to send a response back and still preform other tasks.
I Wondered what really is the better method and why.
EDIT:
In the register_shutdown_function documentation, someone published the following method:
<?php
function endOutput($endMessage){
ignore_user_abort(true);
set_time_limit(0);
header("Connection: close");
header("Content-Length: ".strlen($endMessage));
echo $endMessage;
echo str_repeat("\r\n", 10); // just to be sure
flush();
}
// Must be called before any output
endOutput("thank you for visiting, have a nice day');
sleep(100);
mail("you#yourmail.com", "ping", "im here");
?>
Could it be better then any of the functions i stated?
ignore_user_abort() tells PHP/Apache to not terminate execution when the user disconnects. register_shutdown_function simply allows you to do some cleanup while PHP is in the process of shutting down.
register_shut_down is only useful if you need to do some cleanup that PHP's normal shutdown routines wouldn't take care, e.g. removing a manually created lock file, flipping a bit in a DB record somewhere, etc...
In older versions of PHP (<4.1.0 under Apache), register_shutdown_function() would ensure that the connection was closed before your shutdown functions ran. This is no longer the case. The endOutput() function in your edit should indeed do what you want, provided you don't have any output buffers open. Though, it does set the script to be able to run forever if necessary, which could be annoying if it goes into an infinite loop (especially during debugging). You might want to change set_time_limit() to use a value that actually reflects how many seconds the script should take.
It's probably best to avoid register_shutdown_function() if you don't need it, since it has some other odd behavior (such as not being able to add a second layer of shutdown functions to run if the first shutdown function calls exit()).

I want to execute more than one method at a time in php

Hi Please help me in executing more than one method at a time in PHP.
Below is example:
<?php
function writeName()
{
sleep(3);
echo "Kai Jim Refsnes";
}
function b(){
sleep(3);
echo"b";
}
b();
writeName());
?>
Here above program take 6 sec to execute.But I want to run my both method simultaneously so that program should execute with in 3 sec(Multi threading).
With common PHP its not possible, because PHP is executed sequential. You may have a look at a job-server like gearman, or you may try to use forks (pcntl_fork()). It's not multi-threading, because there is no shared memory.
Sorry, but multithreading is not supported in PHP.
But you could start a PHP script which can run in the background using exec(). Just make sure you redirect it's output elsewhere.
That should be the closest you can get to "multithreading" without additional tools. Here's what the manual says:
Note: If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.

Is there a function similar to setTimeout() (JavaScript) for PHP?

The question sort of says it all - is there a function which does the same as the JavaScript function setTimeout() for PHP? I've searched php.net, and I can't seem to find any...
There is no way to delay execution of part of the code of in the current script. It wouldn't make much sense, either, as the processing of a PHP script takes place entirely on server side and you would just delay the overall execution of the script. There is sleep() but that will simply halt the process for a certain time.
You can, of course, schedule a PHP script to run at a specific time using cron jobs and the like.
There's the sleep function, which pauses the script for a determined amount of time.
See also usleep, time_nanosleep and time_sleep_until.
PHP isn't event driven, so a setTimeout doesn't make much sense. You can certainly mimic it and in fact, someone has written a Timer class you could use. But I would be careful before you start programming in this way on the server side in PHP.
A few things I'd like to note about timers in PHP:
1) Timers in PHP make sense when used in long-running scripts (daemons and, maybe, in CLI scripts). So if you're not developing that kind of application, then you don't need timers.
2) Timers can be blocking and non-blocking. If you're using sleep(), then it's a blocking timer, because your script just freezes for a specified amount of time.
For many tasks blocking timers are fine. For example, sending statistics every 10 seconds. It's ok to block the script:
while (true) {
sendStat();
sleep(10);
}
3) Non-blocking timers make sense only in event driven apps, like websocket-server. In such applications an event can occur at any time (e.g incoming connection), so you must not block your app with sleep() (obviously).
For this purposes there are event-loop libraries, like reactphp/event-loop, which allows you to handle multiple streams in a non-blocking fashion and also has timer/ interval feature.
4) Non-blocking timeouts in PHP are possible.
It can be implemented by means of stream_select() function with timeout parameter (see how it's implemented in reactphp/event-loop StreamSelectLoop::run()).
5) There are PHP extensions like libevent, libev, event which allow timers implementation (if you want to go hardcore)
Not really, but you could try the tick count function.
http://php.net/manual/en/class.evtimer.php is probably what you are looking for, you can have a function called during set intervals, similar to setInterval in javascript. it is a pecl extension, if you have whm/cpanel you can easily install it through the pecl software/extension installer page.
i hadn't noticed this question is from 2010 and the evtimer class started to be coded in 2012-2013. so as an update to an old question, there is now a class that can do this similar to javascripts settimeout/setinterval.
Warning: You should note that while the sleep command can make a PHP process hang, or "sleep" for a given amount of time, you'd generally implement visual delays within the user interface.
Since PHP is a server side language, merely writing its execution output (generally in the form of HTML) to a web server response: using sleep in this fashion will generally just stall or delay the response.
With that being said, sleep does have practical purposes. Delaying execution can be used to implement back off schemes, such as when retrying a request after a failed connection. Generally speaking, if you need to use a setTimeout in PHP, you're probably doing something wrong.
Solution: If you still want to implement setTimeout in PHP, to answer your question explicitly: Consider that setTimeout possesses two parameters, one which represents the function to run, and the other which represents the amount of time (in milliseconds). The following code would actually meet the requirements in your question:
<?php
// Build the setTimeout function.
// This is the important part.
function setTimeout($fn, $timeout){
// sleep for $timeout milliseconds.
sleep(($timeout/1000));
$fn();
}
// Some example function we want to run.
$someFunctionToExecute = function() {
echo 'The function executed!';
}
// This will run the function after a 3 second sleep.
// We're using the functional property of first-class functions
// to pass the function that we wish to execute.
setTimeout($someFunctionToExecute, 3000);
?>
The output of the above code will be three seconds of delay, followed by the following output:
The function executed!
if you need to make an action after you execute some php code you can do it with an echo
echo "Success.... <script>setTimeout(function(){alert('Hello')}, 3000);</script>";
so after a time in the client(browser) you can do something else, like a redirect to another php script for example or echo an alert
There is a Generator class available in PHP version > 5.5 which provides a function called yield that helps you pause and continue to next function.
generator-example.php
<?php
function myGeneratorFunction()
{
echo "One","\n";
yield;
echo "Two","\n";
yield;
echo "Three","\n";
yield;
}
// get our Generator object (remember, all generator function return
// a generator object, and a generator function is any function that
// uses the yield keyword)
$iterator = myGeneratorFunction();
OUTPUT
One
If you want to execute the code after the first yield you add these line
// get the current value of the iterator
$value = $iterator->current();
// get the next value of the iterator
$value = $iterator->next();
// and the value after that the next value of the iterator
// $value = $iterator->next();
Now you will get output
One
Two
If you minutely see the setTimeout() creates an event loop.
In PHP there are many libraries out there E.g amphp is a popular one that provides event loop to execute code asynchronously.
Javascript snippet
setTimeout(function () {
console.log('After timeout');
}, 1000);
console.log('Before timeout');
Converting above Javascript snippet to PHP using Amphp
Loop::run(function () {
Loop::delay(1000, function () {
echo date('H:i:s') . ' After timeout' . PHP_EOL;
});
echo date('H:i:s') . ' Before timeout' . PHP_EOL;
});
Check this Out!
<?php
set_time_limit(20);
while ($i<=10)
{
echo "i=$i ";
sleep(100);
$i++;
}
?>
Output:
i=0 i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 i=10

Can PHP tell when the browser goes away?

If I'm generating a stream of data to send out to a browser, and the user closes the browser, can I tell within PHP that I don't need to bother generating or sending the rest of the stream? I'd like to insert something into this loop:
while (!feof($pipes[1])) {
echo fgets($pipes[1]);
}
My fallback plan is to have the browser use a JavaScript onunload to hit another PHP page to kill the process that's generating the data, but it would be cleaner if PHP could tell when I'm echoing to nowhere.
By default PHP will abort the script if the user navigates away. There are however times where you don't want this to happen so php has a config you set called ignore_user_abort.
http://php.net/manual/en/misc.configuration.php
There's also a function called register_shutdown_function() that is supposedly executed when execution halts. I've never actually used it, so I won't vouch for how well it works, but I thought I'd mention it for completeness.
I believe that script will automatically abort when loaded normally (No ajax). But if you want to implement some sort of long polling via php using xmlhttprequest I think you will have to do it with some sort of javascript because then php can't detect it. Also like to know the precise case.
These answers pointed me towards what I was looking for. The underlying process needed special attention to kill it. I needed to jump out of the loop. Thanks again, Stack Overflow.
while (!feof($pipes[1]) && !connection_aborted())
{
echo fgets($pipes[1]);
}
if (connection_aborted())
{
exec('kill -4 '.$mypid);
}

Categories