PHP Extensions Overview
debt(d3/e3/b5/t5)
Closest to 'default linter catches the common case' (d3). Composer validates ext- requirements in composer.json, and PHPStan can detect calls to functions from unloaded extensions. The detection_hints confirm these tools catch the pattern of missing extension declarations, though runtime failures on production still occur if composer.json requirements are incomplete.
Closest to 'simple parameterised fix' (e3). The quick_fix indicates adding ext- requirements to composer.json require section and adding bootstrap checks — this is a straightforward pattern but requires touching configuration and potentially adding guard code in multiple entry points rather than a single-line fix.
Closest to 'persistent productivity tax' (b5). Extension availability affects all PHP contexts (web, cli, queue-worker per applies_to), creating ongoing friction: every new environment setup, CI pipeline, and deployment must ensure correct extensions. Not architecture-defining (b7), but definitely more than localised to one component.
Closest to 'notable trap' (t5). The misconception explicitly states developers believe extensions are 'only needed for exotic functionality' when core tasks like multibyte string handling require mbstring/intl. This is a documented gotcha most PHP developers eventually learn — str_ functions silently misbehave on non-ASCII without mbstring, but it's not a catastrophic always-wrong trap.
Also Known As
TL;DR
Explanation
PHP's core is intentionally lean — most functionality comes from extensions compiled as shared libraries. Bundled extensions ship with PHP: PDO, cURL, mbstring, OpenSSL, GD, intl, zip, sodium, and opcache. PECL provides additional extensions installable via pecl install: Redis, Imagick, Xdebug, Swoole. Extensions are enabled in php.ini with extension=name or zend_extension=xdebug.so. Check loaded extensions with php -m on the CLI or phpinfo() in a web context. For production, load only required extensions to minimise attack surface and memory footprint. opcache and sodium are always recommended.
Common Misconception
Why It Matters
Common Mistakes
- Not checking required extensions in composer.json require section — code ships to environments missing them.
- Assuming an extension available on your dev machine is available on production — always declare dependencies.
- Loading unnecessary extensions — each loaded extension adds memory overhead even if unused.
- Not restarting PHP-FPM after adding an extension to php.ini — the change has no effect until restart.
Code Examples
// Extension not declared in composer.json:
{
"require": {
"php": ">=8.1"
// Missing: "ext-intl": "*", "ext-gd": "*" — will fail silently on deploy
}
}
// Check if extension loaded:
if (!extension_loaded('intl')) throw new \RuntimeException('ext-intl required');
// Declare in composer.json:
{
"require": {
"php": ">=8.2",
"ext-pdo": "*",
"ext-mbstring": "*",
"ext-intl": "*",
"ext-redis": "*"
}
}
// Install (Ubuntu/Debian):
$ apt-get install php8.3-intl php8.3-redis php8.3-imagick
// Docker:
FROM php:8.3-fpm-alpine
RUN docker-php-ext-install pdo_mysql intl
RUN pecl install redis && docker-php-ext-enable redis