-1

I have an index.php file in which when the button is clicked it redirects to another page.php. However, the redirect does not work. Adding ob_start() and ob_end() does not change the situation. The contents of the index.php file look like this:

<?php ob_start();?>
<!DOCTYPE html>
<html>
<head>
<?php if (isset($_POST['link-btn'])) {  
    header("Location:page.php"); 
    exit();} ?>
</head>
<body>
<section id="main">
    <form method="post"> 
    <button type="submit" name="link-btn">Next page</button>
    </form>
</section>
</body>
</html>
<?php ob_end();?>
  • There is no ob_start() in your code. And have you tried to move the ` – hakre Jul 16 '23 at 12:57
  • Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. It is a very common error to read code with include, or require, functions, or another file access function, and have spaces or empty lines that are output before header() is called. The same problem exists when using a single PHP/HTML file. https://www.php.net/manual/en/function.header.php ☺️ – deEr. Jul 16 '23 at 13:01
  • The site has ob_start() and ob_end(). Moving the block from – Grzegorz Komarzyniec Jul 16 '23 at 13:03
  • @GrzegorzKomarzyniec, based on your response to my answer, it sounds like the line of `header("Location:page.php");` is being called. As such, please can you provide all response headers that are being returned. In Firefox, I can get these by opening Web Developer Tools, and going to the Network tab. After then refreshing the page, you should be able to click the entry for your index.php – SimonMayer Jul 16 '23 at 13:49
  • Once you have the response headers, please edit your question to include them. This might help in case either the location header is missing, badly formed, or some other anomaly is occurring with the headers in general – SimonMayer Jul 16 '23 at 13:51
  • 1
    define "does not work" – Your Common Sense Jul 16 '23 at 14:39
  • that being said, and I understand it's really not what you asked, but is that form actually submitting anything? if not, maybe the venerable anchor element could do what you want? `Click Me`. – Félix Adriyel Gagnon-Grenier Jul 16 '23 at 20:35

2 Answers2

0

According to https://www.php.net/manual/en/function.header.php:

Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP.

I think you're confusing the HTTP header with the HTML element. They are different things.

This should work:

<?php 
if (isset($_POST['link-btn'])) {  
    header("Location:page.php"); 
    exit();
} 
?>
<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <section id="main">
            <form method="post"> 
                <button type="submit" name="link-btn">Next page</button>
            </form>
        </section>
    </body>
</html>

Alternatively, you can redirect a page using a meta tag in the HTML head (perhaps this is the source of your confusion), although for this use case, it's probably a bad idea, as you're sending html and relying on the browser. e.g. <meta http-equiv="Refresh" content="0; url='https://www.w3docs.com'" />

On a more general note, it looks like you're using buttons and form submission for page navigation. I'd caution against custom approaches like this, as they add complexity. Deviation from standard approaches makes code harder to support, and can majorly impede accessibility.

SimonMayer
  • 4,719
  • 4
  • 33
  • 45
  • I did it this way, but it doesn't work. Strange situation, because on another site I once did it in an analogous way for many subpages and it works. – Grzegorz Komarzyniec Jul 16 '23 at 13:16
  • What if you remove the if statement? I'm curious whether the problem is that header() isn't working as expected, or it's simply not even being called. – SimonMayer Jul 16 '23 at 13:22
  • The if statement works because I inserted an echo in place of the header. Removing the if statement doesn't move to another page. Strange because there is another page on the server in the same directory, where I used a similar solution a long time ago and it works. I can't find the difference. – Grzegorz Komarzyniec Jul 16 '23 at 13:37
  • In XAMPP, the solution works. When transferred to the server, it stops working. – Grzegorz Komarzyniec Jul 16 '23 at 13:46
  • @GrzegorzKomarzyniec That sounds like the server generates content _before_ the `ob_start`. Examining the source code of the response would help here. Otherwise, maybe the page.php does not exist? Is the path absolute or relative? – Félix Adriyel Gagnon-Grenier Jul 16 '23 at 20:37
-1

Right now you have a page that have html tag, therefore it seems like you have Response status 200 OK, you only set header with Location in it. I would probably go in a slightly different way:

<?php 
    if (isset($_POST['link-btn'])) {  
       header("Location:page.php", true, 301); 
    } else {
?>

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<section id="main">
    <form method="post"> 
    <button type="submit" name="link-btn">Next page</button>
    </form>
</section>
</body>
</html>
<?php } ?>

What you really need to do is to create this type of HTTP Response

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301

I believe that you have writen the PHP code into the HTML <head> element, because you know that this contains header. But be aware in here. You have HTTP Response (or HTTP Request) with headers. And then you have headers in your HTML, which is the body (not header) of the HTTP Response. Therefore you are setting header() in PHP for the HTTP Response, but that is fine anywhere in the code before the code is sent (that's when you get common error "headers have already been sent"). Once the HTTP Response is out there, you can not modify it. Therefore it's the best to create all of it at once, then create HTTP Response and then send it.

If you look here

https://github.com/symfony/symfony/blob/6.4/src/Symfony/Component/HttpFoundation/Response.php#L241

you will see method __toString that actually creates the HTTP Response itself, this is what browser is getting from the server. To learn this it's the best way how to understand the web :)