Question

How to Check Whether a PHP Session Has Started

phpsessionsession-variables

Question

I have a PHP file that is sometimes included from a page that has already started a session, and sometimes from a page that has not started one yet. Because of that, calling session_start() in this script sometimes triggers a “session already started” warning.

I tried checking for the session cookie first:

if (!isset($_COOKIE['PHPSESSID'])) {
    session_start();
}

But then I ran into this notice:

Notice: Undefined variable: _SESSION

What is the correct way to check whether a session has already started in PHP?

Would using @session_start() make this work properly, or would it only hide the warnings?

Short Answer

By the end of this page, you will understand how PHP sessions work, why checking the PHPSESSID cookie is not a reliable way to know whether a session is active, and how to safely call session_start() only when needed. You will also learn why suppressing errors with @session_start() is usually the wrong fix and how to use $_SESSION correctly.

Concept

PHP sessions let you store data across multiple requests for the same user. Common examples include login state, shopping cart contents, and user preferences.

A session is not the same thing as a session cookie:

  • The session cookie usually contains a session ID such as PHPSESSID.
  • The active PHP session exists only after PHP has initialized session handling for the current request.

That means this is important:

  • A cookie may exist even if session_start() has not been called yet in the current script.
  • A cookie may be missing, and PHP can still create a new session when session_start() runs.
  • $_SESSION is only reliably available after the session has been started.

So checking $_COOKIE['PHPSESSID'] does not answer the question “Has the session already been started in this request?”

The real concept is: session state is managed by PHP, not by manually checking the cookie.

In modern PHP, the correct tool is session_status(), which tells you whether sessions are disabled, not started, or already active.

Why this matters in real programming:

  • Included files often run in different contexts.
  • Reusable code should not assume a session is always active.
  • Hiding warnings can leave real bugs in place.
  • Proper session checks prevent notices and duplicated initialization.

Mental Model

Think of a PHP session like a locker system at a gym:

  • The cookie is like a locker key number in your pocket.
  • session_start() is like going to the desk and opening the locker system for this visit.
  • $_SESSION is the actual locker contents you can access only after the system has been opened.

Just because you have a key number does not mean the locker is already open right now. You still need the front desk process for the current visit.

So:

  • Cookie present = you may have a known locker ID.
  • Session started = the locker is actually opened for this request.
  • $_SESSION usable = you can now read and write locker contents.
Take Quiz

Syntax and Examples

The safest modern approach is to check session_status() before calling session_start().

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

This means:

  • PHP_SESSION_NONE: no session has been started yet for this request.
  • session_start(): start or resume the session.

Example: safe reusable file

<?php
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

$_SESSION['username'] = 'alice';
echo $_SESSION['username'];

This file works whether:

  • the session was already started earlier, or
  • no session had been started yet.

Older PHP pattern

If you are working with older PHP versions that do not support session_status(), people often used this pattern:

<?php
if (session_id() === '') {
    session_start();
}

This checks whether a session ID exists for the current request. It is older and less clear than session_status(), but still better than checking the cookie manually.

What not to do

if (!isset($_COOKIE['PHPSESSID'])) {
    session_start();
}

Why this is unreliable:

  • The cookie may exist even if the session has not been started in this request.
  • The session name may not be PHPSESSID.
  • Cookies can be disabled or renamed.
  • PHP can create a new session even without an existing cookie.

Step by Step Execution

Consider this example:

<?php
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

if (!isset($_SESSION['count'])) {
    $_SESSION['count'] = 1;
} else {
    $_SESSION['count']++;
}

echo $_SESSION['count'];

Step by step

  1. PHP reaches the session_status() check.
  2. If no session is active yet, session_start() runs.
  3. PHP loads the session data for the current session ID, or creates a new session if needed.
  4. Now $_SESSION becomes available.
  5. The script checks whether $_SESSION['count'] exists.
  6. If it does not exist, it is set to 1.
  7. If it already exists, it is incremented.
  8. The updated count is printed.

First request

  • No active session yet.
  • session_start() starts one.
  • $_SESSION['count'] does not exist.
  • Output: 1

Second request from the same user

  • Session resumes.
  • $_SESSION['count'] already exists.
  • It becomes 2.
  • Output: 2

The important lesson is that $_SESSION should be used after the session is active.

Real World Use Cases

Sessions are used in many common PHP applications:

User authentication

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

$_SESSION['user_id'] = 42;

Used to remember who is logged in.

Shopping cart

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

$_SESSION['cart'][] = ['id' => 10, 'qty' => 2];

Used to keep cart items across page loads.

Flash messages

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

$_SESSION['flash'] = 'Profile updated successfully';

Used to show one-time status messages after redirects.

Multi-step forms

Store partially completed form data between steps.

Admin dashboards

Keep role and permission data available between requests.

Take Quiz

Real Codebase Usage

In real projects, developers usually avoid calling session_start() randomly in many files. Instead, they use clear patterns.

Central bootstrap file

A common approach is to start the session once in a front controller, config file, or bootstrap file.

