¿Cuándo usar self y cuándo $this? Acláralo de una vez por todas
\n\nSi alguna vez has programado en PHP con orientación a objetos, seguro te has topado con la pregunta: «¿Qué debería usar, self o $this?». Esta duda es tan común que en Stack Overflow acumula decenas de miles de visitas y cientos de comentarios. Y no es casualidad: la diferencia entre ambos es uno de esos «detalles» que puede convertir tu código en algo funcional pero confuso, o en algo elegante y claro.
Vamos a dejarlo claro desde el principio: no son intercambiables. Tienen filosofías distintas y, lo que es más importante, un comportamiento diferente con la herencia. Si usas $this donde debería ir self, o viceversa, corres el riesgo de introducir errores lógicos difíciles de depurar.
En este artículo lo desglosaremos todo: desde lo básico hasta escenarios avanzados. ¡Allá vamos!
\n\n\n\n
Respuesta rápida (para quien tiene prisa)
\n\nSi solo quieres recordar una regla, que sea esta:
\n\n- \n
$this->— para acceder a propiedades y métodos de instancia (del objeto). Solo funciona dentro de un contexto no estático. \n self::— para acceder a propiedades y métodos estáticos de la clase. Funciona tanto en contexto estático como no estático. \n static::— «enlace estático tardío» (Late Static Binding). Se usa cuando necesitas que una clase hija sobrescriba el comportamiento de la clase padre. \n
Pero, como siempre, el diablo está en los detalles. Vamos a profundizar.
\n\n¿Qué es $this?
\n\n$this es una pseudovariable que hace referencia al objeto actual. Solo está disponible dentro de métodos de clase (no estáticos) y apunta a la instancia con la que estás trabajando.
<?php\n\nclass Usuario {\n public string $nombre;\n\n public function setNombre(string $nombre): void {\n $this->nombre = $nombre; // accedemos a la propiedad del objeto actual\n }\n\n public function getNombre(): string {\n return $this->nombre;\n }\n}\n\n$usuario = new Usuario();\n$usuario->setNombre('Ana');\necho $usuario->getNombre(); // Ana\n\nSencillo: $this->nombre significa «toma la propiedad nombre del objeto que llamó a este método».
¿Qué es self?
\n\nself es una referencia a la clase actual, no al objeto. Se usa para acceder a miembros estáticos de la clase (propiedades y métodos declarados con la palabra clave static).
<?php\n\nclass Configuracion {\n public static string $nombreApp = 'PythonLib';\n\n public static function getNombreApp(): string {\n return self::$nombreApp; // accedemos a la propiedad estática de la clase\n }\n}\n\necho Configuracion::getNombreApp(); // PythonLib\n\nNota importante: self siempre apunta a la clase donde está escrito. Incluso si creas una clase hija, self en la clase padre seguirá refiriéndose al padre. Esta es la diferencia clave con static.
La diferencia principal: self vs $this en herencia
\n\nAquí es donde se pone interesante. Imagina que tienes una clase base Animal y una clase hija Perro.
<?php\n\nclass Animal {\n public static function quienSoy(): string {\n return 'Soy un animal';\n }\n\n public function decir(): string {\n // Usamos self — está vinculado a la clase Animal\n return self::quienSoy();\n }\n}\n\nclass Perro extends Animal {\n public static function quienSoy(): string {\n return 'Soy un perro';\n }\n}\n\n$perro = new Perro();\necho $perro->decir(); // Soy un animal\n\n¿Ves? Aunque Perro sobrescribe quienSoy(), el método decir() sigue llamando a la versión de Animal porque usamos self. Si hubiéramos usado static::, el resultado sería «Soy un perro». Eso es el enlace estático tardío.
En cambio, $this siempre se refiere al objeto real, sin importar desde qué clase se llame el método. Si decir() usara $this->quienSoy() (y quienSoy no fuera estático), llamaría a la versión sobrescrita en Perro.
Errores comunes y cómo evitarlos
\n\nUno de los errores más frecuentes es usar $this para acceder a propiedades estáticas. Esto no funciona y lanza un error. Recuerda: $this-> es para instancias, self:: es para estáticos.
Otro error es pensar que self y static son lo mismo. No lo son: self se resuelve en tiempo de compilación (clase donde se escribe), mientras que static se resuelve en tiempo de ejecución (clase que realmente se está usando).
Resumen final
\n\n| Contexto | Usa | Ejemplo |
|---|---|---|
| Propiedades/métodos de instancia | $this-> | $this->nombre |
| Propiedades/métodos estáticos | self:: | self::$nombreApp |
| Herencia con sobrescritura estática | static:: | static::quienSoy() |
Con esto ya tienes las herramientas para elegir correctamente. La práctica hará que se vuelva automático. ¡A programar!