php runtime and server environment
SAPI Overview
SAPI means Server API. It is the layer that connects PHP to the environment that started it.
You will see SAPIs in setup debugging, production incidents, local development, hosting panels, and performance conversations. The SAPI tells you whether PHP was started by a terminal, a web server, a process manager, or a hosting-specific integration.
The Main SAPIs You Should Recognise
Common SAPIs include:
clifor command-line PHPcli-serverfor PHP's built-in development servercgi-fcgiorfpm-fcgifor CGI/FastCGI/FPM-style web executionapache2handlerfor Apache's PHP modulelitespeedfor LiteSpeed/OpenLiteSpeed LSAPI setups
Check the current one with:
<?php
declare(strict_types=1);
echo 'Running through: ' . PHP_SAPI . PHP_EOL;
if (PHP_SAPI === 'cli') {
echo 'Started from the command line.' . PHP_EOL;
} else {
echo 'Started by a web-facing runtime.' . PHP_EOL;
}
// Example CLI output:
// Running through: cli
// Started from the command line.
This small check can explain why a setting or extension appears in one context but not another.
CLI
CLI is for terminal commands:
php script.php
composer install
php -l public/index.php
Use CLI for scripts, Composer, tests, queue workers, cron jobs, and framework commands.
CLI receives input through arguments, environment variables, and standard streams. It does not automatically have HTTP request data.
CGI And FastCGI
CGI is an older way for a web server to start a program to handle a request. Classic CGI can be inefficient because it starts a new process frequently.
FastCGI improves this by allowing long-lived processes to handle multiple requests. PHP-FPM is a FastCGI process manager designed specifically for PHP.
In modern PHP production, when people mention FastCGI, they usually mean a web server passing requests to PHP-FPM.
PHP-FPM
PHP-FPM manages pools of PHP worker processes. Nginx, Caddy, Apache, or another web server forwards PHP requests to those workers.
Typical flow:
browser -> web server -> PHP-FPM -> public/index.php
FPM is common because it separates HTTP handling from PHP execution. It also gives operations teams control over worker counts, users, pools, slow logs, and process lifecycle.
Apache Module
The Apache module embeds PHP into Apache itself. It is often simple in local stacks, but it ties PHP execution closely to Apache.
If PHP_SAPI reports apache2handler, the request was handled through Apache's module integration.
Many modern systems prefer PHP-FPM because it works with multiple web servers and keeps PHP process management separate.
LSAPI
LSAPI is associated with LiteSpeed and OpenLiteSpeed hosting environments. It is common in some shared hosting and control panel setups.
If you see litespeed as the SAPI, treat it as a hosting/runtime integration detail. You still debug the same major categories: active PHP version, loaded configuration, extensions, process user, logs, and web server routing.
Why The SAPI Changes Debugging
Different SAPIs can have different:
php.inifiles- extension sets
- process users
- working directories
- environment variables
- error logs
- memory and execution limits
- request inputs
Diagnostic endpoint for web SAPIs:
<?php
declare(strict_types=1);
header('Content-Type: text/plain');
echo 'PHP: ' . PHP_VERSION . PHP_EOL;
echo 'SAPI: ' . PHP_SAPI . PHP_EOL;
echo 'Loaded ini: ' . (php_ini_loaded_file() ?: 'none') . PHP_EOL;
echo 'Memory limit: ' . ini_get('memory_limit') . PHP_EOL;
Use it locally or behind access control. Do not expose runtime details publicly.
Choosing A Runtime
For local learning, the built-in server is often enough.
For production web applications, PHP-FPM behind Nginx, Apache, or Caddy is a common default.
For Apache-only local stacks, the Apache module may appear.
For managed hosting, LSAPI may appear.
For scripts, workers, and maintenance commands, CLI is the runtime.
The professional habit is not arguing that one SAPI is always best. It is knowing which one is running and what operational tradeoffs it brings.
What You Should Be Able To Do
After this lesson, you should be able to define SAPI, identify common SAPI names, explain the difference between CLI, FastCGI/FPM, Apache module, and LSAPI, and use a diagnostic to prove which one handled a request.
For junior PHP work, this matters because "works in terminal but not in browser" is often a SAPI mismatch. Knowing where PHP is running is the first step to fixing it.
Practice
Practice: Identify A PHP SAPI
Create a short SAPI diagnostic and a note explaining what the result means.
Task
Build a PHP file that prints:
- PHP version
- SAPI name
- loaded
php.ini - memory limit
Run it once from CLI and once through any local web setup you have available.
Use strict types. Keep example output inside the PHP code block as comments.
Afterward, add a short note explaining what you would check next if CLI and web results differ.
Show solution
This diagnostic is small enough to run from CLI or through a local web server.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') {
header('Content-Type: text/plain');
}
echo 'PHP: ' . PHP_VERSION . PHP_EOL;
echo 'SAPI: ' . PHP_SAPI . PHP_EOL;
echo 'Loaded ini: ' . (php_ini_loaded_file() ?: 'none') . PHP_EOL;
echo 'Memory limit: ' . ini_get('memory_limit') . PHP_EOL;
// Example CLI output:
// PHP: 8.5.6
// SAPI: cli
// Loaded ini: /etc/php.ini
// Memory limit: 128M
//
// Example web output:
// PHP: 8.5.6
// SAPI: cli-server
// Loaded ini: /etc/php.ini
// Memory limit: 128M
If CLI and web results differ, check the loaded php.ini, enabled extensions, process user, environment variables, and web server or PHP-FPM configuration for the web runtime.