well am trying to use the header to send information, but my html is already outputting information, I tried to fix the problem by using the ob_start() function to no avail
ob_start();
require('RegisterPage.php');
if(isset($_POST['register']))
{
if(register($errormsg,$regnumber))
{
$to = $_POST['email'];
$subject = "Registration";
$txt = "You need to return to the Classic Records homepage and enter the number given in order to finish your registration ".$regnumber."";
$headers = "From: registration#greenwichtutoring.com";
mail($to,$subject,$txt,$headers);
header('Location:emailNotification.html');
}
else $error=$errormsg;
}
ob_end_flush();
Check if any scripts included before the ob_start() function are outputting HTML. Sometimes an included file can contain a space after the PHP closing tag. That space will be outputed as is. To fix this, leave the PHP closing tag from your file.
E.g.
<?php
class someClass {
...
}
?><whitespace>
Can give you some good headaches. This is fine and fixes the above problem:
<?php
class someClass {
...
}
You need to call ob_start before any output has happened. So, for example, as the first statement in your main PHP script file (make sure that there is nothing before your <?php like some whitespace of a BOM).
Here you're trying to redirect to a different page and show a message. It can't happpen.
Instead, try using a link, or echo-ing:
<meta http-equiv="Refresh" content="(delay in seconds);URL=(destination)">
in your <HEAD>.
In your case, you want this to be instant, so:
<meta http-equiv="Refresh" content="0;URL=emailNotification.html">
The better alternative, is simply to not require the page until after the if.
If i remember correctly the header(); is executed at the end of the execution of the php script , so try moving it in the beginning of the if
Cheers
You have to buffer the html output, not the php logic. E.g:
ob_start();
<html>...
/* PHP */
...
ob_end_flush();
header('Location: http://www.foo.com/emailNotification.html');
1 space after Location:
and
full url
With Your Dynamic HTTP_HOST
header('Location: http://'.$_SERVER["HTTP_HOST"].'/emailNotification.html');
Chris.
Related
I am fairly new to PHP, even more so to the ob_ functions, so help me understand this, as the manual is somehow does not provide a very simple example or reference.
I am assuming that "output buffering" is what delays and holds php from sending headers until full content is sent, and that may be why the header() function does not issue an error if ob_start() is declared above. If so, my question is how do I "buffer" only some contents instead of just mentioning ob_start() at the top of my script, which is greatly slowing down my application?
Example.
<?php
namespace App\Controller;
class Home extends Controller{
public function showHomePage()
{
$students = $pdo->query('SELECT id FROM students');
$view->showContent($students); // includes content.php
}
}
//content.php
<p> showing stundent by id </p>
<?php
showContent()
{
if(!$students){
header('Location: /404');
}else{
//show students
}
}
}
Now you can see in the above example that, as soon as content.php is loaded, it will issue header already sent sent error (if $students evaluates to false/null ) so, to hide this error, I placed ob_start() inside my howHomePage method as seen here
public function showHomePage()
{
$students = $pdo->query('SELECT id FROM students');
ob_start();
$view->showContent($students); // includes content.php
}
Now, with the above approach, I get no header errors, but I would like to close that buffer as soon as the showContent() method is executed. In other means, I don't want the ob_start() to apply only for that following function. I tried to do something like this
public function showHomePage()
{
$students = $pdo->query('SELECT id FROM students');
ob_start();
$view->showContent($students); // includes content.php
on_end_flush();
}
but now, the contents showContent() are not being shown
<p> showing stundent by id </p>
<?php
showContent()
{
if(!$students){
header('Location: /404');
}else{
//show students
}
}
}
This is a terrible way to code. You've already got your output baked in, which, as you've noted, prevents you from changing the header(). This is a major driver behind MVC, which holds that you need to segment your code and separate your view(HTML) from your controller(PHP). In this case, you've put a function inline with your HTML.
There's a couple of ways to work around this without having to resort to output buffering
Do the check on $students earlier in the page (like when you get/build the data set) and issue the 404 there.
Move your HTML into a separate template file (maybe check out Smarty to help with that) and then do your drawing there.
I had the same issue and solved it by adding:
ob_implicit_flush(true);
to the beginning of the php file. This outputs everything right away and you can take your other flush commands out.
http://php.net/manual/en/function.ob-implicit-flush.php
ob_implicit_flush() will turn implicit flushing on or off. Implicit
flushing will result in a flush operation after every output call, so
that explicit calls to flush() will no longer be needed.
Does anybody have any ideas why the below page isn't redirecting?
My php file that I want to redirecting is:
<?php require_once("../includes/db_connection.php"); ?>
<?php require_once("../includes/functions.php"); ?>
<?php
if (isset($_POST['submit'])) {
} else {
redirect_to("new_subject.php");
}
?>
The functions file is:
<?php
function redirect_url($new_location)
{
header("location:".$new_location);
exit;
}
?>
I have removed the db_connection.php file to see if that makes any difference but it doesn't.
Besides the fact that the function you call and the function name you have are different ("redirect_to" vs. "redirect_url"), you also have white space before you make a header call. The space between the requires and the next PHP block is white space and will disallow setting of headers after the white space has been sent to browser.
I would highly suggest you turn on error logging in PHP and reference the error logs when investigating a problem. You would see both the function call error and the header error in your logs.
Also, it is generally pretty poor coding form to open and close PHP tags unnecessarily. You could clean this up to look like this:
<?php
require_once("../includes/db_connection.php");
require_once("../includes/functions.php");
if (!isset($_POST['submit'])) {
redirect_url("new_subject.php");
}
?>
Note here that you can keep a separation between the requires and the code to aid in readability, but since you never exit the PHP block, you don't have a white space problem.
Function name is redirect_url()
So code should be
else {
redirect_url("new_subject.php");
}
Your function call should be
redirect_url("new_subject.php");
instead of
redirect_to("new_subject.php");
You can try this,
<?php
if (isset($_POST['submit'])) {
//some thing do here
} else {
redirect_url("new_subject.php");
}
function redirect_url($new_location)
{
header("location:".$new_location);
exit;
}
?>
I have a function, 'redirect_to()' written on php script that is called after a successful update to a page on my custom CMS. It works fine on the localhost, but when I try it on my actual live domain I get the following error message:
Warning: Cannot modify header information - headers already sent by (output started at /hermes/bosweb/web119/b1192/ipg.typaldosnetcom/edit_listing.php:7) in /hermes/bosweb/web119/b1192/ipg.typaldosnetcom/includes/functions.php on line 20
Here is the code for the redirect_to() function:
function redirect_to ($location = NULL) {
if ($location != NULL) {
header("Location: {$location}");
exit;
}
}
I've made sure to call the function before I output any HTML, so I'm not sure what the problem really is.
My question: Why am I receiving this error?
It's not lying. You've output something before getting to this point. Check the locations mentioned in the error messages.
Show us the first 25 lines of each of the files mentioned.
you already sent your output to the page before you set the header. first you need to set the headers and then can the output come.
It can even be a whitespace.
It means something was already outputted on the suggested line. Try going there and see what it does.
Try pasting the surrounding code on that position for a better clarification if you can't find the problem yourself.
One common cause is to have a line after a php file you're including...
Simple solution: remove the closing php tag "?>" from all files as it's not needed..
You can test if you have a character before the opening php-script tag by removing any closing php-script tag. This way you are sure there isn't any character left (it's not needed).
Use output buffering:
<?php
ob_start();
// Test buffered output.
echo 'hello world';
function redirect_to ($location = NULL) {
if ($location != NULL) {
header('Location: ' . $location);
exit;
}
}
// rest of php file here
ob_end_flush();
?>
Docs: ob_start() and ob_end_flush()
Whenever PHP outputs an error message it disregards css and a beautifully designed page by outputting the message at the top of the page removing anything that stands in its way.
for example
some code} else {
echo "error, please do something!";
How do I get it to (or ask it nicely) to output the text inside a div that already exists inside my css so that it will obey the formatting and alignment rules that comes with that div.
You can use the following php.ini settings:
error_prepend_string = "<div class='error'>"
error_append_string = "</div>"
Or something to that effect.
EDIT
Actually, I just realized the "error" you're talking about involves an echo/print out. Here's the problem.
You're printing (echoing) the string error DIRECTLY TO the output buffer (which sends the HTML to the browser when you're finished running all your code). echo() and print() sends what you are echoing/printing straight out, unless it's in an output_buffer block (I won't confuse you with details on that).
So, you're managing your regular html/text output in such a way as to NOT print the page content out to the output buffer, but in this case you are using an echo, which sends the string data directly to the buffer AT THAT MOMENT.
For instance:
Your problem in a simple example
<?php
$mystr = "<html>";
$mystr .= "<body><h1>Hello World</h1></body></html>";
echo "<head></head>";
echo $mystr;
?>
Which would give me on output to the browser:
<head></head><html><body><h1>Hello World</h1></body></html>
I am storing the string data, but echoing the HEAD block before I echo the other html data.
What I need to do instead:
<?php
$mystr = "<html>";
$mystr .= "<head></head>";
$mystr .= "<body><h1>Hello World</h1></body></html>";
echo $mystr;
?>
Which would give me on output to the browser:
<html><head></head><body><h1>Hello World</h1></body></html>
I am storing the string output (your error, in this case) until I need to output it later. This is what you need to know, and accomplish in your code.
I would investigate error_reporting(0)/display_errors, error_get_last, and set_error_handler.
http://www.php.net/manual/en/function.error-reporting.php
http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors
http://php.net/manual/en/function.error-get-last.php
http://www.php.net/manual/en/function.set-error-handler.php
So that you could stop sending all errors immediately to the output buffer (which is why it's at the top of the page), and then capture, store and present your errors.
error_reporting(0);
set_error_handler('phpLogError');
function phpLogError() {
$error = error_get_last();
if ($error['type'] == 1) {
//do your stuff
}
}
function phpGetLoggedErrors() {
// return your prettified html errors
}
Or, in other words...
php_error_handle.php
<?php
$GLOBAL['_logged_php_errors'] = array();
error_reporting(0);
set_error_handler('phpLogError');
function phpLogError() {
global $_logged_php_errors;
$error = error_get_last();
if ($error['type'] == 1) {
$_logged_php_errors[] = "<span>$error</span>";
}
}
function phpGetLoggedErrors() {
global $_logged_php_errors;
return "<ol><li>".implode('</li><li>',$_logged_php_errors)."</li></ol>";
}
?>
other.php
<?php
require_once 'php_error_handle.php';
// other stuff, pages included/required, etc...
Just make sure this require_once happens at the first line of code.
Extending #mario above, I've used this at the top of my php file (in dev, not production of course!) which works great. Even in Wordpress admin files!
ini_set('error_prepend_string',"<div class='error'>") ;
ini_set('error_append_string',"</div>") ;
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
Try...catch
http://php.net/manual/en/language.exceptions.php
You can make the error echo in your own css.
echo '<div class="yourerrorclass">error, please do something!</div>';
If it is in the wrong place in the output, that is because you output the error too soon. The entire HTML is outputted sequentially by PHP. If you output the error before any of the other HTML, the error will be on the top of the page and will actually make your HTML invalid.
Displaying errors to screen should be entirely suppressed when running in production, instead log them to file for checking, and fixing. There are details, and the suggested settings in the php.ini file.
I've written a script to geocode some points which has a structure basically like this:
//get an unupdated record
$arr_record;
while(count($arr_record) > 0)
{
//strings are derived from $arr_record
geocode($string1);
geocode($string2);
geocode($string3);
array_pop($arr_record);
}
function geocode($string) {
//if successful
update($coords)
}
function update($coords) {
//update the database
header('Location:http://localhost/thisfile.php')
}
The trouble is that even when the geocode is successful and the database is updated, and teh header resent, the script still goes back into the while loop without reloading the page and starting again on a new record.
Is this normal behaviour for PHP? How do I avoid it behaving like this?
After header() use die(); to terminate the script and output.
How do I avoid it behaving like this?
Put exit() after header().
another effective way is not to send headers directly in a loop. which is not proper (i couldn't find in php.net manual but i remember it was discussed before in phpusenet).
it may act unexpected in different php versions. & different apache ver. installations.
php as cgi will make problems too.
you can assign it to return as string then you can send header later...
function update($coords) {
//update the database
if(statement to understand update is ok){
return 'Location:http://localhost/thisfile.php';
} else {
return false;
}
}
if($updateresult=update($cords)!=false){ header($updateresult); }
but if i were you... i would try to work ob_start() ob_get_contents() ob_end()
because those are the excellent way to control what will be sent to browser. normal mimetypes or headers... whatever. it's better way while working with headers & html output at the same time.
ob_start(); /* output will be captured now */
echo time(); /* echo test */
?>
print something more...
<?php /* tag test */
/* do some stuff here that makes output. */
$content=ob_get_contents();
ob_end_clean();
/* now everything as output with echo, print or phptags.
are now stored into $content variable
then you can echo it to browser later
*/
echo "This text will be printed before the previous code";
echo $content;