Накратко: PHP CLI (Command Line Interface) е вариантът на PHP за командния ред. Той изпълнява скриптове без уеб сървър, например за Cron задачи, Composer или задачи по поддръжка. Има собствени стандартни стойности, често собствен php.ini и понякога дори друга версия от тази на уебсайта. Затова php -v не е надеждно доказателство, че уебсайтът е коригиран след PHP2Shell.
Какво е PHP CLI?
Ръководството на PHP назовава две основни области на приложение на PHP: скриптове за уебсайтове и скриптове в командния ред. За второто има собствен SAPI с име cli. Той не се нуждае нито от уеб сървър, нито от браузър, а само от интерпретатора на PHP. Според ръководството е особено подходящ за задачи, които се изпълняват редовно чрез Cron под Linux или чрез планировчика на задачи под Windows.
Типични примери от фирменото ежедневие: нощни импорти в магазина, изпращане на бюлетини, почистване на кешове, актуализации чрез Composer или инструментите за команден ред на CMS като WP-CLI или конзолата на Symfony. Под Windows файлът се казва php.exe, а CGI вариантът php-cgi.exe.
За разлика от PHP-FPM CLI не е услуга. Всяко извикване стартира нов процес, според ръководството чете конфигурацията наново и приключва, когато скриптът е готов. Рестартиране след актуализация затова не е нужно. Изключение са дълго работещите процеси, стартирани през CLI, например работни процеси на опашки във framework-ове или демони под systemd или Supervisor. Те работят дни наред със заредения веднъж интерпретатор и след актуализация на PHP трябва да бъдат рестартирани също като уеб работните процеси.
За управителите и ръководителите на проекти това означава: и задачите на заден план принадлежат към описа и към всеки план за актуализации.
С какво CLI се различава от уеб версията?
Според ръководството CLI презаписва твърдо някои настройки. Те не могат да се променят чрез php.ini, а само по време на изпълнение с ini_set():
| Директива | Стойност в CLI | Обосновка според ръководството |
|---|---|---|
html_errors |
изключена | HTML таговете пречат в терминала |
implicit_flush |
включена | изходът трябва да се появява веднага |
max_execution_time |
0 (неограничено) | скриптовете в командния ред често работят дълго |
register_argc_argv |
включена | скриптовете винаги получават $argc и $argv |
output_buffering |
изключена | твърдо зададена, функциите за буфериране остават използваеми |
max_input_time |
изключена | CLI не познава GET, POST или качвания |
Още една разлика: CLI не сменя директорията към тази на скрипта. Който извика php -f ordner/skript.php от /tmp, продължава да работи в /tmp. Относителните пътища в Cron задачи затова са честа причина за грешки.
Малък скрипт, който трябва да работи само в командния ред:
<?php
if (PHP_SAPI !== 'cli') {
http_response_code(403);
exit('Nur für die Kommandozeile.');
}
$tage = (int) ($argv[1] ?? 30);
$grenze = time() - $tage * 86400;
$alt = 0;
foreach (glob(__DIR__ . '/cache/*.tmp') ?: [] as $datei) {
if (filemtime($datei) < $grenze) { $alt++; }
}
fwrite(STDOUT, "Dateien älter als $tage Tage: $alt\n");
Проверката на PHP_SAPI не позволява поддържащ скрипт да бъде задействан през браузъра, ако случайно лежи в уеб директорията. Ръководството изрично препоръчва SAPI да се проверява така, вместо да се разчита на наличието на $argv.
Най-важните опции на PHP CLI
Следните опции са от прегледа на опциите в ръководството на PHP и са особено полезни за администратори:
php -vпоказва номера на версията на CLI.php --iniпоказва кои конфигурационни файлове се зареждат.php -mизброява компилираните и заредените модули.php -iизвикваphpinfo()и извежда резултата като текст.php -l datei.phpпроверява само синтаксиса (lint). От PHP 8.3 и за няколко файла наведнъж.php -r 'code'изпълнява код директно, без<?php.php -d name=wertзадава INI настройка за това извикване.php -nизцяло игнорира php.ini.php --ri nameпоказва конфигурацията на разширение.
php --ini
php -m | grep -i -E "opcache|sodium|pdo"
php --ri session | grep upload_progress
php -l src/Controller.php src/Model.php
Вграденият уеб сървър: само за разработка
С php -S localhost:8000 CLI стартира малък уеб сървър. Примерният изход в ръководството посочва PHP 5.4.0 като изходна точка. Ръководството е категорично: сървърът служи за разработка, не е пълноценен уеб сървър и не бива да работи в публични мрежи и в продукция. Ако на даден сървър работи постоянно и е достъпен отвън, това е находка, която трябва да отстраните.
CLI, Cron и сигурност след PHP2Shell
Известните съобщения за PHP2Shell назовават PHP-FPM, mod_php, php-cgi, FrankenPHP и LiteSpeed като засегнати режими на работа. CLI не обработва заявки от мрежата. За сигурността тя обаче е важна в три отношения:
- Грешно доказателство:
php -vпоказва версията на CLI. Уебсайтът може да ползва друга версия, а backport корекциите на дистрибуциите често не променят показвания номер. Как да докажете състоянието правилно, е описано в Проверка на версията на PHP и състоянието на корекциите и в статията Защо php -v показва същия номер. - Устойчивост чрез Cron: След пробив атакуващите обичат да ползват Cron задачи, които редовно стартират PHP скрипт. Указания за търсене дава Откриване на скрити Cron задачи като задна вратичка.
- Същият пакет: CLI обикновено идва от същия източник на пакети като PHP-FPM и принадлежи към актуализацията.
Как помага PHP SOS конкретно?
- Съпоставяне на версиите: Сравняваме състоянието на CLI и на уеб и доказваме коя версия Вашият уебсайт действително предоставя.
- Проверка на Cron задачите: Изброяваме всички планирани PHP задачи на всички потребители и ги съотнасяме към техните приложения.
- Защита на поддръжката: Преместваме скриптовете за поддръжка извън уеб директорията и въвеждаме проверки на SAPI.
- Постоянна грижа: В договора за поддръжка на сигурността поддържаме CLI, уеб SAPI и Cron задачите актуални заедно.
Често задавани въпроси
php -v показва ли версията на моя уебсайт?
Не непременно. php -v показва версията на варианта за команден ред. Уебсайтът може да работи през друга версия на PHP-FPM или през модул на Apache. За уебсайта има значение състоянието на уеб SAPI, което установявате чрез услугата или чрез кратковременен проверочен файл.
Защо CLI скриптовете работят неограничено дълго?
Според ръководството на PHP CLI задава max_execution_time твърдо на 0, т.е. неограничено, защото скриптовете в командния ред често изпълняват продължителни задачи. Времето за работа може да се ограничи чрез самия скрипт или чрез инструменти като timeout.
Мога ли да използвам вградения уеб сървър php -S в продукция?
Не. Ръководството го описва като помощно средство за разработка, а не като пълноценен уеб сървър, и не препоръчва ползването му в публични мрежи и в продукция. За работещи системи пред него трябва да стоят Apache, Nginx или LiteSpeed с PHP-FPM.
OPcache активен ли е в командния ред?
По подразбиране не. Според ръководството opcache.enable_cli е 0. За кратки скриптове кешът така или иначе носи малко полза, защото всяко извикване е нов процес.