Módulo 01: Entorno de desarrollo
Objetivos del módulo
- Conocer las distintas formas de tener PHP 8.5 en tu ordenador y elegir la más adecuada
- Instalar PHP 8.5 de forma nativa en Windows, macOS o Linux
- Configurar
php.iniy activar las extensiones necesarias - Valorar los paquetes todo-en-uno (XAMPP, Laragon) y Docker
- Usar el servidor integrado de PHP y los comandos básicos de la CLI
- Preparar Visual Studio Code con las extensiones adecuadas
- Instalar Composer y configurar Xdebug para depurar paso a paso
- Crear la estructura de tu primer proyecto y ejecutar un “Hola mundo” en la terminal y en el navegador
1. ¿Qué necesitas para programar en PHP?
📘 Concepto: Un entorno de desarrollo es el conjunto de herramientas que te permiten escribir, ejecutar y depurar código en tu propio ordenador antes de publicarlo. Es como el taller de un carpintero: necesitas las herramientas (PHP, editor), el banco de trabajo (servidor web) y los materiales (base de datos).
Para este curso necesitas:
| Pieza | Para qué sirve | Herramienta recomendada |
|---|---|---|
| Intérprete PHP 8.5 | Ejecuta tu código | PHP 8.5 oficial |
| Servidor web | Sirve las páginas al navegador | Servidor integrado php -S (desarrollo), Apache o Nginx |
| Editor de código | Escribir código con ayudas | Visual Studio Code |
| Gestor de dependencias | Instalar librerías | Composer |
| Depurador | Ejecutar paso a paso e inspeccionar variables | Xdebug + extensión PHP Debug |
| Base de datos (desde el módulo 15) | Guardar información | MariaDB o MySQL |
Las tres opciones de instalación
| Opción | Ventajas | Inconvenientes | Recomendada para |
|---|---|---|---|
| Instalación nativa | Control total, ligera, aprendes cómo funciona PHP de verdad | Hay que configurar cada pieza a mano | Este curso (opción principal) |
| Paquete todo-en-uno (XAMPP, Laragon) | Un instalador con Apache, PHP y MariaDB | Suelen ir por detrás en versiones de PHP; ocultan la configuración | Empezar rápido en Windows |
| Docker | Entorno idéntico en cualquier máquina y en producción; varias versiones a la vez | Requiere aprender Docker; más consumo de recursos | Equipos de trabajo y proyectos profesionales |
💡 Consejo: Te recomendamos la instalación nativa para los módulos 01-14 (solo necesitas PHP y el servidor integrado) y, cuando llegues a bases de datos (módulo 15), elegir entre instalar MariaDB o usar el
compose.yamlcon Docker que verás en este módulo.
2. Instalación nativa en Windows
Paso 1: Descargar PHP 8.5
- Entra en la sección de descargas para Windows de php.net (la antigua dirección
windows.php.net/downloadredirige allí). - Busca PHP 8.5 y descarga el ZIP de la variante VS17 x64 Non Thread Safe (un fichero con un nombre como
php-8.5.x-nts-Win32-vs17-x64.zip).
| Variante | Cuándo usarla |
|---|---|
| Non Thread Safe (NTS) | Línea de comandos, servidor integrado, FastCGI (IIS, Nginx). La que necesitas en este curso |
| Thread Safe (TS) | Cuando PHP se carga como módulo dentro de Apache (php8apache2_4.dll) |
| x86 | Solo para Windows de 32 bits (muy raro hoy en día) |
⚠️ Importante: Las compilaciones de PHP para Windows necesitan el Visual C++ Redistributable for Visual Studio 2015-2022 (versión x64). Si al ejecutar
phpaparece un error sobreVCRUNTIME140.dll, descárgalo desde la web de Microsoft (https://aka.ms/vs/17/release/vc_redist.x64.exe) e instálalo.
Paso 2: Descomprimir
Crea la carpeta C:\php y descomprime dentro el contenido del ZIP. Debes tener algo así:
C:\php\
├── ext\ ← extensiones (php_mbstring.dll, php_pdo_mysql.dll...)
├── php.exe ← intérprete de línea de comandos
├── php-cgi.exe
├── php.ini-development ← plantilla de configuración para desarrollo
├── php.ini-production ← plantilla de configuración para producción
└── ...
💡 Consejo: Evita rutas con espacios o tildes (como
C:\Program Files\oC:\Users\José\). Algunas herramientas dan problemas con ellas.
Paso 3: Añadir PHP al PATH
El PATH es la lista de carpetas donde Windows busca los programas cuando escribes un comando. Añadiendo C:\php podrás escribir php desde cualquier terminal.
Con la interfaz gráfica:
- Pulsa
Winy escribe “variables de entorno”. Abre Editar las variables de entorno del sistema. - Pulsa Variables de entorno….
- En “Variables de usuario”, selecciona Path y pulsa Editar.
- Pulsa Nuevo, escribe
C:\phpy acepta todas las ventanas.
Con PowerShell (para tu usuario, sin permisos de administrador):
# Añade C:\php al PATH del usuario actual
$rutaActual = [Environment]::GetEnvironmentVariable('Path', 'User')
[Environment]::SetEnvironmentVariable('Path', "$rutaActual;C:\php", 'User')
Cierra todas las terminales (y VS Code) y abre una nueva. Comprueba:
php -v
PHP 8.5.x (cli) (built: ...) (NTS Visual C++ 2022 x64)
Copyright (c) The PHP Group
Zend Engine v4.5.x, Copyright (c) Zend Technologies
with Zend OPcache v8.5.x, Copyright (c), by Zend Technologies
⚠️ Importante: Si ves “php no se reconoce como un comando interno o externo”, el PATH no está bien o no has abierto una terminal nueva. Si ves una versión antigua (por ejemplo 7.4), es que tienes otro PHP antes en el PATH (típico si instalaste XAMPP en el pasado). Comprueba cuál se está usando con
where.exe phpy reordena las entradas del PATH.
Paso 4: Crear el php.ini
php.ini es el fichero de configuración de PHP. El ZIP trae dos plantillas; para desarrollo usa la primera:
Copy-Item C:\php\php.ini-development C:\php\php.ini
| Plantilla | Diferencias clave |
|---|---|
php.ini-development | Muestra todos los errores en pantalla (display_errors = On). Ideal para aprender |
php.ini-production | Oculta los errores al usuario y los registra en un log. Lo que se usa en un servidor real |
Paso 5: Activar extensiones
Las extensiones añaden funcionalidades a PHP (cadenas multibyte, bases de datos, cURL…). Abre C:\php\php.ini con un editor y busca estas líneas. Quita el punto y coma inicial (;) para activarlas:
; Carpeta donde están las extensiones (descomenta esta línea en Windows)
extension_dir = "ext"
; Extensiones recomendadas para el curso
extension=curl
extension=fileinfo
extension=gd
extension=intl
extension=mbstring
extension=openssl
extension=pdo_mysql
extension=pdo_sqlite
extension=sodium
extension=sqlite3
extension=zip
Busca también estas directivas y ajústalas:
; Zona horaria (si no la configuras, date() usará UTC)
date.timezone = Europe/Madrid
; Mostrar todos los errores (ya vienen así en php.ini-development)
error_reporting = E_ALL
display_errors = On
display_startup_errors = On
; Límites razonables para desarrollo
memory_limit = 256M
upload_max_filesize = 20M
post_max_size = 25M
📘 Concepto: En
php.ini, el punto y coma;inicia un comentario. Por eso las extensiones vienen “apagadas”: están comentadas. Quitar el;las activa.
Comprueba qué fichero de configuración está leyendo PHP:
php --ini
Configuration File (php.ini) Path:
Loaded Configuration File: C:\php\php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
Si en “Loaded Configuration File” aparece (none), PHP no encuentra tu php.ini: revisa que se llame exactamente así (cuidado con que Windows no lo haya guardado como php.ini.txt).
3. Instalación nativa en macOS
En macOS la forma más sencilla es Homebrew, el gestor de paquetes más popular. Si no lo tienes, instálalo siguiendo las instrucciones de https://brew.sh.
# Instala la última versión estable de PHP (la rama 8.5)
brew install php
# Comprueba la versión
php -v
Si necesitas una versión concreta (por ejemplo, porque brew install php ya instale una más nueva en el futuro), el tap de Shivam Mathur ofrece todas las ramas:
brew tap shivammathur/php
brew install shivammathur/php/php@8.5
brew link --overwrite --force shivammathur/php/php@8.5
Localiza el php.ini y las extensiones:
php --ini
# Loaded Configuration File: /opt/homebrew/etc/php/8.5/php.ini
Homebrew ya incluye las extensiones más comunes (mbstring, intl, pdo_mysql, curl…). Edita ese php.ini para fijar date.timezone = Europe/Madrid.
💡 Consejo: Homebrew también instala PHP-FPM. Si más adelante quieres usarlo con Nginx, puedes arrancarlo como servicio con
brew services start php. Para este curso basta con el servidor integrado.
4. Instalación nativa en Linux
Ubuntu y derivadas: repositorio ondrej/php
Los repositorios oficiales de cada versión de Ubuntu traen una versión fija de PHP que no siempre es la última. Ondřej Surý, mantenedor de los paquetes de PHP en Debian, publica un repositorio (PPA) con todas las versiones actuales:
# 1. Herramienta para añadir repositorios
sudo apt update
sudo apt install -y software-properties-common
# 2. Añadir el repositorio de Ondřej Surý
sudo add-apt-repository ppa:ondrej/php
sudo apt update
# 3. Instalar PHP 8.5 (CLI) y las extensiones del curso
sudo apt install -y php8.5-cli php8.5-common php8.5-mbstring php8.5-intl \
php8.5-curl php8.5-xml php8.5-zip php8.5-gd php8.5-mysql php8.5-sqlite3
# 4. Comprobar
php -v
⚠️ Importante: Si instalas el paquete genérico
php8.5(sin-cli), apt instalará también Apache y su módulo de PHP. No es un problema, pero si solo quieres la línea de comandos y el servidor integrado, instalaphp8.5-cli.
En Debian el repositorio equivalente es packages.sury.org; sigue las instrucciones de su web para añadirlo.
Ficheros de configuración en Debian/Ubuntu
En estas distribuciones hay un php.ini por cada SAPI:
/etc/php/8.5/cli/php.ini ← línea de comandos y servidor integrado
/etc/php/8.5/apache2/php.ini ← Apache (si lo instalaste)
/etc/php/8.5/fpm/php.ini ← PHP-FPM (si lo instalaste)
/etc/php/8.5/mods-available/ ← un .ini por extensión
Las extensiones se activan y desactivan con:
sudo phpenmod mbstring # activar
sudo phpdismod xdebug # desactivar
5. Paquetes todo-en-uno: XAMPP y Laragon
Los paquetes todo-en-uno instalan de una vez Apache, PHP, MariaDB/MySQL y phpMyAdmin.
| Paquete | Sistemas | Ventajas | A tener en cuenta |
|---|---|---|---|
| XAMPP (Apache Friends) | Windows, macOS, Linux | Muy conocido, gratuito, panel de control sencillo | Sus versiones van muy por detrás de PHP: durante mucho tiempo su última versión ha traído PHP 8.2 |
| Laragon | Windows | Rápido, permite cambiar de versión de PHP desde el menú, crea dominios .test automáticos | Desde la versión 7 es de pago (la 6 fue la última gratuita); las versiones actuales incluyen PHP 8.5 |
| Laravel Herd | Windows, macOS | Instalación en un clic, cambio de versión de PHP sencillo | Orientado a Laravel, aunque sirve para cualquier proyecto PHP |
⚠️ Importante: Para este curso necesitas PHP 8.5. Antes de usar un paquete todo-en-uno, comprueba qué versión de PHP trae. Si trae una anterior, tienes dos opciones:
- Actualizar el PHP del paquete: en Laragon basta con descomprimir el ZIP de PHP 8.5 en
laragon\bin\php\y seleccionarlo en el menú PHP → Version. En XAMPP hay que sustituir la carpetaxampp\phppor una compilación Thread Safe de PHP 8.5 y ajustar la configuración de Apache, un proceso delicado.- Usar el paquete solo para la base de datos (MariaDB y phpMyAdmin) y ejecutar tu código con el PHP 8.5 nativo.
💡 Consejo: Si ya tenías XAMPP instalado, ten cuidado con el PATH: es muy habitual que
php -vmuestre el PHP antiguo de XAMPP (C:\xampp\php) en lugar del 8.5 que acabas de instalar. Usawhere.exe phppara saber cuál se ejecuta.
6. Docker
📘 Concepto: Docker ejecuta aplicaciones dentro de contenedores: entornos aislados y ligeros que incluyen todo lo necesario (sistema base, PHP, extensiones). Es como enviar tu proyecto dentro de un contenedor de mercancías estándar: funcionará igual en tu portátil, en el de un compañero y en el servidor.
Necesitas Docker Desktop (Windows/macOS) o Docker Engine (Linux).
Imágenes oficiales de PHP
| Imagen | Contenido | Uso |
|---|---|---|
php:8.5-cli | PHP de línea de comandos | Ejecutar scripts, Composer, tests |
php:8.5-apache | PHP + Apache con mod_php | Aplicaciones web clásicas |
php:8.5-fpm | PHP-FPM (sin servidor web) | Combinado con un contenedor Nginx |
php:8.5-cli-alpine | Versión mínima basada en Alpine Linux | Imágenes pequeñas |
Prueba rápida sin instalar nada más:
docker run --rm php:8.5-cli php -v
Ejecutar un script de la carpeta actual:
# Monta la carpeta actual en /app y ejecuta hola.php
docker run --rm -v "$PWD":/app -w /app php:8.5-cli php hola.php
En PowerShell, sustituye "$PWD" por "${PWD}".
Un entorno web completo con Docker Compose
Vamos a montar Apache + PHP 8.5 + MariaDB + phpMyAdmin. Estructura del proyecto:
mi-proyecto/
├── compose.yaml
├── docker/
│ └── php/
│ └── Dockerfile
└── public/
└── index.php
docker/php/Dockerfile:
FROM php:8.5-apache
# Extensiones del sistema necesarias para compilar extensiones de PHP
RUN apt-get update && apt-get install -y --no-install-recommends \
libicu-dev libzip-dev \
&& rm -rf /var/lib/apt/lists/*
# Extensiones de PHP: PDO para MySQL/MariaDB, intl y zip
RUN docker-php-ext-install pdo_mysql intl zip
# Xdebug para depurar (solo en desarrollo)
RUN pecl install xdebug && docker-php-ext-enable xdebug
# Usar la configuración de desarrollo que trae la imagen
RUN cp "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
# Activar mod_rewrite (URLs amigables) y servir la carpeta public/
RUN a2enmod rewrite
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
# Composer copiado desde su imagen oficial
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
compose.yaml:
services:
web:
build: ./docker/php
ports:
- "8080:80" # http://localhost:8080
volumes:
- ./:/var/www/html # tu código, sincronizado en vivo
environment:
XDEBUG_MODE: debug,develop
XDEBUG_CONFIG: client_host=host.docker.internal client_port=9003
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- db
db:
image: mariadb:11.8
environment:
MARIADB_ROOT_PASSWORD: root
MARIADB_DATABASE: curso_php
MARIADB_USER: curso
MARIADB_PASSWORD: curso
ports:
- "3306:3306"
volumes:
- datos_db:/var/lib/mysql
phpmyadmin:
image: phpmyadmin:5
ports:
- "8081:80" # http://localhost:8081
environment:
PMA_HOST: db
depends_on:
- db
volumes:
datos_db:
public/index.php:
<?php
declare(strict_types=1);
echo '<h1>PHP ' . PHP_VERSION . ' funcionando en Docker</h1>';
Comandos básicos:
docker compose up -d --build # construir y arrancar en segundo plano
docker compose ps # ver los contenedores
docker compose logs -f web # ver los logs del servidor web
docker compose exec web php -v # ejecutar un comando dentro del contenedor
docker compose exec web composer install
docker compose down # parar (los datos de la BD se conservan en el volumen)
Abre http://localhost:8080 y verás la versión de PHP. phpMyAdmin estará en http://localhost:8081 (usuario root, contraseña root).
⚠️ Importante: Las contraseñas de este
compose.yamlson solo para desarrollo local. Nunca uses credenciales así en un servidor real ni subas contraseñas reales a un repositorio.
💡 Consejo: Dentro de la red de Docker, tu código PHP se conecta a la base de datos usando como host el nombre del servicio (
db), nolocalhost. Lo verás en el módulo 15.
7. La línea de comandos de PHP
Instales como instales PHP, tendrás el ejecutable php. Estos son los comandos que más usarás:
| Comando | Qué hace |
|---|---|
php -v | Muestra la versión de PHP |
php fichero.php | Ejecuta un script |
php -m | Lista los módulos (extensiones) cargados |
php -i | Muestra toda la configuración (equivale a phpinfo() en texto) |
php --ini | Indica qué php.ini se está usando |
php -l fichero.php | Comprueba la sintaxis sin ejecutar (lint) |
php -r 'código' | Ejecuta código directamente, sin fichero |
php -a | Abre el modo interactivo |
php -S localhost:8000 | Arranca el servidor web integrado |
php --ri mbstring | Muestra la configuración de una extensión concreta |
Ejecutar código suelto con php -r
php -r 'echo PHP_VERSION, PHP_EOL;'
php -r 'echo date("d/m/Y H:i"), PHP_EOL;'
⚠️ Importante: Con
php -rno se escribe la etiqueta<?php. Y cuidado con las comillas: en PowerShell y Bash las variables$dentro de comillas dobles las interpreta la propia terminal. Usa comillas simples por fuera.
El modo interactivo: php -a
El modo interactivo (REPL) te permite escribir instrucciones y ver el resultado al momento. Es perfecto para probar funciones:
$ php -a
Interactive shell
php > echo strtoupper('hola');
HOLA
php > $precio = 19.99;
php > echo $precio * 3;
59.97
php > var_dump(str_contains('Curso de PHP', 'PHP'));
bool(true)
php > exit
💡 Consejo: Usa
php -acomo “calculadora de PHP” durante el curso: cuando dudes de qué devuelve una función, pruébala ahí en segundos.
8. El servidor web integrado
PHP incluye un pequeño servidor web para desarrollo. No necesitas instalar Apache ni Nginx para empezar.
# Sirve la carpeta actual en http://localhost:8000
php -S localhost:8000
# Sirve la carpeta public/ (lo habitual en proyectos reales)
php -S localhost:8000 -t public
# Usa un puerto distinto si el 8000 está ocupado
php -S localhost:8080
Salida en la terminal:
[Sat Oct 3 10:15:02 2026] PHP 8.5.x Development Server (http://localhost:8000) started
[Sat Oct 3 10:15:07 2026] [::1]:52144 Accepted
[Sat Oct 3 10:15:07 2026] [::1]:52144 [200]: GET /
[Sat Oct 3 10:15:07 2026] [::1]:52144 Closing
Cada petición aparece en la terminal con su código de estado, lo que resulta muy útil para depurar. Para pararlo, pulsa Ctrl + C.
⚠️ Importante: El servidor integrado es solo para desarrollo. No está pensado para soportar tráfico real ni tiene las medidas de seguridad de Apache o Nginx. Nunca lo uses en producción.
9. phpinfo(): la radiografía de tu PHP
La función phpinfo() genera una página HTML con toda la información de tu instalación: versión, php.ini cargado, extensiones, variables de entorno…
<?php
// info.php
phpinfo();
php -S localhost:8000
# Abre http://localhost:8000/info.php
Qué mirar en esa página:
| Sección | Qué te dice |
|---|---|
| Cabecera | Versión exacta de PHP (8.5.x) |
| Server API | Cómo se ejecuta PHP (Built-in HTTP server, Apache 2.0 Handler, FPM/FastCGI) |
| Loaded Configuration File | Ruta del php.ini que se está usando |
| Secciones por extensión | Si una extensión aparece, está cargada (busca mbstring, pdo_mysql, xdebug) |
| date | Zona horaria configurada |
⚠️ Importante:
phpinfo()revela muchísima información sobre tu servidor que un atacante podría aprovechar. Borrainfo.phpcuando termines y no lo subas nunca a un servidor público.
💡 Consejo: Ten en cuenta que el
php.inide la CLI y el del servidor web pueden ser distintos (sobre todo en Linux o con XAMPP). Si una extensión funciona en la terminal pero no en el navegador, comparaphp --inicon lo que dicephpinfo()en el navegador.
10. Visual Studio Code
Visual Studio Code es un editor gratuito, ligero y con extensiones para todo. Descárgalo desde https://code.visualstudio.com.
Extensiones recomendadas
| Extensión | Autor | Para qué |
|---|---|---|
| PHP Intelephense | Ben Mewburn | Autocompletado, ir a la definición, detección de errores, documentación al pasar el ratón |
| PHP Debug | Xdebug | Conecta VS Code con Xdebug para depurar paso a paso |
| EditorConfig for VS Code | EditorConfig | Respeta la configuración de sangrado y codificación del proyecto |
| Docker / Container Tools | Microsoft | Gestionar contenedores desde el editor (si usas Docker) |
Instálalas desde el panel de extensiones (Ctrl + Shift + X) o desde la terminal:
code --install-extension bmewburn.vscode-intelephense-client
code --install-extension xdebug.php-debug
code --install-extension editorconfig.editorconfig
💡 Consejo: Intelephense recomienda desactivar la extensión integrada de VS Code PHP Language Features para evitar sugerencias duplicadas. En el panel de extensiones busca
@builtin php, y desactiva “PHP Language Features” (deja activa “PHP Language Basics”, que da el coloreado).
Configuración recomendada
Abre la configuración en JSON (Ctrl + Shift + P → Preferences: Open User Settings (JSON)) y añade:
{
"intelephense.environment.phpVersion": "8.5.0",
"[php]": {
"editor.defaultFormatter": "bmewburn.vscode-intelephense-client",
"editor.formatOnSave": true,
"editor.tabSize": 4,
"editor.insertSpaces": true
},
"files.encoding": "utf8",
"files.eol": "\n",
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true
}
| Opción | Efecto |
|---|---|
intelephense.environment.phpVersion | Intelephense analiza el código como PHP 8.5 (reconoce \|>, array_first()…) |
editor.formatOnSave | Formatea el fichero al guardar |
editor.tabSize: 4 | 4 espacios de sangrado, como indica el estándar PSR-12/PER |
files.encoding: utf8 | Todos los ficheros en UTF-8 (imprescindible para tildes y eñes) |
files.eol: \n | Saltos de línea estilo Unix, el estándar en proyectos PHP |
11. Composer
📘 Concepto: Composer es el gestor de dependencias de PHP. Permite instalar librerías de terceros (y sus dependencias) con un solo comando y genera un sistema de carga automática (autoload) de clases. Es el equivalente a
npmen JavaScript opipen Python. Lo estudiarás a fondo en el módulo 13.
Instalación en Windows
Descarga y ejecuta Composer-Setup.exe desde https://getcomposer.org/download/. El instalador detecta tu php.exe (asegúrate de que señala a C:\php\php.exe) y añade Composer al PATH.
Instalación en macOS
brew install composer
Instalación en Linux (y macOS sin Homebrew)
# Descarga el instalador
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
# Ejecuta el instalador (genera composer.phar)
php composer-setup.php
# Borra el instalador
php -r "unlink('composer-setup.php');"
# Muévelo a una carpeta del PATH para usarlo como "composer"
sudo mv composer.phar /usr/local/bin/composer
⚠️ Importante: La página oficial de descarga incluye un paso adicional para verificar la firma (hash SHA-384) del instalador. El hash cambia con cada versión, así que cópialo siempre de
getcomposer.org/downloaden lugar de un tutorial.
Comprobación
composer --version
# Composer version 2.x.x ...
composer diagnose
# Comprueba la configuración, la conexión con Packagist, OpenSSL...
12. Xdebug: depurar paso a paso
📘 Concepto: Depurar consiste en ejecutar el programa pausándolo en las líneas que te interesan (puntos de interrupción o breakpoints) para ver el valor de cada variable y avanzar instrucción a instrucción. Es como ver una película fotograma a fotograma para descubrir dónde se equivoca el actor. Xdebug es la extensión de PHP que lo hace posible.
Xdebug 3.5 es la primera versión con soporte oficial para PHP 8.5.
Instalación
| Sistema | Cómo instalarlo |
|---|---|
| Windows | Descarga la DLL desde https://xdebug.org/download que coincida con tu PHP (8.5, NTS, VS17, x64). Cópiala en C:\php\ext\ y renómbrala a php_xdebug.dll |
| macOS | pecl install xdebug |
| Ubuntu (PPA ondrej) | sudo apt install php8.5-xdebug |
| Docker | pecl install xdebug && docker-php-ext-enable xdebug (como en el Dockerfile anterior) |
💡 Consejo: Si dudas de qué fichero descargar, usa el asistente de
https://xdebug.org/wizard: pegas la salida dephp -iy te dice exactamente qué DLL bajar y dónde ponerla.
Configuración
Añade al final de tu php.ini (en Ubuntu, en /etc/php/8.5/mods-available/xdebug.ini):
[xdebug]
zend_extension=xdebug
; debug = depuración paso a paso
; develop = mensajes de error mejorados y var_dump() más legible
xdebug.mode=debug,develop
; Conectar con el editor en cada petición
xdebug.start_with_request=yes
; Dónde escucha VS Code
xdebug.client_host=127.0.0.1
xdebug.client_port=9003
⚠️ Importante: Xdebug se carga con
zend_extension, no conextension. Si usasextension=xdebug, aparecerá un aviso y no funcionará.
Comprueba que está cargado:
php -v
PHP 8.5.x (cli) ...
Zend Engine v4.5.x, Copyright (c) Zend Technologies
with Xdebug v3.5.x, Copyright (c) 2002-2026, by Derick Rethans
with Zend OPcache v8.5.x, Copyright (c), by Zend Technologies
También puedes llamar a xdebug_info() en un script para ver un informe completo de su configuración.
💡 Consejo: Con
start_with_request=yes, Xdebug intenta conectar con el editor en cada ejecución, lo que ralentiza un poco PHP y puede mostrar avisos si VS Code no está escuchando. Una alternativa esxdebug.start_with_request=trigger, que solo depura cuando la petición lleva el parámetroXDEBUG_TRIGGER(por ejemplo,http://localhost:8000/?XDEBUG_TRIGGER=1).
Configurar VS Code
En VS Code, abre el panel Ejecutar y depurar (Ctrl + Shift + D), pulsa “crear un archivo launch.json” y elige PHP. Se crea .vscode/launch.json. Déjalo así:
{
"version": "0.2.0",
"configurations": [
{
"name": "Escuchar Xdebug",
"type": "php",
"request": "launch",
"port": 9003
},
{
"name": "Ejecutar el script abierto",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 9003
},
{
"name": "Escuchar Xdebug (Docker)",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html": "${workspaceFolder}"
}
}
]
}
| Configuración | Cuándo usarla |
|---|---|
| Escuchar Xdebug | VS Code espera conexiones. Luego ejecutas el script en la terminal o recargas la página en el navegador |
| Ejecutar el script abierto | VS Code lanza php con el fichero que tienes abierto. Ideal para scripts de CLI |
| Escuchar Xdebug (Docker) | Igual que la primera, pero traduce las rutas del contenedor a las de tu proyecto |
Tu primera sesión de depuración
Crea depurar.php:
<?php
declare(strict_types=1);
$precios = [12.50, 8.99, 23.00];
$total = 0;
foreach ($precios as $precio) {
$total += $precio; // ← pon aquí un punto de interrupción (F9)
}
$iva = $total * 0.21;
echo "Total con IVA: " . ($total + $iva) . PHP_EOL;
- Haz clic a la izquierda del número de la línea
$total += $precio;(o pulsaF9). Aparece un punto rojo. - Elige la configuración Ejecutar el script abierto y pulsa
F5. - La ejecución se detiene en el punto rojo. En el panel Variables verás
$precios,$precioy$totalcon sus valores. - Usa los controles de depuración:
| Botón / tecla | Acción |
|---|---|
F5 Continuar | Sigue hasta el siguiente punto de interrupción |
F10 Paso a paso por encima | Ejecuta la línea actual y pasa a la siguiente |
F11 Paso a paso por dentro | Si la línea llama a una función tuya, entra en ella |
Shift + F11 Salir | Termina la función actual y vuelve a quien la llamó |
Shift + F5 Detener | Termina la depuración |
- Pulsa
F5varias veces y observa cómo$totalva aumentando: 12.5, 21.49, 44.49.
💡 Consejo: En el panel Inspección (Watch) puedes escribir expresiones como
$total * 0.21para ver su valor en cada pausa. Y en la Consola de depuración puedes ejecutar código PHP en el contexto del punto de pausa.
13. Tu primer proyecto
Estructura recomendada
curso-php/
├── .vscode/
│ └── launch.json ← configuración de depuración
├── public/ ← lo ÚNICO accesible desde el navegador
│ ├── index.php
│ └── css/
│ └── estilos.css
├── src/ ← tu código PHP (clases, funciones)
├── scripts/ ← scripts de línea de comandos
│ └── hola.php
├── .editorconfig
├── .gitignore
└── composer.json ← cuando uses Composer
📘 Concepto: La carpeta
public/es la raíz web (document root): solo lo que hay dentro se puede pedir desde el navegador. El resto del código (configuración, clases, contraseñas de la base de datos) queda fuera de su alcance. Es una medida de seguridad básica que usan todos los frameworks.
.editorconfig:
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[*.{yml,yaml,json}]
indent_size = 2
“Hola mundo” en la línea de comandos
scripts/hola.php:
<?php
declare(strict_types=1);
$nombre = $argv[1] ?? 'mundo'; // primer argumento de la terminal, o 'mundo'
echo "¡Hola, {$nombre}!" . PHP_EOL;
echo 'Estás usando PHP ' . PHP_VERSION . ' en ' . PHP_OS_FAMILY . PHP_EOL;
php scripts/hola.php
php scripts/hola.php Ana
Salida:
¡Hola, mundo!
Estás usando PHP 8.5.x en Windows
¡Hola, Ana!
Estás usando PHP 8.5.x en Windows
📘 Concepto:
$argves un array con los argumentos que recibe un script de línea de comandos.$argv[0]es el nombre del propio script y$argv[1]el primer argumento. El operador??devuelve'mundo'si no existe (lo verás en el módulo 03).
“Hola mundo” en el navegador
public/index.php:
<?php
declare(strict_types=1);
$titulo = 'Mi primer proyecto PHP';
$version = PHP_VERSION;
$fecha = date('d/m/Y H:i');
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $titulo ?></title>
<link rel="stylesheet" href="css/estilos.css">
</head>
<body>
<main>
<h1>¡Hola, mundo!</h1>
<p>Esta página la ha generado <strong>PHP <?= $version ?></strong>.</p>
<p>Fecha y hora del servidor: <?= $fecha ?></p>
</main>
</body>
</html>
public/css/estilos.css:
body {
font-family: system-ui, sans-serif;
background: #f4f4f8;
display: grid;
place-items: center;
min-height: 100vh;
margin: 0;
}
main {
background: white;
padding: 2rem 3rem;
border-radius: 12px;
box-shadow: 0 4px 20px rgb(0 0 0 / 0.08);
}
h1 {
color: #777bb3; /* el morado del logo de PHP */
}
Arranca el servidor desde la raíz del proyecto:
php -S localhost:8000 -t public
Abre http://localhost:8000. Verás tu página con la versión de PHP y la fecha. Recarga: la hora cambia en cada petición, porque PHP genera la página de nuevo cada vez.
✏️ Ejercicio: Abre “Ver código fuente” en el navegador (
Ctrl + U) y comprueba que no queda ni rastro del código PHP: solo HTML.
Errores comunes al empezar
| Problema | Causa probable | Solución |
|---|---|---|
| El navegador muestra el código PHP o descarga el fichero | Has abierto el fichero con doble clic (file:///) | Accede siempre por http://localhost:8000 |
php no se reconoce como comando | PHP no está en el PATH o la terminal es antigua | Revisa el PATH y abre una terminal nueva |
php -v muestra otra versión | Otro PHP (XAMPP, etc.) va antes en el PATH | where.exe php (Windows) o which php (Linux/macOS) |
Call to undefined function mb_strlen() | Extensión mbstring desactivada | Descomenta extension=mbstring en php.ini |
Failed to listen on localhost:8000 | El puerto está ocupado | Usa otro puerto: php -S localhost:8080 |
Las tildes se ven como á | Fichero no guardado en UTF-8 o falta <meta charset> | Guarda en UTF-8 y añade <meta charset="UTF-8"> |
| La hora sale con 1 o 2 horas de diferencia | Zona horaria no configurada | date.timezone = Europe/Madrid en php.ini |
14. Ejercicios
Ejercicio 1: Instalación verificada
Instala PHP 8.5 con el método que prefieras y guarda en un fichero entorno.txt la salida de estos comandos: php -v, php --ini y php -m. Comprueba que aparecen mbstring, intl, pdo_mysql y openssl.
Ejercicio 2: Configura tu php.ini
Modifica tu php.ini para que la zona horaria sea Europe/Madrid y memory_limit sea 512M. Verifica los cambios sin abrir el fichero, usando:
php -r 'echo ini_get("date.timezone"), " - ", ini_get("memory_limit"), PHP_EOL;'
Ejercicio 3: Explora el modo interactivo
Abre php -a y averigua el resultado de estas expresiones. Anota cada resultado:
echo PHP_VERSION;echo PHP_OS_FAMILY;echo strrev('reconocer');echo str_repeat('=-', 10);echo date('l');var_dump(10 / 4);
Ejercicio 4: Página de diagnóstico
Crea public/diagnostico.php que muestre en una tabla HTML: la versión de PHP (PHP_VERSION), el sistema operativo (PHP_OS_FAMILY), la zona horaria (date_default_timezone_get()), la ruta del php.ini (php_ini_loaded_file()) y si están cargadas las extensiones mbstring, intl y xdebug (usa extension_loaded('mbstring'), que devuelve true o false). Sírvela con php -S y ábrela en el navegador.
Ejercicio 5: Depura un bucle
Escribe un script que sume los números del 1 al 10 con un bucle for (puedes copiar la estructura del ejemplo de depuración y adaptarla). Pon un punto de interrupción dentro del bucle y, usando solo el depurador, apunta el valor de la variable acumuladora en cada vuelta. ¿En qué vuelta supera el valor 20?
Ejercicio 6: Entorno con Docker
Monta el entorno de la sección 6 con docker compose up -d --build. Comprueba que:
http://localhost:8080muestra la versión de PHP 8.5.docker compose exec web php -mincluyepdo_mysqlyxdebug.- Puedes entrar en phpMyAdmin (
http://localhost:8081) y ver la base de datoscurso_php.
Ejercicio 7: Saludo con argumentos
Amplía scripts/hola.php para que acepte dos argumentos: nombre y ciudad (php scripts/hola.php Ana Sevilla) y muestre “¡Hola, Ana de Sevilla!”. Si falta la ciudad, debe mostrar solo “¡Hola, Ana!”. Pista: $argv[2] ?? null.
Resumen
| Concepto | Comando / sintaxis |
|---|---|
| Ver versión | php -v |
| Ver extensiones | php -m |
Ver php.ini cargado | php --ini |
| Configuración completa | php -i o phpinfo() |
| Comprobar sintaxis | php -l fichero.php |
| Ejecutar código suelto | php -r 'echo 1 + 1;' |
| Modo interactivo | php -a |
| Servidor integrado | php -S localhost:8000 -t public |
| Activar extensión | extension=mbstring en php.ini |
| Activar Xdebug | zend_extension=xdebug + xdebug.mode=debug |
| Puerto de Xdebug | 9003 |
| Instalar librería | composer require vendor/paquete |
| Docker CLI | docker run --rm php:8.5-cli php -v |
| Docker web | php:8.5-apache + compose.yaml con MariaDB |
| Ubuntu | ppa:ondrej/php → apt install php8.5-cli |
| macOS | brew install php |
| Windows | ZIP VS17 x64 Non Thread Safe en C:\php + PATH |