PHP header in a loop - php

Is it possible to "call" a PHP script in a loop like this ?
...
while (...)
{
...
header("Location:myscript.php");
...
}
...

Nope. header("Location: ...") is supposed to redirect the browser to a different page, so only one of the calls you make will take effect.
What do you want to do?

You can always include the script from another to execute it's logic:
include('myscript.php');
In principle, this shouldn't require refactoring any myscript.php code. Be forewarned - myscript.php and the containing script will share the same global namespace, which may introduce bugs. (For instance, if the container outputs HTML and myscript calls session_start() a warning will be generated).

What you propose should work fine, however not in the way you expect. The header() function simply sends information to the browser in a single batch before the script content (You modify the http headers). So when the script finishes execution the browser will go to the specified page, hence only the last call to header('Location... will have any effect and that effect will only happen when the php script has finished executing.
A good way to do what I think you want to do would be to encapsulate the functionality of 'myscript.php' into a function.
include 'myscript.php';
while (...)
{
...
myscriptFunction();
...
}
...

You can call header() in a loop, but with the location header, the browser will only follow one.
location:<url> tells the browser to go to the url specified. it is known as a 301 redirect. Why you would call it in a loop, I don't know.

No. Rather pass it as a request parameter, assuming you're trying to redirect to self. E.g.
<?php
$i = isset($_GET['i']) ? intval($_GET['i']) : 10; // Or whatever loop count you'd like to have.
if ($i-- > 0) {
header("Location:myscript.php?i=" . $i);
}
?>
I however highly question the sense/value of this :)
Update, you just want to include a PHP script/template in a loop? Then use include() instead.
while ( ... )
include('myscript.php');
}
If it contains global code, then it will get evaluated and executed that many times.

Related

PHP to call itself with a new paramter value

I have a PHP that receives a parameter (for example 4000) it uses to query a DB with. After executing whatever it needs to do, I want the PHP to call itself so it can do the exact same thing but this time with the new value (for example 8000). Ofocurse I need the first instance to stop/exit/halt.
How can I do this? Include is irrelevant and exec is good for other types of execution (unless I'm wrong here)
Thanks
If you are not required to output anything from the script, you could do the following:
Perform the task while not running into script timeout
Set a location header to the script itself with modified parameters
exit
If you want the script to produce output, you can use the Javascript function location.href instead of the location header. For this, output something like the following snippet at the end of your script:
// php functionality above
?>
<script language="JavaScript">
location.href = "<?php echo $_SERVER['SCRIPT_NAME']; ?>?param=<php echo $param_value; ?>";
</script>
Modify this to fulfill your needs. The header is more suitable for non-interactive setups like the links2 browser, whereas the JavaScript you would use if you want to see whats going on.
You could use recursive functions, which simply means calling the same function from that function. Simple example based on the numbers you gave:
<?php
function do_something( $arg )
{
// Just do something (example)
echo $arg . "\n";
$arg = $arg + 4000;
// Stop doing it when the argument is above 8000
if( $arg > 8000 )
{
return;
}
// Do it again
do_something( $arg );
}
do_something( 4000 );
You can make the script call itself by using the header() method.
Let's say you want to retrieve a batch of 24 rows at every run of a script named whatever.php.
You tell whatever.php to look out for a $_GET parameter. If there is none, you tell it to start from zero when querying the database ("...LIMIT 24"). After you've done what you needed to use header() method in order to call whatever.php again:
header('Location:whatever.php?offset=25');
Now the whatever.php, when called, will know that it must impose an offset to the sql LIMIT ("...LIMIT 25, 24"). After the script done it's job again, you call it again with the header() method:
header('Location:whatever.php?offset=50');
Hope this helps you...

Is the die() or exit() function needed in the end of a php script?

In a php script I have some test and after the script the html page.
When a test fail i call die("Test 1 failed");
If no test fail the php script reach the end ?> and then load the html code after the php script.
Is this a good procedure? Or I need to write die() or exit() before the end of php script?
No you don't have to write that and this is not best practice. If the script reaches the end without fatal errros it will exit.
If this means "testing" for you, you're wrong. Testing should be done using unit tests. For php there is phpunit. Give it a try, that's the proper way of testing your code.
Edit: As CompuChip says in a comment, the only useful use case for exit is when you're writing a php based shell script that should return an error code. See the parameter section of the documentation for the exit() function.
You should never be using die() or exit in your production PHP scripts except in very specific cases. Instead, re-work your code paths to simply show an error message to the user rather than exiting the script early.
No you don't need that, but when writing console PHP scripts, you might want to check with for example Bash if the script completed everything in the right way. That's when you use exit() or die()
Is the die() or exit() function needed in the end of a php script?
No, PHP will end the script itself. If the script is an included file (called from another file) then it will end script in the included file and then continue with any code in the original file after where you included (if there is any code).
So you put die() or exit() where ever you want or need it.
For testing, put it after each block of code you test. I use them in some parts of testing if I just want PHP to show me something then stop, such as print out an array to make sure it's being constructed correctly etc.
eg:
print_r($array);
exit();
For other code tests, I sometimes just echo "Section A worked", etc, such as within if/else. If I want to know if a particular part of code is working or if some criteria is being met or not (basically, it lets you trace where PHP itself is going within your code).
All that said, don't use die() or exit() in production code. You should use a more friendly and controlled messaging setup. For security reasons and visual, as you could potentially give them some info like "ERROR Failed to load SomethingSecret". Also it doesn't look pretty when you page only half loads and then puts out an on screen error message which likely means nothing to the end user.
Have a read through this:
PHP Error handling: die() Vs trigger_error() Vs throw Exception
No !
This is not recommanded to use it
Use trigger_error or error_log to log the tests in your error.log. Then check it.
No you don't have to use these functions at the end of the script, because it exists anyway at the end of the script.
No need to put a die or an exit at the end of the scipt.
But you may use exit to terminate your script with a specific exit code (by default it's 0).
E.g
$ php -r "/* does nothing */;"
$ echo $?
0
$ php -r "exit(123);"
$ echo $?
123
http://php.net/exit
From the documentation:
The link to the server will be closed as soon as the execution of the
script ends, unless it's closed earlier by explicitly calling
mysql_close().
https://secure.php.net/function.mysql-connect
Nope, you don't need to call die() or exit(0 if you have another code to run, like you HTML code

php redirect immediately and also continue execution which dont send data

I need to execute a bunch of functions that consume nearly 50 seconds to complete. But i want redirect to page after execution few function itself and also continue further execution.
The below function execute on form submit as in process.php // it wont echo anything
// all function in serprate process page.
func1
func2
func3
// After above 3 function i need to php redirect to redirect now immediately example.com
func4
func5
func6
I tried using php header but it won't immediately redirecting.
header("Location:http://www.example.com");
If I use exit(); it will redirect but not process function 4,5 and 6.
what i need is any way to redirect immediately after first 3 functions and continue execution.
On paper, you can achieve this by combining flush() and ignore_user_abort():
ignore_user_abort(true);
do_stuff();
send_redirect();
flush();
do_more_stuff();
Manual pages:
http://php.net/manual/en/function.flush.php
http://php.net/manual/en/function.ignore-user-abort.php
Note the known caveats: some browsers (old IEs in particular, and possibly new ones) want a minimum amount of bytes received before processing what you send them, so you might end up needing to toss in some long string in an html comment for it to work as expected.
In practice, the more conventional approach is to register a cron job task in some table, and have a cron.php file take care of pending tasks in a completely separate (and independent) request.
A less conventional approach is also highlighted in the comments: issue a shell command or something to that order — be very wary of sanitizing input if you do that.
Adding this for reference (see comments below):
<!-- IE bug fix: pad the page with enough characters such that it is greater than 512 bytes, even after gzip compression abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono
—>
References:
http://www.clintharris.net/2009/ie-512-byte-error-pages-and-wordpress/
http://core.trac.wordpress.org/ticket/8942
http://core.trac.wordpress.org/ticket/11289
(Actually applies only for http errors, after re-going through it.)
Try to split your process.php in two files : process.php and process_more.php (i.e.). Assuming your are under a unix os server :
Code for process.php :
// code to execute before redirect
func1();
func2();
func3();
// code to execute after redirect in background
// you can pass some parameters
$command = "php -f /path/to/process_more.php param1 param2"
exec($command . " > /dev/null &");
header('Location: http://dn.tld/');
exit();
See more to use parameters with $argv variable, and be careful to prevent the user for injecting another command within the parameters
Code for process_more.php :
func2();
func3();
func4();
Not that you won't be able to access $_GET or $_POST variables. You need to pass any variable you want within the call command.

Auto-execute a function after everything else has executed

Basically, I have a script that is included at the top of a page that does a bunch of things, the most important being an ob_start(). Then in the body of the page I have a variety of tags that will be replaced, such as {hello_word}. Then at the very end, I include another script that ends the output buffer, and makes the tag replacements with other code, then prints.
Is there any possible way to do this without having to include my second file at the end? Is there some simple way I can automatically execute a function or include a file at the very end?
You can register a function to be executed at the very end of script using register_shutdown_function
Any objects that you have remaining will be destroyed at the end of the script, and their destructors will be called (manual). You can put code that you want executed at the end in the destructor.
For example:
Class Waitforme {
function __destruct() {
echo "I'm here!";
}
}
$hello = new Waitforme();
This will do nothing until $hello is destroyed, at which time we'll see "I'm here!"
You can use the auto_append setting in php.ini, but you'll sacrifice portability. If you don't plan on distributing your application, this is a good option.

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