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

Store a small PHP shopping cart in $_SESSION['cart'], using a stable SKU or product ID as each line’s key and keeping only the quantity and selected variant in the session. Reload names, prices, stock, tax, and availability from your product catalog whenever you display the cart or process checkout; never treat a browser-submitted or session-stored price as authoritative.

Choose a cart data shape

PHP arrays support string keys and nested arrays, so an associative array works well for cart lines. A stable product identifier makes it straightforward to find, update, or remove a line. If customers can buy the same product in different variants, include the validated variant identifier in the line data or in a composite key so distinct variants do not overwrite one another.

$_SESSION['cart'] = [
    'SKU-123' => [
        'quantity' => 2,
        'variant' => 'blue-medium',
    ],
];

This example stores the SKU, quantity, and variant—not a trusted product name or price. PHP arrays can contain nested values and do not require consecutive integer keys; see the PHP arrays documentation and the PHP language specification for arrays.

Start or retrieve the session and add an item

Call session_start() before sending output. It retrieves an existing session or creates one and makes its data available through $_SESSION. PHP serializes session data at shutdown; file-based storage is the default handler. The PHP session handling guide describes sessions as a way to preserve data across subsequent accesses.

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

if (!isset($_SESSION['cart'])) {
    $_SESSION['cart'] = [];
}

// Validate these values before this point.
$sku = (string) $validatedSku;
$quantity = max(1, min($requestedQuantity, 99));

if (isset($_SESSION['cart'][$sku])) {
    $_SESSION['cart'][$sku]['quantity'] += $quantity;
} else {
    $_SESSION['cart'][$sku] = [
        'quantity' => $quantity,
        'variant' => $validatedVariant,
    ];
}

session_write_close();

The quantity cap of 99 is an example policy, not a PHP requirement: choose a limit that matches your store’s rules and current stock. Validate the SKU and variant against your catalog before writing them to the cart. Close the session after the request has made its changes if it no longer needs to modify session data.

Update or remove a cart line

Validate an update as an integer quantity, then set that SKU’s quantity. Treat zero as a request to remove the line. Check that the SKU is present and valid before changing the array.

<?php
// Assume the session is started and $sku is validated.
$quantity = filter_var(
    $_POST['quantity'] ?? null,
    FILTER_VALIDATE_INT,
    ['options' => ['min_range' => 0, 'max_range' => 99]]
);

if ($quantity === false) {
    http_response_code(400);
    exit('Invalid quantity');
}

if ($quantity === 0) {
    unset($_SESSION['cart'][$sku]);
} elseif (isset($_SESSION['cart'][$sku])) {
    $_SESSION['cart'][$sku]['quantity'] = $quantity;
}

For a remove action, the essential operation is unset($_SESSION['cart'][$sku]). Protect add, update, remove, and checkout requests against cross-site request forgery with CSRF tokens; PHP sessions and authentication alone do not provide CSRF protection.

Build displayed lines and totals from the catalog

When rendering the cart, use the stored identifiers to load current product data from the authoritative catalog. Recheck availability and stock, and calculate line totals, tax, and the checkout total using current trusted values. Do not accept a posted price or description as a source of truth. Revalidate prices and stock at checkout because catalog conditions may change between viewing the cart and placing an order.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Session cart: product identifier, validated variant identifier, and quantity.
  • Catalog or database: product name, current price, tax rules, stock, and availability.
  • Checkout: authoritative recalculation and validation before accepting payment or creating the order.

Keep the session cart secure and responsive

  • Serve the site over HTTPS/TLS and configure session cookies with the Secure and HttpOnly attributes; use SameSite where appropriate.
  • Enable session.use_strict_mode, and regenerate session IDs when privileges change. PHP’s session security guidance covers session-ID protections and related risks.
  • Use CSRF tokens on every state-changing cart and checkout request.
  • Keep the cart payload small. With file-based sessions, PHP locks the session while it is open; in AJAX-heavy flows, finish required session changes and call session_write_close() early to avoid unnecessary blocking. Choose another session backend if its concurrency behavior better fits the application.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When a session array is enough—and when it is not

A session array is a practical choice for a small anonymous cart used on one device. It is quick to implement, but its lifecycle follows the session, so it is not a durable record once that session expires. A database-backed cart keyed to a user account is more suitable when the cart must survive session expiry, appear across devices, be recoverable, or support reporting. The database design adds durable state and queryability, along with additional persistence and operational work.

Consideration Session array Database-backed cart
Persistence after session expiry Cart follows session lifetime; not a durable cart record. Can persist beyond session expiry when stored and retained by the application.
Cross-device access Designed for the current session, typically one device. Can be associated with an account and retrieved on another device.
Concurrency File-based sessions lock while open; backend behavior varies. Supports application-defined shared updates, but requires conflict-handling decisions.
Catalog-price authority Must still reload current values from the catalog. Must still use the catalog as the source of current price and availability.
Recovery and observability Limited by session lifetime and visibility. Durable records can support recovery and query-based reporting.
Operational complexity Quick to implement with little additional persistence machinery. Requires schema, storage, and lifecycle management.

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.