Situación actual: PHP2Shell. Dos vulnerabilidades críticas de PHP (CVSS 9.2) permiten ejecutar código malicioso sin autenticación. Parches desde el 21/10/2026.Qué hacer ahora →

Programación orientada a objetos en PHP

Las aplicaciones PHP modernas son casi siempre orientadas a objetos. Esta página explica sus componentes, las novedades de PHP 8.0 a 8.4 y por qué los métodos mágicos importan para la seguridad.

Actualizado 5 min de lecturaConocimiento de PHP

En resumen: la programación orientada a objetos (POO) agrupa los datos y las funciones correspondientes en clases. Para ello PHP ofrece clases, clases abstractas, interfaces, traits y, desde PHP 8.1, enums. Con PHP 8.0 a 8.4 se añadieron muchos recursos del lenguaje, como la promoción de propiedades en el constructor, readonly, los property hooks y la visibilidad asimétrica. Importante para la seguridad: un código bien encapsulado es más fácil de revisar, y los métodos mágicos hacen peligrosa la deserialización insegura. Frente a vulnerabilidades del intérprete como PHP2Shell, la POO no ayuda.

Qué significa la programación orientada a objetos en PHP

En lugar de usar funciones sueltas y variables globales, una clase describe una cosa del mundo del negocio: un pedido, un cliente, una factura. Establece qué datos le pertenecen (propiedades) y qué se puede hacer con ellos (métodos). Un objeto es un ejemplar concreto de esa clase.

Para quienes toman decisiones tiene un valor práctico: el código orientado a objetos con clases claras se prueba, se revisa y se entrega a un proveedor con más facilidad. En cambio, las aplicaciones PHP antiguas, hechas de muchos scripts sueltos con variables globales, son difíciles de mantener y propensas a fallos en las actualizaciones.

Una idea central es la encapsulación: una clase expone hacia fuera solo los métodos que otros realmente necesitan y protege su estado interno. Un pedido, por ejemplo, solo puede marcarse como pagado mediante un método que antes comprueba si eso es siquiera admisible. Reunir esas reglas en un solo lugar es también una ventaja para la seguridad.

Los componentes de un vistazo

Componente Finalidad Ejemplo breve
Clase plano de objetos con propiedades y métodos class Rechnung { ... }
Clase abstracta base común, no se puede instanciar directamente abstract class Zahlart { ... }
Interfaz contrato: qué métodos debe ofrecer una clase interface Versandfaehig { ... }
Trait métodos reutilizables para clases sin clase padre común trait MitZeitstempel { ... }
Enum conjunto fijo de valores permitidos como tipo propio, desde PHP 8.1 enum Status { case Offen; ... }

Las visibilidades (public, protected, private) regulan quién puede acceder a propiedades y métodos. Las clases se organizan en namespaces y se cargan mediante un autoloader; cómo funciona lo muestra la página Namespaces y autoloading.

PHP moderno: las novedades de 8.0 a 8.4

Los siguientes recursos del lenguaje están documentados en el manual de PHP o en los anuncios de las versiones:

Versión Novedad
8.0 promoción de propiedades en el constructor, operador nullsafe ?->, ::class en objetos
8.1 propiedades readonly, enums, new en inicializadores, final para constantes de clase
8.2 clases readonly; las propiedades dinámicas pasan a considerarse obsoletas
8.3 atributo #[\Override], constantes de clase tipadas
8.4 property hooks, visibilidad asimétrica, new sin paréntesis envolventes

Un ejemplo que combina varios de estos recursos:

<?php
declare(strict_types=1);

enum Status: string
{
    case Offen = 'offen';
    case Bezahlt = 'bezahlt';
}

final class Bestellung
{
    public function __construct(
        public readonly int $id,
        public private(set) Status $status = Status::Offen,  // desde PHP 8.4
    ) {}

    public function alsBezahltMarkieren(): void
    {
        $this->status = Status::Bezahlt;
    }
}

$b = new Bestellung(42);
$b->alsBezahltMarkieren();
echo $b->status->value;              // bezahlt
$s = Status::tryFrom('storniert');   // null en lugar de un error

readonly impide que el ID se modifique tras crearlo. private(set) permite la lectura desde fuera, pero la escritura solo dentro de la clase. Estas garantías en el código hacen menos probables los fallos que de otro modo solo se notan en producción. Los tipos que hay detrás se explican en la página El sistema de tipos de PHP.

Trampas de la actualización en el código orientado a objetos

