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. $_SESSIONis 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.$_SESSIONis 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.
$_SESSIONusable = you can now read and write locker contents.
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
- PHP reaches the
session_status()check. - If no session is active yet,
session_start()runs. - PHP loads the session data for the current session ID, or creates a new session if needed.
- Now
$_SESSIONbecomes available. - The script checks whether
$_SESSION['count']exists. - If it does not exist, it is set to
1. - If it already exists, it is incremented.
- 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.
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
| Approach | What it checks | Reliable? | Notes |
|---|---|---|---|
isset($_COOKIE['PHPSESSID']) | Whether a cookie with that name exists | No | Cookie presence is not the same as an active session |
session_id() === '' | Whether a session ID is currently available | Mostly | Older pattern; works in many cases |
session_status() === PHP_SESSION_NONE | Whether PHP says no session is active | Yes | Best modern choice |
@session_start() | Suppresses warnings while attempting to start | No | Hides problems instead of solving them |
$_COOKIE vs $_SESSION
| Variable | Purpose |
|---|---|
$_COOKIE | Stores cookie values sent by the browser |
$_SESSION | Stores server-side session data after the session is started |
isset() vs empty() for session values
| Function | Best use |
|---|---|
isset($_SESSION['key']) | Check whether a session key exists |
empty($_SESSION['key']) | Check whether a value is missing or falsy |
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
$_SESSIONonly after session initialization. - Check keys with
isset()orempty()before using them.
Older compatibility pattern
if (session_id() === '') {
session_start();
}
Common error signs
session already started→ you calledsession_start()again unnecessarily.headers already sent→ output happened before starting the session.Undefined variable: _SESSION→ you likely wrote_SESSIONinstead 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.
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
- Start the session only if it is not already active.
- Initialize a visit counter in
$_SESSIONif it does not exist. - Increase the counter on each page load.
- Display the current visit count.
- Avoid using
@session_start()or cookie-based session checks.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.