# PHP en la línea de comandos (CLI)

> PHP CLI explicado: diferencias con la versión web, opciones importantes como -l, -m y --ini, tareas cron, servidor integrado y por qué php -v suele engañar.

Fuente: https://phpsos.de/es/php/php-cli/  
Actualizado: 25/10/2026  
Proveedor: PHP SOS, Ayuda de emergencia para PHP y seguridad de servidores. Ayuda inmediata por WhatsApp: https://wa.me/491736494914?text=Hola%20PHP%20SOS%2C%20necesitamos%20ayuda%20con%20nuestro%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Sitio%20web%3A%20%E2%80%A6

**En resumen:** la PHP CLI (Command Line Interface) es la variante de PHP para la línea de comandos. Ejecuta scripts sin servidor web, por ejemplo para tareas cron, Composer o tareas de mantenimiento. Tiene valores por defecto propios, a menudo un php.ini propio y a veces incluso una versión distinta de la del sitio web. Por eso `php -v` no es una prueba fiable de que el sitio web esté parcheado tras PHP2Shell.

## ¿Qué es la PHP CLI?

El manual de PHP menciona dos campos de uso principales de PHP: scripts para sitios web y scripts en la línea de comandos. Para esto último hay una SAPI propia llamada `cli`. No necesita ni servidor web ni navegador, solo el intérprete de PHP. Según el manual, es especialmente adecuada para tareas que se ejecutan periódicamente mediante Cron en Linux o mediante el programador de tareas en Windows.

Ejemplos típicos en el día a día de una empresa: importaciones nocturnas en la tienda, envío de boletines, limpieza de cachés, actualizaciones mediante Composer o las herramientas de línea de comandos de los CMS, como WP-CLI o la consola de Symfony. En Windows el archivo se llama `php.exe` y la variante CGI, `php-cgi.exe`.

A diferencia de PHP-FPM, la CLI no es un servicio. Cada invocación inicia un proceso nuevo, según el manual vuelve a leer la configuración y termina cuando acaba el script. Por eso no es necesario un reinicio tras una actualización. Las excepciones son los procesos de larga duración iniciados mediante CLI, como los workers de colas de los frameworks o los daemons bajo systemd o Supervisor. Funcionan durante días con el intérprete cargado una sola vez y, tras una actualización de PHP, deben reiniciarse igual que los workers web.

Para la dirección y la dirección de proyectos esto significa: también las tareas en segundo plano pertenecen al inventario y a cada plan de actualización.

## ¿En qué se diferencia la CLI de la versión web?

Según el manual, la CLI sobrescribe de forma fija algunos ajustes. No pueden cambiarse mediante el php.ini, solo en tiempo de ejecución con `ini_set()`:

| Directiva | Valor en la CLI | Motivo según el manual |
|---|---|---|
| `html_errors` | desactivado | las etiquetas HTML molestan en el terminal |
| `implicit_flush` | activado | las salidas deben aparecer de inmediato |
| `max_execution_time` | 0 (sin límite) | los scripts de línea de comandos suelen ser largos |
| `register_argc_argv` | activado | los scripts reciben siempre `$argc` y `$argv` |
| `output_buffering` | desactivado | fijo, las funciones de búfer siguen siendo utilizables |
| `max_input_time` | desactivado | la CLI no conoce GET, POST ni cargas de archivos |

Otra diferencia: la CLI no cambia al directorio del script. Quien ejecuta `php -f ordner/skript.php` desde `/tmp` sigue trabajando en `/tmp`. Por eso, las rutas relativas en las tareas cron son una fuente de error frecuente.

Un pequeño script que solo debe ejecutarse en la línea de comandos:

```php
<?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");
```

La comprobación de `PHP_SAPI` evita que un script de mantenimiento se active desde el navegador si por descuido está en el directorio web. El manual aconseja expresamente comprobar así la SAPI en lugar de fiarse de la existencia de `$argv`.

## Las opciones más importantes de la PHP CLI

Las siguientes opciones proceden del resumen de opciones del manual de PHP y son especialmente útiles para administradores:

1. **`php -v`** muestra el número de versión de la CLI.
2. **`php --ini`** muestra qué archivos de configuración se cargan.
3. **`php -m`** lista los módulos compilados y cargados.
4. **`php -i`** llama a `phpinfo()` y muestra el resultado como texto.
5. **`php -l datei.php`** comprueba solo la sintaxis (lint). Desde PHP 8.3, también para varios archivos a la vez.
6. **`php -r 'code'`** ejecuta código directamente, sin `<?php`.
7. **`php -d name=wert`** fija un ajuste INI para esta invocación.
8. **`php -n`** ignora por completo el php.ini.
9. **`php --ri name`** muestra la configuración de una extensión.