En las aplicaciones antiguas son especialmente relevantes dos cambios. Desde PHP 8.2.0 está obsoleta la creación de propiedades dinámicas, es decir, de propiedades que no están declaradas en la clase, salvo que la clase lleve el atributo #[\AllowDynamicProperties]. El código antiguo lo hace a menudo sin darse cuenta y llena entonces los logs de avisos. Además, según el manual, las propiedades tipadas deben estar inicializadas antes de la primera lectura; de lo contrario, PHP lanza un Error.

Resulta útil el atributo #[\Override] de PHP 8.3: marca un método como sobrescritura de un método de la clase padre. Si ese método ya no existe, por ejemplo tras un cambio de nombre en una biblioteca, PHP notifica un error en lugar de dejar que el método quede en silencio sin efecto. Estas comprobaciones hacen más predecibles las actualizaciones; en proyectos antiguos atascados le ayuda nuestra migración a una versión de PHP con soporte.

Objetos y memoria

En PHP, los objetos se pasan mediante identificadores (handles). Si se pasa un objeto a una función, esta trabaja con el mismo objeto, no con una copia. Es eficiente, pero lleva con facilidad a referencias circulares, por ejemplo cuando un pedido conoce sus líneas y cada línea vuelve a conocer su pedido. El conteo de referencias por sí solo no limpia estos ciclos; para eso PHP tiene su propio recolector de basura (garbage collector). Los detalles figuran en la página Gestión de memoria en PHP.

POO y seguridad: métodos mágicos y deserialización

PHP conoce métodos mágicos que se llaman automáticamente, como __construct, __destruct, __toString, __get o __wakeup. Es práctico, pero tiene un reverso: si una aplicación convierte de nuevo en objetos, con unserialize(), datos ajenos, un atacante puede decidir qué clases se crean y, con ello, activar código existente en métodos mágicos. Cómo evitarlo lo describe la guía Deserialización insegura en PHP. En breve: para el intercambio de datos, use json_encode() y json_decode(), y emplee unserialize() solo para datos propios y de confianza, idealmente con la opción allowed_classes.

En el caso de PHP2Shell, en cambio, el buen código orientado a objetos no ayuda. CVE-2026-109618 y CVE-2026-109619 están en el intérprete y, según el equipo de PHP, con mod_php se demostró un exploit antes de que se ejecute el código de la aplicación. Es obligatoria la actualización a PHP 8.5.12, 8.4.27, 8.3.36 o 8.2.35 y el reinicio de todos los procesos de PHP.

¿Cómo ayuda PHP SOS en concreto?

  • Valoramos la estructura de su aplicación y mostramos qué partes dificultan una actualización a una versión de PHP con soporte.
  • Buscamos de forma específica patrones de riesgo, como unserialize() sobre datos ajenos y métodos mágicos peligrosos.
  • Revisamos los desarrollos propios en el marco de una auditoría de seguridad y prueba de penetración.
  • Aplicamos la actualización de PHP, reiniciamos todos los workers y probamos después la aplicación.

Preguntas frecuentes

¿PHP es un lenguaje orientado a objetos?

PHP admite tanto código procedural como orientado a objetos. Hoy, sin embargo, los frameworks, los núcleos de los CMS y los sistemas de tienda se construyen en su mayoría con orientación a objetos, con clases, interfaces y namespaces.

¿Qué diferencia hay entre una interfaz y una clase abstracta?

Una interfaz solo describe qué métodos debe ofrecer una clase. Una clase abstracta puede contener además código y propiedades, pero no se puede instanciar directamente. Una clase puede tener varias interfaces, pero solo una clase padre.

¿Desde cuándo hay enums en PHP?

Las enumeraciones llegaron con PHP 8.1. Sustituyen los conjuntos de constantes por un tipo propio que solo admite los casos definidos. Los backed enums tienen además un valor int o string.

¿Por qué son relevantes para la seguridad los métodos mágicos?

Métodos como __destruct o __wakeup los llama PHP automáticamente, por ejemplo al deserializar datos. Si datos ajenos llegan sin comprobar a unserialize(), pueden desencadenar procesos inesperados en clases existentes.

Fuentes

Contacto inmediato

Cada hora cuenta. Escríbanos ahora.

Describa brevemente el sistema, la versión de PHP y lo que ha observado. Nos pondremos en contacto, aclararemos la situación y trabajaremos en remoto hasta que el incidente quede cerrado y documentado.

Ayuda inmediata