Накратко: PHP разширенията (Extensions) са модули на C, които допълват PHP с функции, например драйвери за бази данни (PDO), криптиране (Sodium, OpenSSL) или кеша за байткод OPcache. Ръководството на PHP различава Core, Bundled, External и PECL разширения. Зареждат се чрез extension или zend_extension в php.ini. Всяко разширение работи в процеса на PHP с неговите права. Затова важи: зареждайте само това, което е нужно, и го актуализирайте заедно с PHP.
Какво са PHP Extensions?
Ядрото на PHP, Zend Engine, може да изпълнява код, но много от нещата, от които приложенията се нуждаят, са в разширенията. Те са написани на C и са или компилирани твърдо в PHP, или се зареждат при стартиране като споделена библиотека (.so под Linux, .dll под Windows).
Важно за вземащите решения: разширенията не са добавки на приложението, а част от средата за изпълнение на PHP. Те се инсталират от хостинг доставчика или администратора на сървъра, а не от агенцията в CMS. Ако липсва разширение, приложението най-често съобщава грешка при инсталирането или при актуализацията.
Също толкова важно е разграничението от пакетите на Composer. Composer инсталира библиотеки, написани на PHP, които лежат в папката на проекта, например пакет за поща или PDF. Разширенията, напротив, са компилиран код, зареждан при стартирането на PHP и важещ за всички приложения на сървъра. Много пакети на Composer изискват определени разширения и го отбелязват в своя composer.json със записи като ext-intl или ext-sodium. Който иска да провери дали един проект намира всички необходими разширения, може да изпълни в папката на проекта composer check-platform-reqs.
Какви видове разширения има?
Ръководството на PHP разпределя разширенията в четири групи:
| Група | Значение според ръководството | Примери от ръководството |
|---|---|---|
| Core | част от ядрото на PHP, не може да се изключи | Arrays, Date/Time, Hash, JSON, PCRE, SPL, Strings |
| Bundled | доставят се с PHP | BC Math, Ctype, Fileinfo, Filter, GD, intl, mbstring, PDO, Sessions |
| External | доставят се с PHP, изискват външни библиотеки | cURL, DOM, GMP, LDAP, OpenSSL, Sodium, Zip |
| PECL | достъпни през PECL, отчасти с външни библиотеки | APCu, Memcached, MongoDB, Yaml |
Разпределението може да се променя. С PHP 8.4 според страницата за издание разширенията IMAP, OCI8, PDO_OCI и pspell са премахнати от доставката и преместени към PECL. Който ги ползва, се нуждае след надграждането от отделна инсталация, която също трябва да се поддържа.
Как се зареждат разширенията?
Споделените разширения според ръководството се зареждат чрез директивата extension в php.ini; Zend разширенията, които навлизат по-дълбоко в машината, чрез zend_extension. И двете могат да стоят само в php.ini. Директорията се определя от extension_dir, за което ръководството препоръчва абсолютен път.
; обикновени разширения
extension=pdo_mysql
extension=sodium
extension=intl
; Zend разширение: OPcache (зареждайте преди Xdebug, ако и двете са активни)
zend_extension=opcache
Дистрибуции като Debian и Ubuntu поставят за всяко разширение малък собствен .ini файл в директорията за сканиране, например под /etc/php/8.3/mods-available/, и го активират за всеки SAPI с phpenmod и phpdismod. Как PHP чете тези файлове, обяснява php.ini, обяснен.
Разширенията се инсталират най-често чрез управлението на пакети, например като пакет php8.3-intl. PECL разширенията могат да се изграждат с pecl или phpize. Според ръководството PECL е оттеглен; препоръчва се PHP Installer for Extensions (PIE). Който изгражда PHP изцяло сам, ще намери указания в Компилиране на PHP от изходния код.
Проверка на разширенията: кои са наистина заредени?
Следните команди са изцяло само за четене. Имайте предвид, че командният ред може да зарежда други разширения от уебсайта.
php -m # модули на CLI
php-fpm8.3 -m # модули на PHP-FPM 8.3 (името зависи от дистрибуцията)
php --re sodium | head -n 5 # функции на разширение
php --ri opcache # конфигурация на разширение
php -r 'var_dump(extension_loaded("intl"));'
В кода приложенията проверяват с extension_loaded() дали има разширение и с get_loaded_extensions() кои са заредени:
<?php
$benoetigt = ['pdo_mysql', 'mbstring', 'intl', 'sodium'];
$fehlend = array_diff($benoetigt, array_map('strtolower', get_loaded_extensions()));
echo $fehlend ? 'Fehlt: ' . implode(', ', $fehlend) : 'Alle Erweiterungen vorhanden';
Разширения и сигурност: по-малко е повече
Разширенията работят в същия процес като PHP и със същите права. Грешка в разширение затова може да тежи толкова, колкото грешка в ядрото. От това следват четири правила:
- Зареждайте само нужното. Всяко допълнително разширение увеличава повърхността за атака. Проверете списъка си спрямо системните изисквания на приложението.
- Актуализирайте заедно с PHP. Доставяните разширения идват с актуализацията на PHP. PECL и външните разширения изискват собствени актуализации и трябва да съответстват на новата версия на PHP.
- Инструменти за разработка не в продукция. Дебъгерите и профилърите като Xdebug принадлежат само в среди за разработка.
- Целенасочено блокиране на функции. Където разширенията носят функции за системни команди, помага Правилно използване на disable_functions.
При PHP2Shell уязвимостите са в ядрото на PHP, а не в разширение. Изключването на модули не ги затваря; необходима е актуализацията до 8.5.12, 8.4.27, 8.3.36 или 8.2.35 с рестартиране на всички PHP процеси. След актуализацията трябва да проверите дали всички разширения отново се зареждат, защото липсващите модули често проличават едва при определени функции. Как да държите зависимостите трайно под контрол, описва Поддържане на зависимостите актуални.
Как помага PHP SOS конкретно?
- Установяване на състоянието: Изброяваме за всеки SAPI всички заредени разширения с произход и версия.
- Почистване: Съпоставяме списъка с нуждите на Вашето приложение и деактивираме излишното след тест.
- Актуализиране: В рамките на заздравяването на сървъра привеждаме PHP и всички външни разширения в поддържано състояние.
- Проверка след актуализации: Контролираме дали след всяка актуализация на PHP всички необходими модули са отново заредени.
Често задавани въпроси
Каква е разликата между extension и zend_extension?
С extension PHP зарежда обикновени разширения като драйвери за бази данни. С zend_extension според ръководството се зареждат Zend разширения, които навлизат по-дълбоко в машината, например OPcache или Xdebug. И двете директиви могат да стоят само в php.ini.
Как да видя кои разширения са заредени?
В командния ред с php -m, за уебсайта чрез функцията get_loaded_extensions() в кратковременен проверочен файл или чрез php-fpm -m на съответната версия. Имайте предвид, че CLI и уеб SAPI могат да зареждат различни разширения.
Какво е PECL и какво е PIE?
PECL е регистър на PHP разширения, предоставяни чрез пакетната система PEAR. Според ръководството на PHP PECL е оттеглен; вместо него се препоръчва PHP Installer for Extensions (PIE).
Затваря ли изключването на разширение PHP2Shell?
Не. Уязвимостите на PHP2Shell са в ядрото на PHP, а не в разширение, което може да се изключи. По-малкото разширения намалява повърхността за атака като цяло, но не замества актуализацията до поправена версия.