首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 獲取運行環境識別 (SAPI) 實現差異化邏輯

     編輯:PHP 相關知識

PHP 可運行於多種 SAPI (Server API) 環境,透過 php_sapi_name() 識別當前環境,可實現 CLI/Web/嵌入式等差異化邏輯。

核心函式

<?php
$sapi = php_sapi_name();
echo "當前 SAPI: $sapi";

常見 SAPI 返回值對照

環境php_sapi_name() 返回值備註
Apache 模組 (mod_php)apache2handler最常見生產環境
Apache CGI / FastCGIcgi-fcgiPHP-FPM、suPHP
Nginx + PHP-FPMfpm-fcgi現代主流部署
命令列 (CLI)cli腳本、定時任務、Queue Worker
內建 Web Servercli-serverphp -S localhost:8000
IIS (ISAPI)isapiWindows IIS 6
IIS (FastCGI)cgi-fcgiWindows IIS 7+
嵌入式 (Embed)embedPHP 嵌入 C/C++ 應用
phpdbg 除錯器phpdbgPHP 5.6+ 內建除錯器

實務應用場景

1. CLI 專用邏輯 (定時任務、佇列處理)

<?php
if (php_sapi_name() === 'cli') {
    // CLI 環境:無限執行時間、無輸出緩衝、可讀取 stdin
    set_time_limit(0);
    ini_set('memory_limit', '512M');
    
    // 讀取管道輸入
    $stdin = fopen('php://stdin', 'r');
    while (($line = fgets($stdin)) !== false) {
        processLine(trim($line));
    }
    
    // 彩色輸出
    echo "\033[32m成功\033[0m\n";
    exit(0);
}

// Web 環境:正常 HTTP 處理
handleHttpRequest();

2. 區分 Apache/Nginx 針對性優化

<?php
$sapi = php_sapi_name();

if (strpos($sapi, 'apache') !== false) {
    // Apache mod_php: 進程模型、.htaccess 生效
    apache_setenv('no-gzip', 1); // 關閉 mod_deflate 避免雙重壓縮
} elseif ($sapi === 'fpm-fcgi') {
    // PHP-FPM: fastcgi_finish_request() 可用
    // 適合異步任務、大檔案下載後續處理
}

3. 統一入口自動適配

<?php
// public/index.php
require __DIR__ . '/../vendor/autoload.php';

$sapi = php_sapi_name();

if ($sapi === 'cli') {
    // Artisan/Console 入口
    $app = require __DIR__ . '/../bootstrap/console.php';
    $kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
    $status = $kernel->handle(
        $input = new Symfony\Component\Console\Input\ArgvInput,
        new Symfony\Component\Console\Output\ConsoleOutput
    );
    exit($status);
} elseif ($sapi === 'cli-server') {
    // 開發測試用內建伺服器:靜態檔案直接服務
    $uri = urldecode(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
    if ($uri !== '/' && file_exists(__DIR__ . $uri)) {
        return false; // 讓內建伺服器直接服務靜態檔
    }
}

// 正常 HTTP 請求處理
$app = require __DIR__ . '/../bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);

4. 環境感知配置載入

<?php
function loadConfig() {
    $sapi = php_sapi_name();
    $base = __DIR__ . '/config';
    
    // 共用配置
    $config = require "$base/app.php";
    
    // 環境專屬覆蓋
    $envConfigs = [
        'cli' => 'console.php',
        'cli-server' => 'local.php',
        'fpm-fcgi' => 'production.php',
        'apache2handler' => 'production.php',
    ];
    
    if (isset($envConfigs[$sapi])) {
        $override = require "$base/{$envConfigs[$sapi]}";
        $config = array_merge_recursive($config, $override);
    }
    
    // .env 覆蓋 (最高優先級)
    if (file_exists(__DIR__ . '/.env')) {
        $dotenv = new Symfony\Component\Dotenv\Dotenv();
        $dotenv->load(__DIR__ . '/.env');
    }
    
    return $config;
}

相關超全域變數輔助判斷

變數CLI 環境Web 環境
$_SERVER['argc']>= 1未設定
$_SERVER['argv']參數陣列未設定
$_SERVER['REQUEST_METHOD']未設定GET/POST...
$_SERVER['HTTP_HOST']未設定域名
STDIN/STDOUT/STDERR可用不可用

常數判斷替代方案 (PHP 7.2+)

<?php
// 定義於 php.h,編譯時確定
echo PHP_SAPI; // 等同 php_sapi_name(),但略快 (無函式呼叫)

// 預定義常數
defined('STDIN')   // CLI 專用
defined('STDOUT')  // CLI 專用
defined('STDERR')  // CLI 專用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved