🐘 Curso PHP · Nivel N1 Principiante

Bloque 1: Primer servidor y fundamentos

Los cursos anteriores corrían en tu navegador; PHP vive en el servidor. En este bloque montarás tu primer entorno local (XAMPP), escribirás tus primeros scripts y dominarás las piedras angulares del lenguaje: variables, tipos, operadores y estructuras de control. A partir de aquí, todo el backend del curso se apoya en esta base.

⏱ ≈ 12 horas 📚 5 lecciones ✍️ 18 ejercicios guiados 📝 Examen final superable (≥ 70 %)
Lección 1 · Teoría

El servidor y PHP

Hasta ahora todo tu código era cliente: HTML, CSS y JavaScript se descargan y ejecutan en el navegador de quien visita tu web. PHP es lenguaje de servidor: su código se ejecuta en la máquina que aloja la web y solo envía el resultado al visitante. Ahí está su gran ventaja: puedes acceder a bases de datos, leer ficheros, iniciar sesiones y generar contenido dinámico antes de que el HTML llegue al navegador.

🤔 ¿Y si el usuario ve el código PHP? No puede. El servidor ejecuta PHP (etiqueta <?php ... ?>) y solo entrega el HTML resultante. Si alguna vez ves código PHP en pantalla, es que el servidor no está interpretándolo (falta activarlo o no usas un servidor).

1.1 · Cliente vs servidor

Quién ejecuta qué
LenguajeDónde se ejecutaPara qué
HTML / CSSNavegadorEstructura y estilo
JavaScriptNavegadorInteractividad en el cliente
PHPServidorLógica, datos y seguridad del lado servidor

1.2 · XAMPP: tu primer servidor local

XAMPP (y alternativas como Laragon) instala en tu ordenador un paquete con todo lo que necesitas: el servidor Apache (que responde a las peticiones), el intérprete de PHP y el gestor de bases de datos MySQL/MariaDB.

  • Descarga e instala XAMPP (apachefriends.org).
  • Abre el panel y pulsa Start en «Apache».
  • Tus proyectos van en la carpeta htdocs dentro de la instalación de XAMPP.
  • En el navegador escribes localhost/mi-proyecto/ en lugar de abrir el archivo con doble clic.
💡 Regla de oro: para que PHP funcione, SIEMPRE abre la web a través de localhost. Abrir un .php con doble clic (file://) mostrará el código en bruto o lo descargará, porque no hay ningún servidor interpretándolo.

1.3 · phpinfo() para comprobar el entorno

htdocs/verphp.php
<?php
    // Muestra una página enorme con toda la configuración de PHP
    phpinfo();
?>

Abre localhost/verphp.php. Si ves una tabla con la configuración, tu servidor PHP funciona perfectamente. Este archivo solo es para pruebas: elimínalo después.

Lección 2 · Teoría

Sintaxis y primer script

2.1 · Las etiquetas de apertura y cierre

PHP se «enciende» y «apaga» dentro del HTML con unas etiquetas especiales. Todo lo que esté dentro de ellas se ejecuta en el servidor; todo lo que esté fuera es HTML normal que se envía tal cual:

mezcla de HTML y PHP
<h1>Mi página dinámica</h1>

<?php
    // aquí dentro va el código PHP que se ejecuta en el servidor
    echo "Hola desde el servidor";
?>

<p>Esto ya es HTML de nuevo</p>
⚠️ Siempre que pongas código PHP en un archivo con HTML, el archivo debe tener extensión .php (por ejemplo index.php), no .html. Así el servidor sabe que debe interpretarlo.

2.2 · echo y el punto y coma

echo es la instrucción que imprime/emite texto hacia el navegador. Cada instrucción termina en punto y coma ; — olvidarlo es el error de sintaxis más frecuente en PHP.

mi primer script
<?php
    echo "¡Hola, mundo!";
    echo "Me llamo PHP y corro en el servidor.";
?>

2.3 · Comentarios

PHP admite los mismos comentarios que JavaScript, más el estilo de shell con #:

tres sabores
<?php
    // Comentario de una línea
    # Otro comentario de una línea (estilo shell)

    /*
       Comentario de bloque:
       ocupa varias líneas y sirve para
       explicar secciones o desactivar código.
    */
?>

2.4 · Atajos: echo corto y plantillas

Existe un atajo para imprimir en una sola línea — <?= ... ?> — muy usado dentro de plantillas. Es exactamente lo mismo que <?php echo ...; ?>:

interpolar dentro de HTML
<p>Bienvenido, <?= "usuario" ?>.</p>
💡 echo no es una función, es una construcción del lenguaje: se escribe sin paréntesis (aunque echo("hola") también funciona). Puedes encadenar varios valores con comas: echo "a", "b", "c";.
Lección 3 · Teoría

Variables, constantes y tipos

3.1 · Variables: siempre van con $

Las variables en PHP se escriben con un signo de dólar delante ($nombre) y son débiles/tipadas en tiempo de ejecución: puedes guardar un número y luego un texto en la misma variable sin cambiar nada. A diferencia de JavaScript, no usas let ni const para declararlas — basta con asignar:

asignar, reasignar y cambiar de tipo
<?php
    $nombre = "Raúl";
    $edad = 34;
    echo "Me llamo $nombre";   // variables se interpola dentro de dobles comillas

    $edad = 35;               // reasignar
    $edad = "treinta y cinco"; // PHP lo permite: cambia de tipo
?>

3.2 · Nombres de variables

  • Deben empezar por $ y luego una letra o guion bajo _.
  • Distinguen mayúsculas: $Nombre y $nombre son variables DIFERENTES.
  • Se recomienda snake_case: $precio_total, $año_nacimiento.
  • No uses espacios ni guiones ($mi-variable se interpreta como una resta).

3.3 · Constantes

Para valores fijos hay dos formas: la función define() (clásica, global) y la palabra clave const (a partir de PHP 5.3, más recomendada). Por convención se escriben en MAYÚSCULAS. No llevan $:

dos formas de crear constantes
<?php
    const IVA = 0.21;
    const EMPRESA = "TécnicoWeb";

    define("MAX_INTENTOS", 3);

    echo EMPRESA, " IVA: ", IVA;
    // IVA = 0.22; ❌ No se puede reasignar una constante
?>

3.4 · Los tipos de datos básicos

Tipos que dominarás este bloque
TipoEjemploPara…
string"hola", 'adiós'Texto
int42, -3Números enteros
float3.14, 2.5e3Números con decimales
booltrue, falseVerdadero/falso
null$vacio = null;«Sin valor»
array[1, 2, 3]Colecciones (los verás en el Bloque 2)

3.5 · var_dump() y gettype(): el detective

var_dump() muestra el tipo y el valor de una variable (ideal para depurar); gettype() devuelve el tipo como texto:

inspeccionar variables
<?php
    $precio = 19.99;
    var_dump($precio);       // float(19.99)
    echo gettype($precio); // "double" (float en PHP)
?>

3.6 · Comillas simples vs dobles

comillas dobles: interpolan
$usuario = "Alba";
echo "Hola, $usuario";   // Hola, Alba
comillas simples: texto literal
$usuario = "Alba";
echo 'Hola, $usuario';  // Hola, $usuario (literal)

Con las dobles, la variable se sustituye (interpola); con las simples, se muestra la palabra $usuario tal cual. Las simples son un pelín más rápidas y a veces más legibles para texto sin variables.

💡 Si dentro de una cadena con dobles comillas necesitas un «$» literal, escápalo con \ echo "\$usuario" imprime $usuario.
Lección 4 · Teoría

Operadores y cadenas

4.1 · Operadores aritméticos

Los básicos
OperadorHaceEjemplo
+ - *Suma, resta, multiplicación7 * 6 // 42
/División7 / 2 // 3.5
%Resto (módulo)7 % 2 // 1
**Potencia2 ** 10 // 1024

4.2 · Asignación con atajos

menos tinta, mismo resultado
$puntos += 10;   // $puntos = $puntos + 10
$vida   -= 5;    // $vida = $vida - 5
$saldo  *= 2;    // $saldo = $saldo * 2
$visitas++;       // suma 1   |   $visitas-- resta 1

4.3 · Concatenación con el punto

En PHP la «suma» de textos se hace con el punto . (no con +). El operador = combinado con el punto (.=) permite añadir texto al final de un string:

concatenar con . y .=
$nombre = "Raúl";
$texto = "Hola, " . $nombre;   // "Hola, Raúl"

$msg = "Puntos: ";
$msg .= 10;                       // $msg = "Puntos: 10"

4.4 · Comparación y lógicos

PHP tiene dos niveles de comparación, igual que JavaScript: suelta (==, convierte tipos) y estricta (===, exige mismo tipo y valor). Escribe === por defecto:

❌ == convierte antes de comparar
"5" == 5       // true 😱
0 == "abc"     // true 😱 (PHP antiguo)
✅ === exige mismo tipo
"5" === 5      // false ✔️
5 === 5       // true ✔️

Lógicos: && (y), || (o), ! (no). También existen las variantes textuales and, or, xor.

4.5 · Funciones de cadenas esenciales

el día a día con strings
$frase = "Hola Mundo";

strlen($frase)          // 10 — longitud en caracteres
strtoupper($frase)     // "HOLA MUNDO"
strtolower($frase)     // "hola mundo"
ucfirst("hola")        // "Hola" — primera en mayúscula
str_replace("Mundo", "PHP", $frase) // "Hola PHP"
str_contains($frase, "ola") // true (PHP 8)
trim("  texto  ")     // "texto" — quita espacios
substr($frase, 0, 4) // "Hola" — recorta
💡 En PHP 8 (el que usaremos) hay funciones estupendas y «limpias» como str_contains, str_starts_with y str_ends_with. En versiones antiguas había que usar strpos() con trucos.
Lección 5 · Teoría

Estructuras de control

5.1 · Condicionales: if / elseif / else

tomar decisiones
$edad = 17;

if ($edad >= 18) {
    echo "Eres mayor de edad.";
} elseif ($edad >= 13) {
    echo "Eres adolescente.";
} else {
    echo "Eres un niño.";
}

5.2 · El operador ternario y el fusión de null

expresiones compactas
// Ternario: (condición) ? valor_si_true : valor_si_false
$mensaje = ($edad >= 18) ? "Mayor" : "Menor";

// Fusión de null (PHP 7+): usa $nombre si no es null, si no el «??» usa la alternativa
$rol = $usuario['rol'] ?? "invitado";

5.3 · switch

Cuando comparas la misma variable con varios valores fijos, switch es más legible. No olvides el break en cada caso:

elegir entre varios casos
$día = "viernes";

switch ($día) {
    case "lunes":
    case "martes":
    case "miércoles":
    case "jueves":
        echo "Entre semana";
        break;
    case "viernes":
        echo "¡Casi fin de semana!";
        break;
    default:
        echo "Fin de semana";
}

5.4 · match (PHP 8): el sucesor moderno

match es como un switch pero es una expresión (devuelve un valor) y no necesita break:

match devuelve un valor
$nota = "A";

$mensaje = match ($nota) {
    "A" => "Excelente",
    "B" => "Muy bien",
    "C" => "Aprobado",
    default => "No presentado",
};

5.5 · Bucles: for, while y el todopoderoso foreach

repetir con for y while
// for: sabemos cuántas veces
for ($i = 1; $i <= 5; $i++) {
    echo "$i ";
}

// while: mientras se cumpla la condición
$contador = 0;
while ($contador < 3) {
    echo "vuelta $contador\n";
    $contador++;
}
foreach recorre arrays y colecciones
$paises = ["España", "Francia", "Italia"];

foreach ($paises as $pais) {
    echo "$pais\n";
}

// con índice/clave
foreach ($paises as $indice => $pais) {
    echo "$indice: $pais\n";
}
💡 foreach es, con diferencia, el bucle más usado en PHP en el mundo real: con él recorres listas de productos, usuarios, filas de una base de datos… Domínalo en ambos formatos.
Práctica guiada

✍️ Los 18 ejercicios del bloque

Crea la carpeta php-b1/ dentro de htdocs y resuelve en orden — cada ejercicio usa lo aprendido en los anteriores. Abre cada archivo escribiendo en el navegador localhost/php-b1/ej01.php, ej02.php… (¡siempre a través de localhost!).

⚠️ A partir de este bloque, los ejercicios PUEDEN mostrar HTML además de texto: usa echo para imprimir y comprueba el comportamiento en tu navegador con F12 → pestaña «Red» si necesitas depurar.

Sección A · Servidor y sintaxis

1 Hola desde el servidor

Crea ej01.php con un <?php ?> que imprima con echo dos frases: «¡Hola, mundo!» y «Corro en el servidor.» en dos líneas distintas. Ábrelo a través de localhost.

Ver solución
<?php
    echo "¡Hola, mundo!\n";
    echo "Corro en el servidor.\n";
?>

2 Documenta tu script

Añade a ej01.php un comentario de bloque arriba con tu nombre y fecha, y un comentario de una línea que explique cada echo. Prueba además el estilo #.

Ver solución
/*
  ej01.php — primer script
  Autor: Raúl · 28/08/2026
*/
<?php
    // saludo inicial al cargar la página
    echo "¡Hola, mundo!\n";
    # explicación en estilo shell
    echo "Corro en el servidor.\n";
?>

3 html en el mismo archivo

Crea ej03.php que combine HTML y PHP: un <h1> estático, y debajo un bloque PHP con echo mostrando tu ciudad y año. Usa el atajo <?= ?> en al menos un punto para imprimir dentro de una etiqueta <p>.

Ver solución
<h1>Mi ficha</h1>

<p>Vivo en <?= "Madrid" ?>.</p>

<?php
    echo "Año: 2026";
?>

Sección B · Variables, constantes y tipos

4 Ficha en variables

Declara $nombre, $edad y $ciudad con tus datos. Muestra con un único echo (interpolando las variables en dobles comillas) la frase: «Me llamo ___ , tengo ___ años y vivo en ___.»

Ver solución
<?php
    $nombre = "Raúl";
    $edad = 34;
    $ciudad = "Madrid";

    echo "Me llamo $nombre, tengo $edad años y vivo en $ciudad.\n";
?>

5 Reasignación libre

PHP permite reasignar y cambiar de tipo sin problema. Parte de $puntos = 0, súbelo a 10 y luego a 25. Después asigna a $puntos el texto "veinticinco". Muestra cada valor con un echo y usa var_dump al final para ver su tipo.

Ver solución
<?php
    $puntos = 0;
    $puntos = 10;
    $puntos = 25;
    echo "$puntos\n";

    $puntos = "veinticinco";
    echo "$puntos\n";
    var_dump($puntos);
?>

6 Constantes de la empresa

Crea con const las constantes EMPRESA, NUMERO_SEDE_ANIO y con define() la constante MAX_INTENTOS. Imprímelas todas y trata de reasignar una en un comentario explicando el error esperado.

Ver solución
<?php
    const EMPRESA = "TécnicoWeb";
    const NUMERO_SEDE_ANIO = 2026;

    define("MAX_INTENTOS", 3);

    echo EMPRESA, "\n";
    echo NUMERO_SEDE_ANIO, "\n";
    echo MAX_INTENTOS, "\n";
    // EMPRESA = "Otra"; ❌ No se puede reasignar una constante
?>

7 Detective de tipos

Declara una variable de cada tipo visto (string, int, float, bool, null) y, para cada una, muestra su valor con var_dump(). Observa cómo varían los tipos en la salida.

Ver solución
<?php
    $texto   = "hola";
    $numero  = 42;
    $decimal = 3.14;
    $activo  = true;
    $vacio   = null;

    var_dump($texto, $numero, $decimal, $activo, $vacio);
?>

8 Simples vs dobles

Con $usuario = "Alba", muestra en una línea con comillas dobles "Hola, $usuario" y en otra con comillas simples 'Hola, $usuario'. Añade un comentario que explique por qué los resultados difieren.

Ver solución
<?php
    $usuario = "Alba";

    echo "Hola, $usuario\n";      // Hola, Alba — interpola
    echo 'Hola, $usuario\n';      // $usuario literal, y \n no salta línea
?>

Sección C · Operadores y cadenas

9 Calculadora de compra

$precio = 19.99, $unidades = 3. Calcula subtotal, IVA (21 %) y total, y muestra los tres valores con echo y concatenación con punto.

Ver solución
<?php
    $precio   = 19.99;
    $unidades = 3;

    $subtotal  = $precio * $unidades;
    $cuota_iva = $subtotal * 0.21;
    $total     = $subtotal + $cuota_iva;

    echo "Subtotal: " . $subtotal . "\n";
    echo "IVA: " . $cuota_iva . "\n";
    echo "Total: " . $total . "\n";
?>

10 ¿Par o impar?

Con el módulo, muestra el resto de dividir 7 entre 2 y 8 entre 2, y comenta qué significa cada resultado. Después guarda en $es_par el resultado de comprobar si 8 % 2 === 0 (usando la comparación estricta).

Ver solución
<?php
    echo "7 % 2 = " . (7 % 2) . " (impar)\n";
    echo "8 % 2 = " . (8 % 2) . " (par)\n";

    $es_par = (8 % 2 === 0);
    var_dump($es_par); // bool(true)
?>

11 Contador de visitas

Parte de $visitas = 100. Súmale 50 con +=, réstale 20, incrementa con ++ y muestra el valor después de cada paso (usa varios echo).

Ver solución
<?php
    $visitas = 100;
    echo "$visitas\n";

    $visitas += 50;
    echo "$visitas\n";

    $visitas -= 20;
    echo "$visitas\n";

    $visitas++;
    echo "$visitas\n";
?>

12 Reloj matemático

Convierte 3725 segundos a horas, minutos y segundos usando SOLO divisiones y módulos. Pista: / 3600, luego % 3600, / 60… Muestra 1h 2m 5s usando intdiv() (división entera) o el cast (int).

Ver solución
<?php
    $total = 3725;

    $horas   = intdiv($total, 3600);   // 1
    $resto   = $total % 3600;          // 125
    $minutos = intdiv($resto, 60);    // 2
    $segundos = $resto % 60;        // 5

    echo "$horas" . "h " . $minutos . "m " . $segundos . "s\n";
?>

13 Comparador estricto

Muestra con var_dump los resultados de: 5 == "5", 5 === "5", "a" !== "b" y 18 >= 18. Comenta cada línea explicando el porqué.

Ver solución
<?php
    var_dump(5 == "5");    // true: == convierte "5" a int antes
    var_dump(5 === "5");   // false: int ≠ string
    var_dump("a" !== "b"); // true: son distintos
    var_dump(18 >= 18);    // true: incluye el límite
?>

14 Fábrica de cadenas

Partiendo de $frase = " aprendo PHP en TecnicoWeb ": muestra su longitud con strlen(), límpiala con trim(), conviértela a mayúsculas y sustituye «PHP» por «el backend» con str_replace(). Muestra cada resultado por separado.

Ver solución
<?php
    $frase = "  aprendo PHP en TecnicoWeb  ";

    echo strlen($frase) . "\n";
    $frase = trim($frase);
    echo strtoupper($frase) . "\n";
    echo str_replace("PHP", "el backend", $frase) . "\n";
?>

15 Orden de precedencia

Calcula y muestra el resultado de la expresión 2 + 3 * 4 y de la versión con paréntesis (2 + 3) * 4. Comenta qué operador gana y por qué.

Ver solución
<?php
    echo (2 + 3 * 4) . "\n";     // 14: * primero, luego +
    echo ((2 + 3) * 4) . "\n";  // 20: los paréntesis mandan
?>

Sección D · Estructuras de control

16 Mayor de edad

Con $edad = 17, muestra mediante if / elseif / else mensajes distintos para mayor de edad (≥ 18), adolescente (≥ 13) y niño. Cambia el valor a 21 y comprueba que el mensaje cambia.

Ver solución
<?php
    $edad = 17;

    if ($edad >= 18) {
        echo "Mayor de edad\n";
    } elseif ($edad >= 13) {
        echo "Adolescente\n";
    } else {
        echo "Niño\n";
    }
?>

17 Días de la semana con match

Usa match (PHP 8) para clasificar $dia = "viernes" como «entre semana» (lunes–jueves), «¡casi!» (viernes) o «finde» (sábado–domingo). Guarda el resultado en una variable y muéstrala con echo.

Ver solución
<?php
    $dia = "viernes";

    $mensaje = match ($dia) {
        "lunes", "martes", "miércoles", "jueves" => "Entre semana",
        "viernes" => "¡Casi fin de semana!",
        "sábado", "domingo" => "Fin de semana",
        default => "Día no válido",
    };

    echo $mensaje . "\n";
?>

18 🏆 Proyecto integrador: «lista-productos.php»

Une TODO el bloque en un solo archivo que genere la ficha de unos productos con su total:

  • Al menos 3 variables con snake_case (mezcla números y cadenas).
  • Al menos una operación aritmética entre variables (subtotal/IVA/total).
  • Al menos una concatenación con el punto . y una interpolación en comillas dobles.
  • Uso de una constante (const o define()) para el IVA.
  • Un if que muestre un mensaje si el total supera un umbral (p. ej. 50).
  • Un foreach que recorra un array de nombres de productos y los liste.
  • Alguna función de cadenas vista (strtoupper, trim, etc.).

Este ejercicio es el reto del laboratorio del examen: la validación automática comprobará estos criterios sobre el código dentro de las etiquetas <?php ... ?>.

Evaluación del bloque

📝 Examen del Bloque 1

Dos partes: un test teórico autoevaluable (mínimo 70 %) y un reto práctico de autocorrección con checklist.

Parte A · Test teórico (aprueba con 11/15)

1 · ¿Dónde se ejecuta el código PHP?
2 · Para que PHP funcione con XAMPP, debes abrir tus archivos…
3 · ¿Qué instrucción imprime texto en PHP?
4 · ¿Cómo se declara una variable en PHP?
5 · ¿Cuál es la diferencia entre $Nombre y $nombre?
6 · ¿Qué hace echo "Hola, $nombre" con comillas DOBLES?
7 · ¿Con qué operador se concatena texto en PHP?
8 · ¿Qué devuelve 8 % 2?
9 · ¿Cuál es la semántica de 5 === "5"?
10 · ¿Qué pasa si usas == con "5" == 5?
11 · ¿Qué función te muestra el tipo y valor de una variable?
12 · ¿Cuál de estas se usa para recorrer un array en PHP?
13 · ¿Cuál es el sucesor moderno de switch que devuelve un valor en PHP 8?
14 · ¿Qué devuelve str_replace("a", "o", "casa")?
15 · ¿Qué hace trim(" hola ")?

Parte B · Reto práctico final

Construye el ejercicio 18 («lista-productos.php») sin mirar soluciones y valida tú mismo/a estos criterios sobre el contenido de tus etiquetas <?php ... ?>. Mínimo para aprobar: 6 de 7 casillas.

Cumplidos: 0 / 7

🎉 ¿Superaste las dos partes? Enhorabuena: has aprobado el Bloque 1 de PHP. Ya montas tu servidor local, escribes scripts y controlas variables, operadores y estructuras de control. En el Bloque 2 aprenderás arrays, ficheros y sesiones: ahí tus páginas empezarán a funcionar de verdad.