🔎 Buscar

🐘 Fundamentos de PHP

Sintaxis, variables, tipos, operadores, control de flujo, arrays, strings, funciones, superglobals, formularios y manejo de errores en PHP 8 explicados con ejemplos completos.

Wiki / Apuntes📖 Contenido

Fundamentos de PHP

PHP es un lenguaje de scripting del lado del servidor diseñado para la web. Se ejecuta en el servidor, genera HTML y se integra con bases de datos. En su versión 8 es un lenguaje moderno con tipos estrictos, expresiones poderosas y un ecosistema (Composer, Laravel, Symfony) enorme. Este artículo cubre la base completa: de los tags de apertura hasta el manejo de errores, con ejemplos ejecutables.

Sintaxis básica: tags, echo y comentarios

El código PHP se incrusta en HTML o se ejecuta como scripts puros. Todo bloque abre con <?php y cierra con ?> (opcional en archivos solo PHP; se recomienda omitirlo para evitar espacios en blanco accidentales en la salida).

<?php
// Comentario de una línea
# Otro comentario de una línea (estilo shell)
/* Comentario de varias líneas
   que sigue y sigue */

echo "Hola, mundo";   // echo imprime sin retorno de carro
print "Hola";         // print devuelve 1

💡 echo no es una función sino una construcción del lenguaje: admite múltiples argumentos echo "a", "b" y es más rápido que print. Para depurar usa var_dump($x) (tipo y valor) o print_r($x) (más legible para arrays).

Variables y tipos

Las variables comienzan con $. PHP es débilmente tipado: el tipo se convierte según el contexto, pero PHP 8 permite declarar tipos en parámetros y retornos.

<?php
$nombre = "Ana";          // string
$edad = 30;               // int
$precio = 19.99;          // float
$activo = true;           // bool
$nada = null;             // null

echo "Hola $nombre";                    // interpolación (comillas dobles)
echo "Hola " . $nombre;                 // concatenación con .
Tipo Descripción Ejemplo
int Enteros (64 bits) 42
float Números de coma flotante 3.14
string Cadenas "hola"
bool Booleano true
array Colección ordenada [1, 2, 3]
null Ausencia de valor null
mixed Cualquier tipo (PHP 8) mixed $x
object Instancia de una clase new Usuario()

⚠️ PHP no es estrictamente tipado por defecto: "10" + 5 devuelve 15 por coerción. Si quieres comparaciones y operaciones estrictas, declara declare(strict_types=1); como primera línea del archivo y usa === en lugar de ==.

<?php
declare(strict_types=1);

function precioConIva(float $precio): float
{
    return $precio * 1.21;
}

var_dump(precioConIva(100));   // float(121)
var_dump((int) "42");          // int(42) — casting explícito

💡 PHP 8.0 añadió union types (int|string) y el tipo mixed. Con strict_types=1, una función que acepta int|string rechaza float, lo que hace tus APIs mucho más predecibles.

Operadores

<?php
$a = 10;
$b = 3;

echo $a + $b;   // 13 (aritméticos: + - * / % **)
$a += 5;        // asignación combinada; también -= *= .= etc.
echo $a == $b;  // igualdad suelta (10 == "10" es true)
echo $a === $b; // identidad estricta (tipo y valor)
echo $a <=> $b; // spaceship: -1, 0 o 1
echo $a ?? $b;  // fusión null: $a si no es null, si no $b
echo $x && $y;  // lógicos: && || !

💡 El operador spaceship <=> devuelve -1, 0 o 1 y es ideal para funciones de comparación en usort(). La fusión null ?? sustituye al patrón isset($x) ? $x : $default.

Control de flujo

if / elseif / else y match

<?php
$nota = 8.5;

if ($nota >= 9) {
    echo "Sobresaliente";
} elseif ($nota >= 5) {
    echo "Aprobado";
} else {
    echo "Suspenso";
}

// match: expresión que devuelve valor, comparación estricta, exhaustiva
$dia = 'sábado';
$esFinDeSemana = match ($dia) {
    'sábado', 'domingo' => true,
    default => false,
};

💡 PHP soporta sintaxis alternativa con : y endif, muy usada en plantillas: <?php if ($x): ?> ... <?php endif; ?>. match admite condiciones combinadas ('a', 'b' => ...) y sin default lanza UnhandledMatchError.

Bucles

<?php
// for clásico
for ($i = 1; $i <= 5; $i++) {
    echo "Vuelta $i ";
}

// foreach sobre arrays asociativos
$usuarios = ['ana' => 'Ana García', 'luis' => 'Luis Pérez'];
foreach ($usuarios as $clave => $valor) {
    echo "$clave$valor ";
}

// break y continue
for ($i = 1; $i <= 10; $i++) {
    if ($i % 2 === 0) continue;   // salta pares
    if ($i === 7) break;          // se detiene en 7
    echo "$i ";
}

// while (y do-while para ejecutar al menos una vez)
$i = 1;
while ($i <= 3) {
    echo $i . " ";
    $i++;
}

Arrays

Los arrays son mapas ordenados: asocian claves a valores. Pueden ser indexados (claves numéricas automáticas) o asociativos.

<?php
$frutas = ['manzana', 'pera', 'uva'];
echo $frutas[0];  // manzana

$producto = [
    'nombre' => 'Portátil',
    'precio' => 899,
    'stock'  => 12,
];
echo $producto['precio'];  // 899

$frutas[] = 'plátano';   // añadir al final
isset($producto['stock']);   // true

// Transformaciones con funciones de orden superior
$numeros = [1, 2, 3, 4, 5];

$cuadrados = array_map(fn($n) => $n ** 2, $numeros);      // [1, 4, 9, 16, 25]
$pares     = array_filter($numeros, fn($n) => $n % 2 === 0); // [2, 4]
$suma      = array_reduce($numeros, fn($acc, $n) => $acc + $n, 0); // 15

sort($numeros);               // ordena y reindexa (modifica el original)
asort($numeros);              // ordena manteniendo claves
$merge = array_merge([1, 2], [3, 4]);        // [1, 2, 3, 4]
$spread = [...[1, 2], ...[3, 4]];            // spread (PHP 7.4+): igual

💡 El spread operator ... en arrays (PHP 7.4+, y con claves string en PHP 8.1+) fusiona arrays de forma concisa: $config = [...$base, ...$override]; donde el último gana. En funciones se usa para variadics.

Strings

<?php
$nombre = 'Ana';
$apellido = 'García';

$completo = $nombre . ' ' . $apellido;        // concatenación
echo "Hola, {$nombre} {$apellido}";           // interpolación

strlen('hola');                        // 4
strtoupper('hola');                    // HOLA
ucfirst('ana');                        // Ana
str_replace('Ana', 'Luis', $completo); // Luis García
explode(',', 'a,b,c');                 // ['a', 'b', 'c']
implode('-', ['a', 'b', 'c']);         // 'a-b-c'
trim('  hola  ');                      // 'hola'
substr('abcdef', 1, 3);                // 'bcd'
str_contains($completo, 'García');     // true (PHP 8)
str_starts_with($completo, 'Ana');     // true

💡 Usa comillas simples cuando no necesites interpolación: son ligeramente más rápidas y evitan escapar caracteres. Las heredocs (<<<EOT ... EOT) permiten bloques multilínea con interpolación.

Funciones

<?php
declare(strict_types=1);

// Tipos en parámetros y retorno, valor por defecto
function saludar(string $nombre, string $saludo = "Hola"): string
{
    return "$saludo, $nombre";
}

// Variadics: número variable de argumentos
function sumarTodos(int ...$numeros): int
{
    return array_sum($numeros);
}

// Arrow functions (PHP 7.4+): capturan variables por valor automáticamente
$iva = 0.21;
$conIva = fn($precio) => $precio * (1 + $iva);

// First-class callable (PHP 8.1+)
$fn = strlen(...);

echo saludar('Ana');             // Hola, Ana
echo sumarTodos(1, 2, 3, 4);     // 10
echo $conIva(100);               // 121
echo $fn('hola');                // 4

⚠️ Las arrow functions solo contienen una expresión y capturan el ámbito exterior automáticamente; las closures clásicas necesitan use ($variable).

Superglobals y formularios

Las superglobals son arrays siempre disponibles, definidos por el servidor web:

Superglobal Contenido
$_GET Parámetros de la query string (?id=3)
$_POST Cuerpo de un formulario method="post"
$_REQUEST Fusión de GET/POST/cookies (evítalo: ambiguo)
$_SERVER Cabeceras, URL, IP del cliente, agente de usuario
$_SESSION Datos de sesión entre peticiones
$_COOKIE Cookies del cliente
$_FILES Archivos subidos
<form method="post" action="procesar.php">
    <label>Nombre: <input type="text" name="nombre"></label>
    <button type="submit">Enviar</button>
</form>
<?php
// procesar.php
$nombre = $_POST['nombre'] ?? 'Anónimo';
$email  = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL);

if ($email === false) {
    echo "El email no es válido";
} else {
    echo "Registro de $nombre con email $email";
}

echo $_SERVER['REQUEST_METHOD'];   // POST
echo $_SERVER['REMOTE_ADDR'];      // IP del cliente

session_start();
$_SESSION['usuario_id'] = 42;      // persistir entre peticiones
echo $_SESSION['usuario_id'];      // 42
session_destroy();

⚠️ Nunca confíes en la entrada del usuario. Todo lo que llega por $_GET y $_POST debe validarse y escaparse: para HTML usa htmlspecialchars($x, ENT_QUOTES), para SQL usa consultas preparadas (PDO), nunca concatenes datos crudos.

Manejo de errores y excepciones

PHP distingue entre errores (problemas del motor: TypeError, DivisionByZeroError…) y excepciones de la aplicación (RuntimeException, InvalidArgumentException…). Ambos se capturan con try/catch, y PHP 7+ los unificó bajo la interfaz raíz Throwable.

<?php
function dividir(int $a, int $b): float
{
    if ($b === 0) {
        throw new InvalidArgumentException("No se puede dividir por cero");
    }
    return $a / $b;
}

try {
    $resultado = dividir(10, 0);
    echo $resultado;
} catch (InvalidArgumentException $e) {
    echo "Error de validación: " . $e->getMessage();
} catch (Throwable $e) {
    error_log($e->getMessage());   // TypeError, Error, Exception...
    echo "Ocurrió un error inesperado";
} finally {
    echo "Este bloque siempre se ejecuta";
}

💡 Con strict_types=1, una llamada con tipo incorrecto lanza TypeError; dividir entre cero lanza DivisionByZeroError (PHP 8). Capturando Throwable cubres ambos mundos. Las excepciones son encadenables: throw new DomainException("...", 0, $e); conserva el error original.

Cheatsheet

Concepto Sintaxis clave
Imprimir echo, var_dump()
Strings concatenar ., interpolar "$var"
Estricto declare(strict_types=1), ===, !==
Valores opcionales $x ?? $default
Comparar <=> spaceship
Iterar foreach ($arr as $k => $v)
Transformar array_map, array_filter, array_reduce
Parámetros variables ...$args, spread ...
Funciones cortas fn($x) => expr, strlen(...)
Entrada del usuario $_GET, $_POST, $_SERVER
Fallos throw new ...Exception, try/catch/finally

Para profundizar

Estudio · Recursos de todo el mundo (inglés, chino, japonés, español, francés, ruso…) curados y traducidos al español.