chdir()
Aprende a cambiar el directorio de trabajo en PHP con chdir(): sintaxis, valor de retorno, casos de uso y buenas prácticas.
La función chdir() de PHP cambia el directorio de trabajo actual de tu script al directorio que le pases como argumento. Esta página explica qué es el directorio de trabajo, la firma exacta de chdir(), cómo manejar el valor que devuelve y los casos habituales y errores que encontrarás en código real.
¿Qué es el directorio de trabajo?
El directorio de trabajo actual (CWD) es la ubicación base que PHP utiliza para resolver rutas relativas. Cuando llamas a algo como fopen('data.txt', 'r') o include 'config.php', PHP combina esa ruta relativa con el CWD para determinar a qué archivo te refieres.
Un error frecuente es suponer que el CWD siempre es la carpeta que contiene el script en ejecución. Eso solo ocurre como punto de partida en algunas configuraciones. El CWD puede diferir del directorio del script; por ejemplo, cuando un script es lanzado por cron, por un servidor web o desde otro directorio de trabajo en la línea de comandos. Cuando la ruta importa, nunca des nada por sentado: léelo con getcwd().
Sintaxis
chdir(string $directory): bool$directory— la ruta a la que cambiar. Puede ser absoluta (/var/www/html) o relativa al CWD actual (../logs).- Valor de retorno —
truesi tiene éxito,falsesi falla (por ejemplo, si el directorio no existe o el proceso no tiene permisos).chdir()emite unE_WARNINGal fallar, por lo que debes comprobar el valor de retorno en lugar de ignorarlo.
Uso básico
<?php
// Where are we now?
echo getcwd() . PHP_EOL; // e.g. /var/www/html
// Move into a subdirectory
chdir('logs');
echo getcwd() . PHP_EOL; // e.g. /var/www/html/logs
// Move back up one level
chdir('..');
echo getcwd() . PHP_EOL; // e.g. /var/www/htmlComo chdir() acepta rutas relativas, chdir('logs') se resuelve desde donde te encuentres en ese momento, mientras que chdir('..') sube un nivel en la jerarquía de directorios.
Comprueba siempre el valor de retorno
Un chdir() fallido deja el CWD sin cambios, lo que puede romper silenciosamente todas las rutas relativas que vengan después. Protege la llamada:
<?php
$target = '/path/that/may/not/exist';
if (chdir($target)) {
echo "Now working in: " . getcwd() . PHP_EOL;
} else {
echo "Could not change to {$target}" . PHP_EOL;
}Guarda y restaura el directorio original
Cambiar el CWD afecta a todo el proceso, no solo a la función actual. Si una función auxiliar cambia de directorio y olvida revertirlo, el código posterior puede leer o escribir los archivos equivocados. Un patrón seguro es capturar el directorio original y restaurarlo cuando hayas terminado:
<?php
$original = getcwd(); // remember where we started
chdir('/tmp');
// ... do work that relies on /tmp being the CWD ...
chdir($original); // restore for the rest of the script
echo getcwd() . PHP_EOL; // back to where we startedCombinar chdir() con includes
Una vez cambiado el CWD, las rutas relativas de include/require se resuelven desde la nueva ubicación:
<?php
chdir('/path/to/app/config');
include 'database.php'; // resolves to /path/to/app/config/database.phpPara los includes en particular, depender del CWD es frágil porque quien llame al código puede cambiarlo. Prefiere una ruta absoluta construida a partir de la ubicación del propio script con la constante mágica __DIR__:
<?php
// Robust regardless of the current working directory
include __DIR__ . '/config/database.php';¿Cuándo usaría chdir()?
- Scripts de CLI y herramientas de compilación que invocan comandos que esperan un directorio específico.
- Trabajos por lotes (ejecutados mediante cron) donde el CWD de lanzamiento es impredecible, por lo que lo estableces explícitamente al inicio.
- Trabajar con rutas relativas de forma masiva — p. ej., iterar archivos en una carpeta sin prefijar cada ruta.
En la mayoría de aplicaciones web deberías preferir rutas absolutas (__DIR__, rutas base configuradas) en lugar de cambiar el CWD global, ya que el cambio se propaga a toda la solicitud.
Funciones relacionadas
getcwd()— lee el directorio de trabajo actual.mkdir()— crea un directorio antes de acceder a él.scandir()/opendir()— lista el contenido de un directorio.realpath()— expande una ruta relativa a su forma absoluta con los enlaces simbólicos resueltos.dirname()— obtiene la parte del directorio de una cadena de ruta.