← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

PHP SAPI Types (FPM, CLI, Embed)

PHP PHP 4.0+ Intermediate
debt(d7/e3/b3/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7), since PHPStan listed in detection_hints won't reliably catch CLI-only functions used in web context or assumptions about $_SERVER population; issues typically surface at runtime in the wrong SAPI.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3), since quick_fix is a PHP_SAPI conditional guard plus separate php.ini pool configuration — small pattern replacement but touches both code and config.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3), since SAPI-awareness affects bootstrap/entrypoint code and config but doesn't shape the whole codebase; most business logic is SAPI-agnostic.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7), since the misconception (FPM workers persist state between requests) contradicts how long-running app servers in other ecosystems work (Node, Python ASGI, Java), leading developers to wrongly cache state in globals.

About DEBT scoring →

TL;DR

SAPI (Server API) defines how PHP is invoked — php-fpm for web requests, php-cli for commands, embed for C extensions — each has different lifecycle and configuration.

Explanation

PHP SAPIs: php-fpm (FastCGI Process Manager) — long-running pool of workers handling web requests, separate PHP-FPM pool config, per-request memory reset. php-cli — single execution, unlimited max_execution_time by default, used for scripts, cron, queues. php-cgi — legacy CGI, spawned per request. apache2handler — mod_php embedded in Apache. embed — PHP embedded in C apps. php_sapi_name() returns the SAPI name. Key differences: superglobals ($_SERVER, $_REQUEST) only populated in web SAPIs. STDIN/STDOUT available in CLI. php-fpm pools can have per-pool php.ini overrides. Workers share nothing between requests — no state persistence without external storage (Redis, DB).

Common Misconception

PHP-FPM workers persist state between requests — each request gets a fresh PHP environment. State must be stored externally.

Why It Matters

Understanding SAPIs prevents SAPI-specific code from being used in the wrong context and helps configure each correctly for performance and security.

Common Mistakes

  • Using CLI-only functions (readline, pcntl) in web context.
  • Not setting different memory_limit/max_execution_time per SAPI.
  • Assuming $_SERVER is populated in CLI scripts.

Code Examples

✗ Vulnerable
// In web request — reads from stdin, only works in CLI:
$input = fgets(STDIN); // Returns false in FPM
✓ Fixed
// SAPI detection:
if (PHP_SAPI === 'cli') {
    $input = fgets(STDIN);
} else {
    $input = $_POST['data'] ?? '';
}

// Check in code:
echo PHP_SAPI; // 'fpm-fcgi', 'cli', 'apache2handler' etc

Added 23 Mar 2026
Views 54
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 1 ping S 1 ping S 4 pings M 0 pings T 2 pings W 0 pings T 1 ping F 1 ping S 0 pings S 0 pings M 1 ping T 0 pings W 2 pings T 0 pings F 0 pings S 0 pings S 2 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Scrapy 9 Amazonbot 7 Perplexity 7 ChatGPT 5 Unknown AI 5 Google 5 Ahrefs 3 SEMrush 3 Meta AI 2 Claude 2 PetalBot 2
crawler 45 crawler_json 3 pre-tracking 2
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Use PHP_SAPI constant to conditionally run SAPI-specific code. Configure separate php.ini pools for FPM vs CLI with appropriate limits.
📦 Applies To
PHP 4.0+ web cli
🔗 Prerequisites
🔍 Detection Hints
PHP_SAPI|php_sapi_name
Auto-detectable: ✗ No phpstan
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Low Context: File


✓ schema.org compliant