Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To move a browser to another PHP page, call header('Location: ...') before sending any HTML or other output, then call exit;. Start the session and check access before rendering the page, too: session_start() also needs to run before output. If PHP reports that headers were already sent, its file-and-line location identifies where output began.

Redirect to another page with header()

PHP’s header() documentation says the function must run before any actual output, including HTML tags, blank lines, or output from PHP. A Location: header tells the browser to request a different URL; PHP sends a 302 redirect by default unless you set another applicable status. End the request with exit; so the current script does not continue running after the redirect.

<?php
header('Location: index.php');
exit;

This is an HTTP redirect, so the browser normally navigates to the destination and updates the address bar. If you want to display another page while keeping the current URL visible, use server-side routing or an include/rendering approach instead.

Start the session and check access before rendering

session_start() creates a session or resumes an existing one. For cookie-based sessions, PHP requires it to run before output reaches the browser, because it may need to send session-related headers. Put session startup and access checks at the top of the request, before a template, markup, or included file that renders content.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<?php
session_start();

if (!isset($_SESSION['user_id'], $_SESSION['logged_in'])) {
    header('Location: index.php');
    exit;
}

require_once 'function.php';
?>
<!-- Render the page only after the checks above. -->

The two-key isset() check above redirects if either session value is missing. Adapt the condition to the access rule your application actually needs. PHP’s session_start() documentation explains the session behavior and the requirement to call it before browser output.

Find what was sent too early

In the SitePoint thread, the reported warning was session_start(): Cannot send session cache limiter - headers already sent. The follow-up message pointed to output beginning at home.php:27, before session_start() ran in header.php on line 5. The page had already emitted an opening <div> before requiring that file. The lesson is to check the first file-and-line location in the warning: it points to the earlier output that prevented PHP from sending headers later.

Output is not limited to visible page content. Check the named file and any files it includes for:

  • HTML or a PHP echo or print before session startup or the redirect.
  • Spaces or blank lines before the opening <?php tag.
  • A closing ?> tag followed by whitespace or a blank line in a PHP-only file.
  • A UTF-8 byte order mark (BOM) at the start of a file.

Included and required files can trigger the same warning as output in the main page. Trace the execution order: a session startup inside header.php is already too late if the calling page printed markup before requiring it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Choose control-flow placement instead of masking the issue

Run request control before templates

For predictable behavior, put session startup, authorization checks, and redirects in a bootstrap or at the top of each relevant page, before rendering begins. A shared bootstrap can centralize the logic; if checks live in individual pages, keep them consistently ahead of output.

Use output buffering only deliberately

Output buffering can postpone sending content, which may allow headers to be added later. It does not fix the underlying ordering problem: session and redirect behavior then depends on buffering being active. Prefer putting control logic first; if buffering is an intentional design choice, make that choice explicit and consistent.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.