Sugerencias de tipo escalar en PHP 7

Por clasificación, PHP es un lenguaje de tipo dinámico y de tipo débil. Estos son dos conceptos diferentes que a menudo se mezclan. Los lenguajes escritos dinámicamente no requieren la declaración explícita de una variable antes de usarla. Los lenguajes débilmente escritos son aquellos en los que la variable no es de ningún tipo de datos específico, es decir, su tipo puede cambiar a través de diferentes reasignaciones de tipo de valor.

Echemos un vistazo al siguiente ejemplo:

// tipo dinámico (sin tipo específico definido, asignando valor directamente)
$name = "Branko"; // string
$salary = 4200.00; // float
$age = 33; // int

// tipo débil (valor variable reasignado en un tipo diferente)
$salary= 4200.00; // float
$salary= $salary + "USD"; // float
$salary= $salary. "USD"; // string

En el código anterior, vemos tres variables diferentes que se utilizan, ninguna de las cuales están predefinidas con un cierto tipo. Solo tenemos valores declarados en ellos. PHP entonces determina el tipo sobre la marcha. Incluso cuando se determina el tipo de variable, aún puede ser cambiado simplemente asignándole otro tipo de valor. Estos son dos muy poderosos conceptos que, cuando se usan sabiamente, pueden salvarnos líneas y líneas de código.

Sin embargo, estas potentes funciones a menudo indirectamente fomentan un mal diseño. Esto es particularmente notable al escribir funciones, ya sea forzando a los diseñadores de funciones a múltiples comprobaciones de tipos de datos, o forzándolos a múltiples tipos de retorno de funciones.

Echemos un vistazo al siguiente ejemplo:

function addTab($tab) {
 if (is_array($tab)) {
 } elseif (is_object($tab)) {
 } elseif (is_string($tab)) {
 } else {
 }
}

Dada la incertidumbre de tipo del argumento de entrada, la función addTab se vio obligada a ramificar su lógica. Del mismo modo, la misma función podría decidir devolver diferentes tipos de datos, dependiendo de la rama lógica. Los diseños como estos suelen ser el resultado de funciones que simplemente trata de hacer demasiado. El verdadero problema ni siquiera está en la función, está en el lado del consumidor de las cosas. Si sucede que el desarrollador que usa una función no es suficientemente consciente  del tipo de parámetro que pasa, pueden ocurrir resultados inesperados.

Para ayudarnos a escribir programas más correctos y autodocumentados, PHP introdujo el tipo reticente.

PHP ha admitido sugerencias de tipo de parámetro de función desde la versión 5.0, pero solo para objetos, y de la versión 5.1 para matrices también. Con PHP 7, los tipos escalares también se pueden insinuar, convirtiéndola en una de las características más emocionantes del lanzamiento. Los siguientes son el tipo escalar

Consejos compatibles con PHP:

  • int
  • float
  • string
  • bool

Ahora podemos escribir funciones de cualquiera de las siguientes maneras:

  • Puede ser  function register($email, $age, $notify) {/ * … * /}
  • Puede ser function register($ email, int $age, $notify) {/ * … */}
  • Puede ser function register(string $email, int $age, bool $notify) {/ * … * /}

Sin embargo, simplemente insinuar tipos escalares no es suficiente ya que las declaraciones de tipo no se aplican por defecto. PHP simplemente intentará convertir al tipo especificado. Al agregar declare (strict_types= 1); directiva como la primera declaración en un archivo PHP, podemos hacer cumplir el comportamiento estricto de verificación de tipos. Vale la pena señalar que esta directiva solo afecta al archivo específico en el que se usa y no afecta a otros archivos incluidos. La directiva de nivel de archivo se utilizó para preservar la compatibilidad con numerosas extensiones y funciones PHP integradas.

Echemos un vistazo al siguiente ejemplo:

declare(strict_types=1);
function register(string $email, int $age, bool $notify) {
 // body
}
register('user@mail.com', '33', true);

Con la directiva de tipos estrictos activada, intentar pasar un tipo de datos incorrecto a un parámetro escalar insinuado daría como resultado una excepción \ TypeError, según el siguiente resultado:

Fatal error: Uncaught TypeError: Argument 2 passed to register() must be of the type integer, string given, called in /test.php on line 11 and defined in /test.php:5 Stack trace: #0 /test.php(11): register('user@mail.co...', '33', true) #1 {main} thrown in /test.php on line 5.

Las sugerencias de tipo escalar son una nueva y poderosa adición al lenguaje PHP. Proporcionan a los desarrolladores una capa adicional de protección durante el tiempo de ejecución, sin sacrificar realmente el sistema de tipo débil en general.

Comparte