Constantes

Vídeo


En esta ocasión le toca el turno a las constantes. Vamos a ver qué son, por qué y cómo usarlas.

Vamos a recuperar el código del artículo anterior:

class Noticia
{
    private $titulo;

    public function mostrar()
    {
        echo $this->titulo . "\n";
    }

    public function cambiarTitulo($titulo)
    {
        if (strlen($titulo) < 30) { echo "Error: título es demasiado corto.\n"; return false; } $this->titulo = $titulo;
    }
}

$noticia = new Noticia();
$noticia->cambiarTitulo("Noticia cambiada");
$noticia->mostrar();

Recordemos que en la función cambiarTitulo comprobábamos la longitud del título. Si era menor de 30 mostrábamos un error.

Cuando alguien vea este código por primera vez este 30 no le va a decir nada. Es solo un número. Tendrá que hacer un pequeño esfuerzo mental para saber qué es lo que se está haciendo Es cierto que entenderlo no va a ser una tarea titánica que va a freír su cereblo, pero ya es un trabajo extra que tendrá que hacer.

¿No sería mejor poder indicar de alguna manera qué significa ese valor? Podríamos comentar el código, pero habría que hacerlo en todos aquellos lugares donde aparezca el número 30. Además, si en algún momento decidimos que en lugar de 30 deben ser 40 tendríamos que cambiarlo seguramente en varios sitios.

¿Qué tal si usamos una propiedad para controlar eso? No parece una mala idea. Vamos a usar una propiedad a la que llamaremos $longitudMinima:

class Noticia
{

    private $titulo;
    public $longitudMinima = 30;

    public function mostrar()
    {
        echo $this->titulo . "\n";
    }

    public function cambiarTitulo($titulo)
    {
        if (strlen($titulo) < $this->longitudMinima) {
            echo "Error: título es demasiado corto.\n";
            return false;
        }
        $this->titulo = $titulo;
    }
}

$noticia = new Noticia();
$noticia->cambiarTitulo("Noticia cambiada");
$noticia->mostrar();

Vamos a la consola y ejecutamos el código:

Error: título es demasiado corto.

Perfecto.

Pero ahora llega el listo de turno y hace:

$noticia = new Noticia();
$noticia->longitudMinima = 0;
$noticia->cambiarTitulo("Noticia cambiada");
$noticia->mostrar();

Si lo ejecutamos:

Noticia cambiada

Vemos que no se hace la comprobación de los 30 caracteres de manera correcta. No se hace porque hemos cambiado la propiedad.

Ya bueno, pero para evitarlo basta con cambiar la propiedad y hacerla private:

private $longitudMinima = 30;

Ahora ya no podrán acceder a ella.

El problema es que todavía se puede seguir modificando desde dentro de la clase. ¿Y por qué haríamos tal cosa? Algunas clases son demasiado grandes, con el tiempo se nos olvidaba que era mejor no cambiarla, porque nos odiamos a nosotros mismos... hay muchos motivos.

Así que, cuando tenemos un valor que no debería cambiar nunca, lo mejor es usar una constante. Una constante no puede cambiar su valor de ninguna manera.

¿Cómo se definen?

Las constantes se definen con este formato:

const NOMBRE = 1;

Los nombres de las constantes se suelen poner en mayúsculas, aunque no es necesario. Ah, y las constantes no llevan el símbolo del $ como las propiedades.

¿Cómo se usan?

Para acceder a ellas desde dentro de la clase se usa el nombre de la constante anteponiendo “self::”.

self::LONGITUD_MINIMA

Con lo que nuestra clase quedaría:

class Noticia
{

    private $titulo;
    const LONGITUD_MINIMA = 30;

    public function mostrar()
    {
        echo $this->titulo . "\n";
    }

    public function cambiarTitulo($titulo)
    {
        if (strlen($titulo) < self::LONGITUD_MINIMA) { echo "Error: título es demasiado corto.\n"; return false; } $this->titulo = $titulo;
    }
}

$noticia = new Noticia();
$noticia->cambiarTitulo("Noticia cambiada");
$noticia->mostrar();

Podemos comprobar en la consola que el programa funciona correctamente:

Error: título es demasiado corto.

Recuerda que no es una propiedad, así que no podemos usar $this:

if (strlen($titulo) < $this->LONGITUD_MINIMA) {

ya que tendríamos un error:

PHP Notice:  Undefined property: Noticia::$LONGITUD_MINIMA

Esto sucede porque PHP buscaría una propiedad con el nombre LONGITUD_MINIMA.

A las constantes también podemos acceder desde el “exterior” a través del objeto:

echo "Longitud mínima: " . $noticia::LONGITUD_MINIMA . "\n";

Aquí tampoco podemos usar -> para acceder al valor de la constante:

echo "Longitud mínima: " . $noticia->LONGITUD_MINIMA . "\n";

Si lo ejecutamos tendríamos el mismo error de antes.

Es importante destacar que para acceder a una constante no necesitamos definir un objeto, podemos acceder directamente a su valor a través de la clase:

echo "Longitud mínima: " . Noticia::LONGITUD_MINIMA . "\n";

Una constante es... constante. Así que su valor no puede cambiar. No se puede hacer algo así:

$noticia::LONGITUD_MINIMA = 56;

Porque PHP nos lanzará un error por la aberración que estamos intentando perpetrar.

Y claro, una constante siempre debe tener un valor. Eso nos lanzaría un error:

const LONGITUD_MINIMA;

Porque ¿para qué queremos una constante sin valor? No vamos a poder darle un valor más tarde por lo que sería absurdo.

Constantes calculadas

Desde la versión 5.6 de PHP se pueden usar expresiones en las constantes. Por ejemplo antes teníamos que hacer:

const SEGUNDOS_DIA = 86400;

y ahora podemos usar esta otra forma:

const SEGUNDOS_DIA = 60 * 60 * 24;

Que da más pistas de dónde viene el valor. O incluso:

    const HORAS = 24;
    const MINUTOS = 60;
    const SEGUNDOS = 60;
    const SEGUNDOS_DIA = self::HORAS * self::MINUTOS * self::SEGUNDOS;

Este ejemplo es bastante tonto y complica las cosas innecesariamente, pero creo que sirve para entender lo que podemos hacer.

Lo que no podemos es usar una propiedad o el valor que devuelve una función para calcular el valor de una constante. Una constante es... constante; y por tanto no puede depender de algo cuyo valor puede cambiar.

Arrays constantes

Desde la versión 5.6 de PHP también se pueden usar Arrays como valor de una constante:

const MI_ARRAY = [ 1, 2, 3 ];

Pero recuerda, este array no se puede modificar.

Volveremos a hablar de las constantes en otros artículos porque aún quedan un par de detalles que comentar.

Autor:
Nivel: Intermedio
Palabras clave:
Fecha publicado:
Fecha actualizado: 10-08-2016

Otros capítulos de la misma serie

Este capítulo es parte de la serie: Curso de Programación orientada a objetos en PHP.

Y muchos más en preparación.

Disponible en los planes: PHP a tope Laravel hero