Getters y Setters
Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy — lección 40 de 91.
Ahora que entiendes los modificadores de acceso, ¿cómo interactúas de forma segura con las propiedades privadas desde fuera de la clase? La respuesta son los getters y setters: métodos públicos que proporcionan un acceso controlado a los datos privados.
Un getter obtiene el valor de una propiedad, mientras que un setter lo modifica. Este patrón le permite añadir validación o lógica cuando se accede a los datos o se cambian:
<?php
class User {
private string $email;
private int $age;
public function getEmail(): string {
return $this->email;
}
public function setEmail(string $email): void {
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->email = $email;
}
}
public function getAge(): int {
return $this->age;
}
public function setAge(int $age): void {
if ($age >= 0 && $age <= 150) {
$this->age = $age;
}
}
}
$user = new User();
$user->setEmail("john@example.com");
$user->setAge(25);
echo $user->getEmail() . "\n";
echo $user->getAge();
Salida:
john@example.com
25El setter valida el formato del correo electrónico y asegura que la edad sea razonable antes de almacenar los valores. Sin setters, cualquiera podría asignar datos inválidos directamente. También puedes crear propiedades de solo lectura proporcionando solo un getter, o propiedades de solo escritura con solo un setter.
Punto clave: Los getters y setters te dan control sobre cómo se accede y se modifican los datos privados, permitiendo la validación, el formateo o cualquier lógica personalizada.
Desafío
FácilVamos a construir un sistema de inventario de productos que utiliza getters y setters para proteger y validar los datos del producto. Crearás una clase Product que asegure que los precios sean siempre positivos y las cantidades de stock nunca sean negativas — demostrando cómo los setters pueden imponer reglas de negocio.
Organizarás tu código en dos archivos:
Product.php— Crea una claseProductcon tres propiedades privadas:$name(string),$price(float), y$stock(integer). Implementa getters y setters para cada propiedad con las siguientes reglas de validación:setName()solo debe aceptar cadenas no vacías — si la cadena está vacía después de recortar los espacios (trimming), no actualices la propiedadsetPrice()solo debe aceptar valores mayores que 0 — rechaza precios de cero o negativossetStock()solo debe aceptar valores de 0 o mayores — rechaza cantidades de stock negativas
getInfo()que devuelva"[name]: $[price] ([stock] in stock)"con el precio formateado a 2 decimales.main.php— Incluye el archivo Product. Recibirás cuatro entradas: un nombre de producto, un precio, una cantidad de stock y un nuevo precio para actualizar. Crea una instancia deProducty usa los setters para asignar el nombre inicial, el precio (convertido a float) y el stock (convertido a integer). Imprime el resultado degetInfo(). Luego intenta actualizar el precio con el nuevo valor de precio (convertido a float) e imprimegetInfo()de nuevo. Finalmente, intenta establecer el stock a-5(un valor inválido) e imprimegetInfo()una vez más para confirmar que el stock no fue cambiado.
Tus setters actúan como guardianes — validan los datos entrantes antes de permitir cambios en las propiedades privadas. Cuando se pasan datos inválidos (como un stock negativo), el setter simplemente los ignora, manteniendo intacto el valor válido existente. Este es el poder de la encapsulación: tu objeto mantiene su integridad independientemente de lo que el código externo intente hacer.
Hoja de referencia
Usa getters y setters para proporcionar un acceso controlado a las propiedades privadas. Un getter recupera un valor, mientras que un setter lo modifica con una validación opcional:
<?php
class User {
private string $email;
private int $age;
public function getEmail(): string {
return $this->email;
}
public function setEmail(string $email): void {
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->email = $email;
}
}
public function getAge(): int {
return $this->age;
}
public function setAge(int $age): void {
if ($age >= 0 && $age <= 150) {
$this->age = $age;
}
}
}
$user = new User();
$user->setEmail("john@example.com");
$user->setAge(25);
echo $user->getEmail(); // john@example.com
echo $user->getAge(); // 25
Los setters pueden validar los datos antes de almacenarlos. Si la validación falla, el setter puede ignorar la actualización, manteniendo intacto el valor existente. Puedes crear propiedades de solo lectura proporcionando únicamente un getter, o propiedades de solo escritura con solo un setter.
Pruébalo tú mismo
<?php
require_once 'Product.php';
// Leer entradas
$name = trim(fgets(STDIN));
$price = trim(fgets(STDIN));
$stock = trim(fgets(STDIN));
$newPrice = trim(fgets(STDIN));
// TODO: Crear una nueva instancia de Product
// TODO: Usar setters para asignar el nombre inicial, el precio (como float) y el stock (como entero)
// TODO: Imprimir el resultado de getInfo()
// TODO: Actualizar el precio con newPrice (como float) e imprimir getInfo() de nuevo
// TODO: Intentar establecer el stock a -5 (inválido) e imprimir getInfo() para confirmar que el stock no cambió
?>Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a OOPClases vs ObjetosLa palabra clave $thisMétodosPropiedadesConstructor (__construct)Destructor (__destruct)Resumen - Calculadora simple4Herencia
Herencia básicaLa palabra clave parent::Sobrescritura de métodosLa palabra clave finalClases abstractasResumen - Jerarquía de empleados7Encapsulamiento
Público, Protegido, PrivadoModificadores de acceso a fondoGetters y SettersOcultamiento de informaciónPromoción de constructor (8.0)Resumen - Sistema de registros de estudiantes10Conceptos avanzados de POO
Composición vs. HerenciaInyección de dependenciasClases anónimasEnums (PHP 8.1)Fibers (PHP 8.1)Clonación de objetos a fondoGeneradores e Iteradores13Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository2Espacios de nombres y Autoloading
Introducción a los espacios de nombresLa palabra clave useEstándar de Autoloading PSR-4Autoloader de ComposerResumen - Proyecto organizado5Interfaces y Contratos
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesInterfaz vs Clase AbstractaType Hinting con InterfacesResumen - Calculadora de Formas8Métodos mágicos
Introducción a los métodos mágicos__toString y __debugInfo__get, __set, __isset, __unset__call y __callStatic__clone y clonación de objetos__serialize y __unserializeResumen - Colección personalizada3Propiedades de clase
Propiedades de instancia vs. estáticasConstantes en clasesMétodos y propiedades estáticosPropiedades privadas y protegidasPropiedades de solo lectura (PHP 8.1)Resumen - Gestor de cuenta bancaria6Polimorfismo
Sobrescritura de métodos revisadaPolimorfismo mediante interfacesType Hinting y tipos de uniónEnlace estático tardíoResumen - Procesador de pagos9Traits
Introducción a los TraitsUso de múltiples TraitsResolución de conflictos de TraitsMétodos abstractos en TraitsTraits frente a herencia12Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy