Leccion 35 de 75 10 min de lectura

Propiedades y Metodos Estaticos

Los miembros estaticos pertenecen a la clase, no a las instancias. Se acceden sin crear objetos y son compartidos por todas las instancias.

¿Que es static?

Las propiedades y metodos static existen a nivel de clase, no de objeto. Se acceden con :: en lugar de ->:

PHP
<?php
declare(strict_types=1);

class Contador
{
    private static int $cuenta = 0;

    public static function incrementar(): void
    {
        self::$cuenta++;
    }

    public static function getCuenta(): int
    {
        return self::$cuenta;
    }
}

// Sin crear objetos
Contador::incrementar();
Contador::incrementar();
Contador::incrementar();

echo Contador::getCuenta(); // 3

Propiedades estaticas compartidas

Las propiedades estaticas se comparten entre todas las instancias:

PHP
<?php
declare(strict_types=1);

class Usuario
{
    private static int $totalUsuarios = 0;

    private string $nombre;

    public function __construct(string $nombre)
    {
        $this->nombre = $nombre;
        self::$totalUsuarios++;
    }

    public function getNombre(): string
    {
        return $this->nombre;
    }

    public static function getTotalUsuarios(): int
    {
        return self::$totalUsuarios;
    }
}

$u1 = new Usuario('Ana');
$u2 = new Usuario('Luis');
$u3 = new Usuario('Eva');

echo Usuario::getTotalUsuarios(); // 3
echo $u1->getNombre();            // Ana
self:: vs $this

Usa self:: para acceder a miembros estaticos y $this-> para miembros de instancia. Los metodos estaticos no pueden usar $this.

Métodos estáticos utilitarios

Los metodos estaticos son utiles para funciones que no dependen del estado de un objeto:

PHP
<?php
declare(strict_types=1);

class Validador
{
    public static function esEmail(string $email): bool
    {
        return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
    }

    public static function esNumero(string $valor): bool
    {
        return is_numeric($valor);
    }

    public static function longitud(string $texto, int $min, int $max): bool
    {
        $len = strlen($texto);
        return $len >= $min && $len <= $max;
    }
}

// Uso directo sin instanciar
var_dump(Validador::esEmail('ana@email.com'));    // true
var_dump(Validador::esNumero('123'));             // true
var_dump(Validador::longitud('Hola', 1, 10));     // true

Factory methods

Un uso comun de metodos estaticos es crear instancias de formas especiales:

PHP
<?php
declare(strict_types=1);

class Fecha
{
    private int $dia;
    private int $mes;
    private int $anio;

    private function __construct(int $dia, int $mes, int $anio)
    {
        $this->dia = $dia;
        $this->mes = $mes;
        $this->anio = $anio;
    }

    public static function hoy(): self
    {
        return new self(
            (int) date('d'),
            (int) date('m'),
            (int) date('Y')
        );
    }

    public static function desde(string $fecha): self
    {
        $partes = explode('-', $fecha);
        return new self(
            (int) $partes[2],
            (int) $partes[1],
            (int) $partes[0]
        );
    }

    public function formato(): string
    {
        return sprintf('%02d/%02d/%04d', $this->dia, $this->mes, $this->anio);
    }
}

$hoy = Fecha::hoy();
$cumple = Fecha::desde('1990-05-15');

echo $hoy->formato();    // 15/01/2024
echo $cumple->formato(); // 15/05/1990

Ejemplo practico: Configuracion global

PHP
<?php
declare(strict_types=1);

class Config
{
    private static array $valores = [];

    public static function set(string $clave, mixed $valor): void
    {
        self::$valores[$clave] = $valor;
    }

    public static function get(string $clave, mixed $default = null): mixed
    {
        return self::$valores[$clave] ?? $default;
    }

    public static function tiene(string $clave): bool
    {
        return isset(self::$valores[$clave]);
    }
}

// Configurar la aplicacion
Config::set('app.nombre', 'Mi App');
Config::set('app.version', '1.0.0');
Config::set('db.host', 'localhost');

// Usar en cualquier parte
echo Config::get('app.nombre');           // Mi App
echo Config::get('app.debug', false);     // false (default)
var_dump(Config::tiene('db.host'));       // true
No abuses de static

El estado global puede dificultar el testing y crear dependencias ocultas. Usa static para utilidades sin estado o cuando realmente necesites compartir datos entre instancias.

Ejercicios

Ejercicio 1: Generador de IDs

Crea una clase IdGenerator con un metodo estatico siguiente(): int que retorne IDs incrementales. El primer ID debe ser 1.

Ver solucion
PHP
<?php
declare(strict_types=1);

class IdGenerator
{
    private static int $ultimoId = 0;

    public static function siguiente(): int
    {
        return ++self::$ultimoId;
    }

    public static function getActual(): int
    {
        return self::$ultimoId;
    }

    public static function reset(): void
    {
        self::$ultimoId = 0;
    }
}

echo IdGenerator::siguiente(); // 1
echo IdGenerator::siguiente(); // 2
echo IdGenerator::siguiente(); // 3
echo IdGenerator::getActual(); // 3

IdGenerator::reset();
echo IdGenerator::siguiente(); // 1

Ejercicio 2: Conversor de unidades

Crea una clase Conversor con metodos estaticos kmAMillas(float $km): float, celsiusAFahrenheit(float $c): float y kgALibras(float $kg): float.

Ver solucion
PHP
<?php
declare(strict_types=1);

class Conversor
{
    public static function kmAMillas(float $km): float
    {
        return $km * 0.621371;
    }

    public static function millasAKm(float $millas): float
    {
        return $millas / 0.621371;
    }

    public static function celsiusAFahrenheit(float $c): float
    {
        return ($c * 9 / 5) + 32;
    }

    public static function fahrenheitACelsius(float $f): float
    {
        return ($f - 32) * 5 / 9;
    }

    public static function kgALibras(float $kg): float
    {
        return $kg * 2.20462;
    }

    public static function librasAKg(float $libras): float
    {
        return $libras / 2.20462;
    }
}

echo Conversor::kmAMillas(100);          // 62.1371
echo Conversor::celsiusAFahrenheit(25);  // 77
echo Conversor::kgALibras(70);           // 154.323

Ejercicio 3: Cache simple

Crea una clase Cache con metodos estaticos set(string $key, mixed $value), get(string $key): mixed y clear(): void que borre todo el cache.

Ver solucion
PHP
<?php
declare(strict_types=1);

class Cache
{
    private static array $datos = [];

    public static function set(string $key, mixed $value): void
    {
        self::$datos[$key] = $value;
    }

    public static function get(string $key, mixed $default = null): mixed
    {
        return self::$datos[$key] ?? $default;
    }

    public static function has(string $key): bool
    {
        return isset(self::$datos[$key]);
    }

    public static function delete(string $key): void
    {
        unset(self::$datos[$key]);
    }

    public static function clear(): void
    {
        self::$datos = [];
    }

    public static function count(): int
    {
        return count(self::$datos);
    }
}

Cache::set('usuario', ['id' => 1, 'nombre' => 'Ana']);
Cache::set('config', ['tema' => 'oscuro']);

echo Cache::count(); // 2
print_r(Cache::get('usuario')); // ['id' => 1, 'nombre' => 'Ana']

Cache::clear();
echo Cache::count(); // 0

¿Te está gustando el curso?

Tenemos cursos premium con proyectos reales y soporte personalizado.

Descubrir cursos premium