Un miembro static es una propiedad o método que pertenece a la clase y no a una instancia concreta.
Hasta ahora, hemos dicho que la Clase es el plano y el Objeto es la casa. Si Juan pinta su casa de azul, la casa de María no cambia de color. Son independientes.
Pero, ¿y si queremos definir una norma que aplique a todas las casas de la urbanización? Por ejemplo: “La hora de recogida de basura es a las 20:00”. Eso no depende de una casa concreta, es una regla global de la comunidad (la Clase).
En PHP, esto se llama Miembros Estáticos.
Propiedades y métodos estáticos (static)
Un miembro estático pertenece a la Clase, no al Objeto.
- No necesitas hacer
newpara usarlo. - Se comparte entre todas las instancias. Si uno lo cambia, cambia para todos.
El operador de resolución de ámbito (::)
Para acceder a lo estático, no usamos la flecha ->. Usamos los dos puntos dobles :: (conocido curiosamente en hebreo como Paamayim Nekudotayim).
class Calculadora {
// Propiedad Estática: Pertenece a la clase Calculadora
public static float $pi = 3.14159;
// Método Estático: No necesita un objeto para funcionar
public static function sumar(int $a, int $b): int {
return $a + $b;
}
}
// USO DIRECTO (Sin new)
echo Calculadora::$pi; // 3.14159
echo Calculadora::sumar(5, 10); // 15Esto es muy útil para Clases de Utilidad (Helpers) donde no tiene sentido crear un objeto porque no guardamos estado, solo queremos ejecutar una función.
self:: vs $this
Aquí está la trampa donde caen todos.
- Dentro de un método normal, usas
$thispara referirte al objeto actual. - Dentro de un método estático, no existe
$this(porque no hay objeto).
Para referirte a la propia clase desde dentro, usamos self::.
class Contador {
public static int $cuenta = 0;
public function __construct() {
// Cada vez que creamos un objeto, aumentamos el contador global
self::$cuenta++;
}
public static function verTotal(): int {
return self::$cuenta;
}
}
new Contador();
new Contador();
new Contador();
echo Contador::verTotal(); // Salida: 3- Si es variable de instancia (
$var) ->$this->var - Si es estática (
static $var) ->self::$var
Constantes de clase (const)
A diferencia de las propiedades estáticas (que pueden cambiar: self::$cuenta++), las constantes son inmutables. Son valores fijos universales para esa clase.
Por defecto son siempre públicas y estáticas.
class Banco {
public const IMPUESTO = 0.21;
private const CLAVE_SECRETA = '1234'; // Desde PHP 7.1 pueden tener visibilidad
public function calcularTotal(float $monto): float {
// Accedemos igual que a un estático
return $monto * (1 + self::IMPUESTO);
}
}
echo Banco::IMPUESTO; // 0.21Profundidad técnica: self:: vs static:: (late static binding)
Este mecanismo se llama late static binding y existe desde PHP 5.3. Imagina que tienes herencia:
class A {
public static function quienSoy() {
echo __CLASS__;
}
public static function test() {
self::quienSoy(); // self se "ata" a la clase donde está escrito (A)
}
}
class B extends A {
public static function quienSoy() {
echo __CLASS__; // Debería decir B
}
}
B::test(); // Salida: "A" (¡Sorpresa!)¿Por qué imprime A? Porque self:: hace referencia a la clase donde se escribió el código (A), no a la que lo llama (B).
Para solucionar esto y permitir polimorfismo en estáticos, usamos static::.
// En la clase A, cambiamos self por static
public static function test() {
static::quienSoy(); // static busca la clase que llamó en tiempo de ejecución
}
B::test(); // Salida: "B" (¡Correcto!)Usa static:: cuando quieras que una clase heredada pueda especializar el comportamiento. Usa self:: cuando la referencia deba quedar ligada a la clase donde se escribe.
La advertencia: no abuses de lo estático
Los métodos estáticos son cómodos, pero una propiedad estática mutable introduce estado compartido. Un método estático puro, en cambio, no tiene por qué mantener estado global.
Hacen que el código sea difícil de testear (Unit Testing) porque crean dependencias ocultas fuertes (Acoplamiento).
- Bien: Funciones puras (Matemáticas, conversores de String).
- Mal:
BaseDeDatos::conectar(). Si haces eso estático, no podrás cambiar la base de datos fácilmente en tus tests.