```bash
php --ini
php -m | grep -i -E "opcache|sodium|pdo"
php --ri session | grep upload_progress
php -l src/Controller.php src/Model.php
```

## El servidor web integrado: solo para desarrollo

Con `php -S localhost:8000`, la CLI inicia un pequeño servidor web. La salida de ejemplo del manual menciona PHP 5.4.0 como punto de partida. El manual es claro: el servidor sirve para el desarrollo, no es un servidor web completo y no debe ejecutarse en redes públicas ni en producción. Si se ejecuta de forma permanente en un servidor y es accesible desde fuera, es un hallazgo que conviene corregir.

## CLI, cron y seguridad tras PHP2Shell

Los informes conocidos sobre PHP2Shell mencionan PHP-FPM, mod_php, php-cgi, FrankenPHP y LiteSpeed como modos de ejecución afectados. La CLI no procesa peticiones de la red. Para la seguridad es importante, sin embargo, en tres aspectos:

- **Prueba falsa:** `php -v` muestra la versión de la CLI. El sitio web puede usar otra versión y los backports de las distribuciones a menudo no cambian el número mostrado. Cómo demostrar el estado correctamente se explica en [Comprobar la versión de PHP y el estado del parche](https://phpsos.de/es/php2shell/php-version-pruefen/) y en el artículo [Por qué php -v muestra el mismo número](https://phpsos.de/es/blog/php-v-zeigt-alte-nummer/).
- **Persistencia mediante cron:** tras una intrusión, a los atacantes les gusta usar tareas cron que inician un script PHP periódicamente. Indicaciones para buscarlas ofrece [Reconocer tareas cron ocultas como puerta trasera](https://phpsos.de/es/blog/cronjobs-als-hintertuer/).
- **Mismo paquete:** la CLI suele proceder del mismo origen de paquetes que PHP-FPM y debe incluirse en la actualización.

## ¿Cómo ayuda PHP SOS en concreto?

- **Contrastar versiones:** comparamos el estado de la CLI y el de la web y demostramos qué versión entrega realmente su sitio web.
- **Revisar las tareas cron:** listamos todas las tareas de PHP programadas de todos los usuarios y las asignamos a sus aplicaciones.
- **Proteger el mantenimiento:** sacamos los scripts de mantenimiento del directorio web y añadimos comprobaciones de SAPI.
- **Atender de forma continua:** en el [contrato de mantenimiento de seguridad](https://phpsos.de/es/leistungen/security-wartungsvertrag/) mantenemos al día conjuntamente la CLI, la SAPI web y las tareas cron.


## Preguntas frecuentes

**¿Muestra php -v la versión de mi sitio web?**  
No necesariamente. php -v muestra la versión de la variante de línea de comandos. El sitio web puede ejecutarse con otra versión de PHP-FPM o con un módulo de Apache. Para el sitio web cuenta el estado de la SAPI web, que se averigua mediante el servicio o un archivo de prueba colocado de forma breve.

**¿Por qué los scripts de la CLI se ejecutan sin límite de tiempo?**  
Según el manual de PHP, la CLI fija max_execution_time en 0, es decir, sin límite, porque los scripts en la línea de comandos suelen realizar tareas largas. La duración puede limitarse mediante el propio script o con herramientas como timeout.

**¿Puedo usar en producción el servidor integrado php -S?**  
No. El manual lo describe como una ayuda para el desarrollo, no como un servidor web completo, y desaconseja su uso en redes públicas y en producción. Para sistemas en producción, delante debe haber Apache, Nginx o LiteSpeed con PHP-FPM.

**¿Está activo OPcache en la línea de comandos?**  
Por defecto no. Según el manual, opcache.enable_cli vale 0. Para scripts cortos la caché aporta poco de todos modos, porque cada invocación es un proceso nuevo.

## Fuentes

- [Manual de PHP: PHP en la línea de comandos](https://www.php.net/manual/en/features.commandline.php)
- [Manual de PHP: diferencias de la SAPI CLI](https://www.php.net/manual/en/features.commandline.differences.php)
- [Manual de PHP: opciones de la CLI](https://www.php.net/manual/en/features.commandline.options.php)
- [Manual de PHP: servidor web integrado](https://www.php.net/manual/en/features.commandline.webserver.php)