<?php
// bootstrap.php
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

Then other files assume the environment is ready.

Guard clause pattern

If a file truly needs a session, it can guard safely:

<?php
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

This is a simple early check before any session access.

Validation before reading keys

Even after the session is active, individual keys may not exist.

if (isset($_SESSION['user_id'])) {
    echo $_SESSION['user_id'];
}

This prevents undefined index notices.

Authentication checks

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

if (!isset($_SESSION['user_id'])) {
    die('Access denied');
}

Error handling mindset

Good code fixes the cause of warnings rather than suppressing them. If session warnings appear, the solution is usually:

  • start the session in one predictable place,
  • check session state properly,
  • avoid output before session_start().

Common Mistakes

1. Checking the cookie instead of session state

Broken approach:

if (!isset($_COOKIE['PHPSESSID'])) {
    session_start();
}

Why it is wrong:

  • Cookie existence does not mean the session is active in this request.
  • The cookie name can be changed.

Use this instead:

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

2. Using $_SESSION before starting the session

Broken code:

echo $_SESSION['username'];

If the session is not active yet, this can cause notices or unexpected behavior.

Correct:

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

if (isset($_SESSION['username'])) {
    echo $_SESSION['username'];
}

3. Suppressing warnings with @session_start()

@session_start();

Why this is a bad idea:

  • It hides useful warnings.
  • It does not fix incorrect program logic.
  • It makes debugging harder.

4. Confusing $_SESSION with _SESSION

Broken code:

echo _SESSION['username'];

Correct code:

echo $_SESSION['username'];

In PHP, superglobals need the $ sign.

5. Sending output before session_start()

Broken code:

echo 'Hello';
session_start();

This can trigger header-related warnings because sessions often need to send headers.

Correct:

session_start();
echo 'Hello';

6. Assuming a session key always exists

Broken code:

if ($_SESSION['is_admin']) {
    // ...
}

Correct:

if (!empty($_SESSION['is_admin'])) {
    // ...
}

Comparisons

ApproachWhat it checksReliable?Notes
isset($_COOKIE['PHPSESSID'])Whether a cookie with that name existsNoCookie presence is not the same as an active session
session_id() === ''Whether a session ID is currently availableMostlyOlder pattern; works in many cases
session_status() === PHP_SESSION_NONEWhether PHP says no session is activeYesBest modern choice
@session_start()Suppresses warnings while attempting to startNoHides problems instead of solving them

$_COOKIE vs $_SESSION

VariablePurpose
$_COOKIEStores cookie values sent by the browser
$_SESSIONStores server-side session data after the session is started

isset() vs empty() for session values

FunctionBest use
isset($_SESSION['key'])Check whether a session key exists
empty($_SESSION['key'])Check whether a value is missing or falsy
Take Quiz

Cheat Sheet

// Best practice: start session only if needed
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}
// Then safely read/write session values
$_SESSION['name'] = 'Alice';

echo $_SESSION['name'];
// Safe existence check
if (isset($_SESSION['name'])) {
    echo $_SESSION['name'];
}

Rules

  • Use session_status() in modern PHP.
  • Do not use the session cookie to detect active session state.
  • Do not suppress warnings with @session_start().
  • Start sessions before output when possible.
  • Access $_SESSION only after session initialization.
  • Check keys with isset() or empty() before using them.

Older compatibility pattern

if (session_id() === '') {
    session_start();
}

Common error signs

  • session already started → you called session_start() again unnecessarily.
  • headers already sent → output happened before starting the session.
  • Undefined variable: _SESSION → you likely wrote _SESSION instead of $_SESSION.

FAQ

How do I know if a PHP session is already started?

Use:

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

Is checking PHPSESSID enough to know whether a session is active?

No. It only tells you whether a cookie exists, not whether PHP has started the session in the current request.

Should I use @session_start() to hide warnings?

Usually no. It only suppresses the warning and can hide real bugs in your code.

Why do I get Undefined variable: _SESSION?

Because the correct PHP superglobal is $_SESSION, with a $ sign.

Can I use $_SESSION without calling session_start()?

You should not rely on that. Start or resume the session first, then access $_SESSION.

Why does session_start() sometimes fail after echo?

Because session handling often sends HTTP headers. If output has already been sent, PHP may raise a headers already sent warning.

What is the best place to start a session in a real app?

Usually in one central file such as a bootstrap, front controller, or application entry point.

Take Quiz

Mini Project

Description

Build a small page visit tracker that safely starts a session only when needed and stores how many times the current user has visited the page. This demonstrates correct session startup, reading from $_SESSION, and updating session data without duplicate session_start() warnings.

Goal

Create a PHP script that counts visits for the current user using sessions.

Requirements

  1. Start the session only if it is not already active.
  2. Initialize a visit counter in $_SESSION if it does not exist.
  3. Increase the counter on each page load.
  4. Display the current visit count.
  5. Avoid using @session_start() or cookie-based session checks.
Take Quiz

Keep learning

Related questions

View more