I was expecting some error like 500 or timeout page with the following code:
<?php
ini_set('max_execution_time',5);
set_time_limit(5);
echo 'start';
sleep(10);
echo '<br/>hi';
However, I get something like this:
start
hi
Did I do something incorrect?
All I want is see the script stoped when timesout in the 5thd second, so the second echo should not be executed(I know this is quite a weird requirement)
Could anyone shred a light, thanks.
PS: seems the sleep() part is quite a distraction, how about I change the code like this:
<?php
ini_set('max_execution_time',5);
set_time_limit(5);
echo 'start';
for($i=1;$i<100000000;$i++){
if($i%100==2) echo $i;
else echo '--';
}
echo '<br/>hi';
According to this comment in php.net you must be using unix...
"Please note that, under Linux, sleeping time is ignored, but under Windows, it counts as execution time." (Sleep is not taken into consideration as part of the execution time in Unix/Linux.)
Additionally, to make it timeout simply loop forever
<?php
while (true) {
// i'll error out after max_execution_time
}
To see how long that is, you can either find out the execution time using microtime or inquire about the max_execution_time variable you just set.
$max_time = ini_get("max_execution_time");
echo $max_time
?>
UPDATE
With your updated code, the output is as expected.
Fatal error: Maximum execution time of 5 seconds exceeded in newfile.php on line 7
Related
I want to use date() function in while loop of PHP but I'm getting an error as
Fatal error: Maximum execution time of 500 seconds exceeded.
I tried to set the execution time more than the time required for the loop to complete, yet it isn't working as expected.
<?php
ini_set('max_execution_time',500);
print date("H:i");
while(date("H:i")!="16:50"){
$i=0;
}
if(date("H:i")=="16:50"){
$file = "buttonStatus.txt";
$handle = fopen($file,'w+');
$onstring = "ON";
fwrite($handle,$onstring);
fclose($handle);
$i=1;
}
echo $i;
?>
This code:
while(date("H:i")!="16:50"){
$i=0;
}
Does nothing but create an infinite loop, there is no way to exit it unless the time reaches the set time. It will literally just loop constantly and never reach the code below it.
If you want to run this script at 16:50 everyday you would be better using a cron task/job. A cron is a task that is run repeatedly, it could be every few minutes, every week, month.. whatever you need.
If you can explain what you are trying to achieve here I can give you a better solution.
I am using SLEEP(). It seems the function works, but the script waits until all my sleep() functions have ran their course before the script displays any output.
Is there a way I can get output for for 1st and then it should wait and go to next ?
echo date('h:i:s') . "<br />";
//sleep for 10 seconds
sleep(10);
//start again
echo date('h:i:s'). "<br />";
//sleep for 10 seconds
sleep(10);
//start again
echo date('h:i:s');
I need output of 1st echo and then script should wait and give second echo ....and so on
Sleep Does not matter as for as output of the page is concerned. Page is served as soon as the last sleep is done... Though it stop processing of the page on server for the time of the sleep. .. in your scenario you should be using javascript for the affect.
You see, PHP runs completely on server-side, and sleep will just make the latency of the page more severe.
As Rab has suggested, try using JavaScript instead. It's not the same as Java (in fact, a lot different), and you might like to find some good tutorials online, or get some good books (the one from Murach is really good, trust me).
I have this PHP code:
<?php
include_once("connect_to_mysql.php");
$max=300;
while($max--)
{
sleep(1);
doMyThings();
}
?>
it is supposed to repeat a mysql query 300 times with gap of 1 second between each. But the problem is after a minute or so in the browser i get this message: No Data Received. Unable to load the webpage because the server sent no data.
The problem is the following: Your code will at least (without considering the amount of time needed by doMyThings()) last 300 seconds. Most PHP environments set the default script running time to about 60 secs, the script stops and nothing is printed out.
Next thing is (if script execution time is set high enough to allow long running scripts), the script has to run until its finished (that is, ~300 secs) and after that, data is written onto the output stream. Until there, you won't see any output.
To circumvent those two problems, see this code:
<?php
// If allowed, unlimited script execution time
set_time_limit(0);
// End output buffering
ob_end_flush();
include_once("connect_to_mysql.php");
$max=300;
// End output buffering IE and Safari Workaround
// They will only display the webpage if it's completely loaded or
// at least 5000 bytes have been "printed".
for($i=0;$i<5000;$i++)
{
echo ' ';
}
while($max > 0)
{
sleep(1);
doMyThings();
$max--;
// Manual output buffering
ob_flush();
flush();
}
?>
Maybe this post is also of interest to you: Outputting exec() ping result progressively
The browser will not wait a whole 5 minutes for you to complete your queries.
You need to find a different solution. Consider executing the PHP script in CLI.
It seems that you have a timeout executing 300 times doMyThings();
You can try with set_time_limit(0);
Set the number of seconds a script is allowed to run. If this is reached, the script returns a fatal error. The default limit is 30 seconds or, if it exists, the max_execution_time value defined in the php.ini.
When you execute long time php code on server side, you need change max_execution_time directive in php.ini. But browser will not wait how long as you want so you need use async technology like AJAX
I am currently implementing a long polling function in Codeigniter and have come up a problem.
Lets say I have a normal PHP Controller:
function longpolling()
{
//PHP Timelimit infinite
set_time_limit(0);
while(true){
echo "test";
//Sleep 3 Seconds
sleep(3);
}
}
The page is just saying loading when called and does not return "test" instead you get 404 Error after a while.
What am I doing wrong?
Thank you!
You aren't doing anything 'wrong' it's just that php doesn't work the way you're expecting it to.
If you did it like this:
$i = 0;
while ($i < 10)
{
echo "Hi There!";
sleep(2);
$i++;
}
It will eventually output lots of Hi There, but not one at a time, rather it will all display at the end of the while loop.
You could even throw a flush() in there
$i = 0;
while ($i < 10)
{
echo "Hi There!";
flush();
sleep(2);
$i++;
}
And you still wont get anything until the very end.
Because your while(true) never ends you will never see any output, and I assume the browser timeout kicks in? Or the max_execution_time setting is reached?
Just popped into my head now: It might work if you wrote some data to a file in an infinite loop I have never tried it myself.
I've ran into issues like this myself. You'll have to look into flushing the output out as php and/or the webserver might be buffering the data until a certain threshold is met. I had a horrible time struggling with IIS over this, I think Apache is a lot easier to manage. Plus there's telling the webserver what to do as well. For apache, here's a snippet found on php.net:
I just had some problems with flush() and ob_flush(). What I did to
resolve this problem took me some time to figure out so I'd like to
share what I came up with.
The main problem is the php setting "output_buffering" which can be
set too large and will prevent your text from outputting. To change
this value you can either set it in php.ini or you can add the line
php_value output_buffering "0"
to your .htaccess file. It will not work with ini_set() since it is
PHP_INI_PERDIR.
This is combined with the flush() function used before sleep(). I also had to output over a number of characters before it started flushing properly:
public function longpolling()
{
echo str_repeat(" ", 1024); flush();
for( $i = 0; $i < 10; $i++) {
echo $i."<br/>";
flush();
sleep(1);
}
}
Also. I just tried this on my server and it wouldn't work until I added the php_value line to my htaccess file. Once I did, it worked as expected.
The page will keep loading until the PHP file execution has reached the end of the file. PHP doesn't work like C or C++. You make a request and when everything is done you get the output. Once the page is loaded no PHP is executing anymore.
And sleep() is just used to slow PHP down in some cases. In this case:
echo "Something";
sleep(30);
echo " else";
"Something" and " else" will be printed at the same moment while the total execution will take 30 seconds more.
I've been playing around with a system I'm developing and managed to get it to cause this:
Fatal error: Maximum execution time of 30 seconds exceeded
It happened when I was doing something unrealistic, but nevertheless it could happen with a user.
Does anyone know if there is a way to catch this exception? I've read around but everyone seems to suggest upping the time allowed.
How about trying as PHP documentation (well... at least one of its readers) say:
<?php
function shutdown()
{
$a = error_get_last();
if ($a == null) {echo "No errors";}
else {print_r($a);}
}
register_shutdown_function('shutdown');
ini_set('max_execution_time', 1);
sleep(3);
?>
Have a look at the following links:
http://www.php.net/manual/en/function.set-error-handler.php#106061
http://www.php.net/manual/en/function.register-shutdown-function.php
Your only options are to increase the allowed execution time (setting it to 0 makes it infinite, but that is not recommended) of the script or spawn a new thread and hope for the best.
The reason that this isn't catchable is that it isn't really thrown. No one line of the code actually triggered the error, rather PHP said, "Nope, sorry, this is too long. Time to shut down now." And that makes sense. Imagine having a script with a max execution time of 30 seconds catching that error and taking another 30 seconds... in a poorly designed program, that opens up some rather nasty opportunities to exploit. At a minimum, it will create opportunities for DOS attacks.
This isn't an exception, it's an error. There are important differences between exceptions and errors, first and foremost errors can't be caught with try/catch semantics.
PHP scripts are built around a paradigm of short execution times, so PHP is configured by default to assume that if a script has been running for longer than 30 seconds it must be caught in an infinite loop and therefore should be terminated. This is to prevent an errant PHP script causing a denial of service, either by accident or by malicious intent.
However, scripts do sometimes need more running time than they are allocated by default.
You can try changing the maximum execution time, either by using set_time_limit() or by altering the value of max_execution_time in the php.ini file to raise the limit. you can also remove the limit entirely by setting the execution time to 0, though this isn't recommended.
set_time_limit() may be disabled by mechanisms such as disable_functions so it might not be available to you, likewise you might not have access to php.ini. If both of these are the case then you should contact your host for help.
One exception is PHP scripts run from the command line. Under these running conditions, PHP scripts may be interactive and need to spend a long time processing data or waiting for input. For this reason there isn't a max_execution_time limit on scripts run from the command line by default.
EDIT TO ADD: PHP 7's error handling had a major overhaul. I believe that errors and exceptions are now both subclasses of Throwable. This may make the above no longer relevant for PHP7+, though I'll have to look more closely into the specifics of how error handling works now to be sure.
There is nothing you can do about it. but you can have graceful shutdown using register_shutdown_function
<?php
ini_set('display_errors', '0');
ini_set("max_execution_time",15 ); //you can use this if you know your script should not take longer than 15 seconds to finish
register_shutdown_function('shutdown');
function shutdown()
{
$error = error_get_last();
if ($error['type'] === E_ERROR) {
//do your shutdown stuff here
//be care full do not call any other function from within shutdown function
//as php may not wait until that function finishes
//its a strange behavior. During testing I realized that if function is called
//from here that function may or may not finish and code below that function
//call may or may not get executed. every time I had a different result.
// e.g.
other_function();
//code below this function may not get executed
}
}
while(true)
{
}
function other_function()
{
//code in this function may not get executed if this function
//called from shutdown function
}
?>
Yeah I tested the solution by TheJanOnline. sleep() does not count into php execution time so here is WORKING version with indefinite loop:
<?php
function shutdown()
{
$a=error_get_last();
if($a==null)
echo "No errors";
else
print_r($a);
}
register_shutdown_function('shutdown');
ini_set('max_execution_time',1 );
while(1) {/*nothing*/}
// will die after 1 sec and print error
?>
There is a little tricky way to handle "Fatal error: Maximum execution time of 30 seconds exceeded" as exception in certain cases:
function time_sublimit($k = 0.8) {
$limit = ini_get('max_execution_time'); // changes even when you set_time_limit()
$sub_limit = round($limit * $k);
if($sub_limit === 0) {
$sub_limit = INF;
}
return $sub_limit;
}
In your code you must to measure execution time and throw exception earlier than the timeout fatal error may be triggered. $k = 0.8 is a 80% of allowed execution time, so you have 20% of time to handle exception.
try{
$t1 = time(); // start to mesure time.
while (true) { // put your long-time loop condition here
time_spent = time() - $t1;
if(time_spent >= time_sublimit()) {
throw new Exception('Time sublimit reached');
}
// do work here
}
} catch(Exception $e) {
// catch exception here
}
I came up with this based on the answer #pinkal-vansia gave. So I'm not claiming an original answer, but an answer with a practical application. I needed a way for the page to refresh itself in the event of a timeout. Since I have been observing enough timeouts of my cURL script to know the code is working, but that sometimes for whatever reason it fails to connect to the remote server, or read the served html fully, and that upon refresh the problem goes away, I am ok with script refreshing itself to "cure" a Maximum execution timeout error.
<?php //script name: scrape_script.php
ini_set('max_execution_time', 300);
register_shutdown_function('shutdown');
function shutdown()
{
?><meta http-equiv="refresh" content="0; url=scrape_script.php"><?php
// just do a meta refresh. Haven't tested with header location, but
// this works fine.
}
FYI, 300 seconds is not too long for the scraping script I'm running, which takes just a little less than that to extract the data from the kinds of pages I'm scraping. Sometimes it goes over by just a few seconds only due to connection irregularities. Knowing that it's connection times that sometimes fail, rather than script processing, it's better to not increase the timeout, but rather just automatically refresh the page and try again.
I faced a similar problem and here was how I solved it:
<?php
function shutdown() {
if (!is_null($error = error_get_last())) {
if (strpos($error['message'], 'Maximum execution time') === false) {
echo 'Other error: ' . print_r($error, true);
} else {
echo "Timeout!\n";
}
}
}
ini_set('display_errors', 0);
register_shutdown_function('shutdown');
set_time_limit(1);
echo "Starting...\n";
$i = 0;
while (++$i < 100000001) {
if ($i % 100000 == 0) {
echo ($i / 100000), "\n";
}
}
echo "done.\n";
?>
This script, as is, is going to print Timeout! at the end.
You can modify the line $i = 0; to $i = 1 / 0; and it is going to print:
Other error: Array
(
[type] => 2
[message] => Division by zero
[file] => /home/user/test.php
[line] => 17
)
References:
PHP: register_shutdown_function - Manual
PHP: set_time_limit - Manual
PHP: error_get_last - Manual