Aspectos del lenguaje

PHP es un lenguaje dinámico y flexible que soporta diversas técnicas de programación. Ha tenido una evolución orgánica y ha cambiado dramáticamente en los últimos años.

PHP ha tenido una historia vibrante desde que comenzó como un proyecto personal de Rasmus Lerdorf, que por entonces no tenía la intención de desarrollar un lenguaje, pero una cosa llevó a otra hasta la implementación actual del Zend Engine 3, pasando de ser un conjunto de rutinas escritas en C para potenciar la página personal de Rasmus a ser un lenguaje en toda regla que hoy potencia gran parte del Internet, desde Wikipedia y Wordpress, tiendas en línea como PrestaShop u OpenCart, hasta los millones de foros, bitácoras y aplicaciones que hoy por hoy dependen de PHP para funcionar.

A pesar de la retrocompatibilidad que se ha tratado de mantener en el lenguaje, en poco se parece el PHP de hoy al PHP de antaño, su evolución (tremendamente orgánica) ha sido producto de un esfuerzo colectivo que ha fructificado en una especificación formal, varias implementaciones y, finalmente, en un lenguaje que cumple con las demandas que la industria y los profesionales de hoy día ejercen.

En este capítulo se abordará todos los aspectos generales necesarios para conocer el lenguaje y comenzar a programar apropiadamente con PHP.

Paradigmas de programación

PHP es un lenguaje de programación cuya sintaxis es heredera de C, pero a diferencia de este último, PHP es un lenguaje de tipado dinámico, multiparadigma e interpretado.

Se ha dotado a PHP con un soporte amplio de paradigmas de programación. Durante su draḿatica evolución se le agregaron destacables mejoras en el soporte de los mismos, tales como ser la orientación a objetos y funcional (gracias al soporte de funciones anónimas [closures {clausuras}]) en PHP 5.0 (2004); los namespaces (espacios de nombres) en PHP 5.3 (2009), y los traits (rasgos) en PHP 5.4 (2012).

Programación imperativa

La programación imperativa no es más que el uso de sentencias que van cambiando los estados de un programa. Es decir, esas sentencias le van instruyendo a la computadora que valor tiene un elemento en un momento dado. Cuando los conjuntos de sentencias se empacan en funciones se le llama programación procedural, y cuando se emplean estructuras para controlar el flujo de los procedimientos, en efecto, se habla de programación estructurada.

Este paradigma es tremendamente útil para automatizar tareas, como crear pequeños scripts que realizan cálculos sencillos o resuelven tareas repetitivas.

El típico ejemplo de «Hola mundo» es en toda regla un ejemplo de programación imperativa para PHP.

echo "¡Hola mundo!";

Programación orientada a objetos

El principio básico de la orientación a objetos es que los programas se comporten como una secuencia de transformaciones en los estados de sus objetos por medio de mensajes; ahora, la implementación de este paradigma requiere el soporte de un conjunto amplio de características, como clases, interfaces, herencia, constructores, clonación, excepciones, etc. PHP soporta bastante bien este paradigma, proveyendo no sólo un conjunto amplio de sus carácterísticas, sino también un rico set de clases básicas de gran utilidad cuando se desarrolla empleando esta técnica de programación.

Ahora, el paradigma orientado a objetos no se implementa igual en todos los lenguajes, por diversas razones, por ejemplo PHP no soporta la herencia múltiple, pero en cambio soporta la elegancia de los traits (rasgos).

Programación funcional

PHP soporta funciones de orden superior, esto significa que una función puede asignarse a una variable. Tanto las funciones definidas por el usuario como las funciones predefinidas por el lenguaje pueden referenciarse por medio de una variable y ser invocadas dinámicamente. Las funciones pueden pasarse como argumentos a otras funciones, y también pueden devolver otras funciones.

La recursividad, una característica que permite a una función llamarse a sí misma, está soportada por el lenguaje, pero la mayoría del código de PHP tiende a enfocarse en la iteración.

PHP 5.4 agregó la posibilidad de enlazar closures a el alcance de un objeto y también mejoró el soporte para invocables en tanto que pueden utilizarse intercambiablemente con funciones anónimas en la mayoría de los casos.

Metaprogramación

PHP soporta varias formas de metaprogramación a través de mecanismos como la API de reflexión y métodos mágicos. Existen muchos métodos mágicos disponibles como __get(), __set(), __clone(), __toString(), __invoke(), etc., que permiten a los desarrolladores inspeccionar el comportamiento de las clases. Algunos desarroladores de Ruby dicen que en PHP falta method_missing (ausencia de método), pero está disponible como __call() y __callStatic().

Interfaz de línea de comandos

PHP fue creado para escribir aplicaciones web, pero también es útil como lenguaje de script para programar aplicaciones de interfaz de línea de comandos (command line interface [CLI]). Los programas PHP para CLI pueden ayudar a automatizar tareas como pruebas, despliegue y administración de aplicaciones.

Los programas PHP para CLI son poderosos porque es posible utilizar directamente el código de una aplicación sin tener que crear y asegurar una GUI web para ella. Sólo hay que tener cuidado de no poner los scripts de PHP en el directorio raíz de acceso público.

Ejecútese desde la línea de comandos:

php -i

La opción -i mostrará en pantalla la configuración de PHP tal como una llamada a la función phpinfo().

La opción -a provee una consola interactiva, similar a la IRM de Ruby o a la consola interactiva de Python. Existe un amplio conjunto de opciones de gran utilidad.

El siguiente ejemplo es un sencillo programa para CLI de «Hola, $name». Para hacerlo, crear un archivo y llamarle hello.php:

if ($argc !== 2) {
    echo "Ejecutado: php hello.php [nombre].\n";
    exit(1);
}
$name = $argv[1];
echo "Hola $name\n.";

PHP establece dos variables especiales basadas en los argumentos con los que se ejecuta el script: $argc es una variable de tipo entero que contiene el argumento de conteo y $argv es otra variable de tipo arreglo conteniendo cada valor del argumento. El primer argumento es siempre el nombre del archivo PHP, en este caso hello.php.

La expresión exit() se usa con número distinto de cero para indicarle a la consola que el comando ha fallado. Los códigos de salida comunmente usados pueden encontrarse aquí.

Para correr el script, ejecutar desde la línea de comandos:

> php hello.php
Ejecutado: php hello.php [nombre]
> php hello.php mundo
Hola mundo.

Sintaxis básica

Como se mencionó al principio de este capítulo, la sintaxis de PHP es principalmente heredera de la sintaxis de C, pero también bebe de PERL, Java y C++. No se asuste el(la) lector(a) por ello, la sintaxis de PHP es sencilla y de fácil aprendizaje.

Etiquetas

Todo código PHP se ubica entre etiquetas de apertura y cierre: <?php ?>. El código PHP puede embeberse junto al html, el intérprete ejecutará sólo aquel código que se encuentre entre las etiquetas PHP; no obstante es recomendable que el html y el código PHP no se mezclen en un mismo archivo, es preferible que los archivos PHP contengan sólo código PHP, la primer línea de estos archivos ha de ser la etiqueta de apertura <?php y la etiqueta de cierre se omite.

<?php
// La línea de arriba debe ser siempre la primera de todo archivo PHP

Comentarios

Los comentarios permiten escribir prosa explicativa que es útil a los programadores e irrelevante al intérprete, de modo que los ignora. Los comentarios cortos se prefijan con // y terminan con la línea.

Los comentarios largos o multilínea se encierran entre \* y */, por ejemplo:

// Comentario corto
/*
Comentario largo,
este comentario puede contener mucho texto que explique el porqué
de las cosas que se están haciendo y puede componerse de muchas líneas.
 */

Sentencias y bloques

Tal como en C, C++ o Java, en PHP cada sentencia debe terminar con un punto y coma «;», y cada bloque se delimita con llaves «{}», ejemplo:

// Las sentencias terminan en punto y coma:
echo "Las sentencias terminan en punto y coma";
$tres = 2 + 1;
echo $tres;

// Los bloques se delimitan en llaves
if(true) {
  // Cuerpo del bloque
}

class LaClase {
  // Cuerpo del bloque
}

Como puede observarse en el ejemplo anterior, tanto una estructura condicional como una clase representan bloques, muchas otras estructuras de PHP también son bloques y se verán más adelante.

Tipos de dato

Un «tipo de dato» determina la semántica y límites de un valor cualesquiera que exista en el contexto de ejecución de todo programa. La especifiación de PHP categoriza los tipos soportados por PHP en dos grupos: escalares y compuestos.

Tipos escalares

Los tipos escalares son tipos de valor o magnitud, su estructura es atómica [1] y todo escalar se comporta como contenedor exclusivo de su propio valor. PHP soporta cinco tipos escalares:

  • bool

  • int (números enteros)

  • float (números de punto flotante)

  • string (cadenas de texto)

  • null (valores «nulos»)

Los tipos integer y float son también conocidos como «tipos aritméticos».

El tipo binario Boolean

Abstrae los valores binarios de verdadero y falso; se expresa como bool, y boolean funge como sinónimo. En consecuencia, este tipo es capaz de contener exclusivamente uno de los dos valores de la lógica booleana correspondientes a verdadero y falso: true y false.

El tipo Entero

Abstrae la representación de los números enteros; se expresa como int, e integer funge como sinónimo. Este tipo respeta sigo (positivo y negativo) y su capacidad de almacenamiento depende de la plataforma (32 o 64 bits); para 32 bits el rango posible ronda entre «-2147483648 y 2147483647» (unos dos mil millones) en tanto que para 64 bits el valor máximo es de alrededor de 9E18 (unos nueve quintillones).

Además de la notación decimal, este tipo también soporta la notación octal, hexadecimal y binaria.

El tipo Flotante

Abstrae la representación de números reales, se expresa como float, en tanto que double y real fungen como sinónimos.

Algunas operaciones sobre enteros pueden producir resultados matemáticos que no se pueden representar como int y por tanto se representarán como float.

El tipo Cadena

Una cadena es un conjunto continuo de bytes que representan una secuencia de cero o más caracteres.

Conceptualmente una cadena puede considerarse como un arreglo de bytes (de elementos) donde sus claves son valores enteros iniciando en el cero. No obstante una cadena no se considera una colección y no puede iterarse [2].

Se expresa como string y carece de sinónimos.

El tipo Nulo

El tipo nulo puede almacenar exclusivamente un sólo valor: NULL. Este valor escalar representa la nulidad, es decir la ausencia de valor o magnitud. Este tipo es especial en tanto que no admite operaciones y su único fin es, precisamente, representar la nulidad. Se expresa como null.

Tipos compuestos

Se denominan compuestos en tanto estos tipos pueden contener otras variables además de sí misma, por ejemplo un objeto contiene a sus propiedades y un arreglo contiene sus elementos.

Los objetos y recursos son tipos gestionados. El tipo contiene información (en un gestor) que encamina hacia el valor. PHP soporta los siguientes tipos compuestos:

  • array (arreglos)

  • object (objeto)

  • callable (invocable)

  • resource

El tipo Arreglo

Un arreglo se expresa como array, se trata de una estructura de datos que contiene una colección de cero o más elementos cuyos valores son accesibles mediante claves de tipo int o string.

El tipo Objeto

Un objeto es una instancia de una clase. Cada declaración de clase define un nuevo tipo, y dicho tipo es también un tipo objeto.

El tipo Invocable

Un invocable es un tipo que denota una función que puede invocarse dentro del contexto al que se provee como argumento.

El tipo Recurso

Un recurso es un descriptor hacia una especie de entidad externa, por ejemplo archivos, bases de datos o sockets de red.

Los recursos son solamente creados y consumidos por la implementación, pero nunca son creados ni consumidos por código PHP.

Variables

Las variables son construcciones que almacenan datos y que son susceptibles de operaciones. En PHP las variables son de tipo dinámico, adoptan el tipo del valor que se les asigna, y si tras una asignación el nuevo valor es de un tipo diferente al anterior, la variable adopta ese nuevo tipo.

Todas las variables en PHP se prefijan con $. Las variables deben nombrarse siempre con letras o con el guión bajo, pero nunca pueden iniciar con un número.

// Variables válidas nombradas de tal forma que reflejan su tipo
$unEntero = 6;
$unaCadena = "Texto",
$unBoolean = false;

// Variable válida que inicia con guión bajo
$_unFlotante = 3.1416;

// Variable inválida, PHP lanzará un error si se declara una variable así
$1VariableInvalida = null;

Debido a que las variables pueden cambiar de tipo, resulta útil poder saber que tipo tiene una variable en un momento concreto, para ello PHP dispone de la función gettype().

$unEntero = "6";
echo gettype($unEntero); // Imprime 'string'

Hay ocasiones en las que se desea forzar a que una variable sea de un tipo determinado, PHP cuenta con la función settype() para establecer un tipo concreto a una variable.

// El tipo de
$unEntero = "6";
settype($unEntero, 'integer');
echo gettype($unEntero); // Imprime 'integer'

Ámbito o alcance

Ámbito o alcance refieren a la accesibilidad de una variable dentro de un contexto. Si una variable se declara a nivel de un archivo será accesible para ese archivo y los archivo que incluya, incluyendo los bloques de estructuras de control y exceptuando para las funciones y clases dentro de dicho archivo.

<?php
$uno = 1;

include "extrafile.php";

Así, dentro del archivo extrafile.php la variable $uno es accesible. No obstante, los bloques implementan un alcance local, es decir, sus variables son accesibles únicamente dentro de su delimitación de bloque.

<?php
$uno = 1; // Variable con alcance de nivel de archivo

if(true) {
  $tres = 3;
}

function local() {
  $dos = 2; // Variable con alcance local
  echo $dos;
}

echo $dos; // Esto es un error porque $dos sólo existe para el bloque de la función.
echo $tres; // Imprimirá 3
local(); // Imprimirá 2

Es necesario tener presente esas diferencias en la accesibilidad de las variables. Por ejemplo, el hecho de que $tres sea accesible fuera del bloque if tras su definición. No obstante lo anterior, por legibilidad, es conveniente «declarar» una variable previo a su redefinición dentro de un bloque.

<?php
$tres = null; // Declarada la variable con un valor nulo para su posterior uso.

if(true) {
  $tres = 3; // Redefinida la variable con un valor determinado
}

echo $tres; // Imprime 3

Operadores

Los operadores son construcciones que permiten transformar el valor de variables y de expresiones. Son implementaciones de los operadores matemáticos, pero con ciertas particularidades.

Como en matemáticas, los operadores responden a una precedencia, así un operador de multiplicación (*) precede a un operador de adición (+). Asímismo es posible manipular la precedencia mediante paréntesis: $nueve = (1 + 2) * 3;

Los operadores también responden a una asociatividad que determina su orden de evaluación, de tal modo que cuando se presentan operadores de igual precedencia, su orden de evaluación se ejecuta en función de su asociatividad.

Operadores aritméticos

Son operadores binarios correspondientes a la arimética básica:

  • + Adición (o suma)

  • - Sustracción (o resta)

  • * Producto (o multiplicación)

  • / Cociente (o división)

Los cuatro operadores anteriormente listados tienen una asociatividad por la izquierda. El operador ** se utiliza para la exponenciación y se asocia por la derecha: $a ** $n significa elevar $a a la enésima potencia.

Operadores de asignación

Todos los operadores de asignación son binarios (es decir, operan sobre dos elementos) y tienen una asociatividad por la derecha. Sirven para establecer el valor del elemento de la derecha en el elemento de la izquierda. El operador de asignación por antonomasia es =; pero no es el único. Otros operadores de asignación son: +=, -=, *=, /=, y sirven como abreviaciones de operaciones entre operadores aritméticos y de asignación. Un ejemplo lo dejará más claro:

<?php
$n = 6;
// Para sumar el propio $n a $n:
$n = $n + $n; // $n = 12

// Puede abreviarse como
$n += $n;

Operadores de comparación

Son operadores binarios que permiten evaluar la semejanza de dos elementos. Estos operadores no responden a ninguna asociatividad.

  • $n == $m Compara si el valor de $n es igual al de $m.

  • $n != $m Compara si el valor de $n es diferente de $m.

  • $n > $m Compara si el valor de $n es mayor que el $m.

  • $n >= $m Compara si el valor de $n es mayor o igual que el $m.

  • $n < $m Compara si el valor de $n es menor que el $m.

  • $n <= $m Compara si el valor de $n es menor o igual que el $m.

Los primeros dos operadores de comparación (== y !=) no comparan el tipo, tal que 6 == '6' devolverá true, y esto puede dar paso a potenciales errores, por ello es recomendable el uso de los operadores de comparación idéntica:

  • $n === $m Compara si el valor de $n es idéntico al de $m.

  • $n !== $m Compara si el valor de $n es no idéntico de $m.

El resultado de la comparación es siempre un valor booleano, y este puede utilizarse tanto en expresiones como asignarse a variables. Algunos ejemplos ayudarán a aclarar mejor estos conceptos:

<?php
$n = 6;
$m = '6'

// Comparación de igualdad
echo $n == $m; // true

// Cambiar el valor y comparar de nuevo
$m = 9;
echo $n == $m //  false

$m = '6';
echo $n != $m // $r = false
echo $n !== $m // $r = true

// Asignar el resultado de una comparación e imprimirlo
$m = 9;
$r = ($n > $m)// $r = false;
echo $r;

Operadores lógicos

Los operadores lógicos son operadores binarios que se asocian por la izquierda y sirven para evaluar expresiones booleanas.

  • $a && $b (AND [Conjunción «ʌ»]) Devolverá true sí y solo sí $a y $b son true.

  • $a || $b (OR [Disyunción inclusiva «ᴠ»]) Devolverá true sí cualquiera de $a o $b son true.

  • $a xor $b (XOR [Disyunción exclusiva «⊕»]) Devolverá true$a o $b son true, pero no ambos.

Otros operadores

Se han visto la mayoría de operadores utilizados en PHP, y aunque no se han listado todos, los vistos hasta ahora son suficientes para la mayoría de operaciones en el día a día habitual del desarrollo con PHP.

Estructuras de control

Las estructuras de control son fundamentales para encaminar el flujo de ejecución de las instrucciones de un programa. Básicamente, toda estructura de control evalúa una expresión y a partir del resultado de dicha evaluación, determina que se ejecuta a continuación.

Se distinguen dos tipos básicos de estructuras de control: condicionales y ciclos.

Condiciones

Sirven para determinar, en función de una condición, que se ejecuta y que no. Las dos estructuras básicas de este tipo son if (<expresión>) y switch (<expresión>).

Condición si if (<expresión>)

A la estrucura if (<expresión>) puede agregarse las construcciones else(<expresión>) y/o else if (<expresión>).

La condición if (<expresión>) evaluará la <expresión> y si esta resulta true ejecutará la sentencia o bloque que le sigue. Si se ha definido else(<expresión>),y el resultado de la <expresión> es false, entonces se ejecuta la sentencia o bloque que le sigue. Si se ha definido else if (<expresión>), y la evaluación del primer if (<expresión>) es false entonces se evaluará la nueva <expresión> correspondiente al else if (<expresión>) y su sentencia o bloque se ejecutará sólo si el resultado de dicha expresión es true. Cabe recordar que la evaluación de la expresión variará según se empleen operadores de comparación idéntica (===) o no (==).

Ejemplos a continuación:

<?php
$verdadero = true;

// La siguiente sentencia se ejecutará siempre
if($verdadero) echo 'verdadero';

// La siguiente sentencia no se ejecutará nunca
if($verdadero === false) echo 'false';

// Del siguiente ejemplo se ejecutará el bloque del else
if($verdadero === false) {
  echo 'nunca entra aquí';
  // Recordando que un bloque se delimita por llaves «{}»
}
else {
  echo 'entra en el else';
  // Cambiar el valor de la expresión
  $verdadero = false;
}

// A continuación se evalúan ambas expresiones,
// pero no entra en ninguna.
if($verdadero) {
  // nunca entra aquí
}
else if($verdadero === 6) {
  // tampoco entra aquí
}
Condición de caso switch (<expresión>)

Para la condición switch (<expresión>) se define una serie de case (casos), si la <expresión> concuerda con un caso, se comenzará a ejecutar a partir de dicha coincidencia hasta el fin de la estructura o cuando se encuentre un break (quiebre). Al switch (<expresión>) se le puede anidar un default como un caso especial que se ejecuratá cuando ninguno de los otros casos coincida con la expresión.

También debe considerarse lo siguiente:

  • La evaluación de comparación es por valor (==) y no la idéntica (===).

  • Puede omitirse la sentencia break, en cuyo caso la ejecución continuará hasta encontrar algún break, return o terminar toda la estructura.

  • Dentro del alcance de una función, si se emplea una sentencia return no hace falta expresar una sentencia ``break`.

Ejemplos a continuación:

<?php

switch ($verdadero) {
  case true:
    echo 'nunca entra aquí';
    break;
  case false:
    echo 'el valor de $verdadero es false\n';
    $verdaredo = true;
    echo 'ahora el valor de $verdadero es true';
    break;
  case 6:
    echo 'nunca entra aquí';
    break;
  case 'nunca':
    return; // Nunca entra aquí tampoco
  default:
    echo 'por defecto tampoco entrará aquí';
}

Comprender todas las combinaciones posibles para una estructura de control puede llevar algo de práctica, pero una vez conseguido es posible obtener un control eficiente y un código elegante.

Ciclos

Los ciclos son estructuras que sirven para controlar la repetición de una sentencia o bloque. Mucha veces es necesario recorrer elementos y operar uno por uno, o bien, repetir una funcionalidad un determinado número de veces.

Los ciclos son semejantes a las condiciones en tanto que también necesitan de una expresión que se evalúa y en función de la cual se determina si el ciclo se ejecuta o no. Tal expresión, por lo general, se modifica con cada iteración del ciclo o bien, se altera una bandera para indicar al ciclo que debe dejar de ejecutarse.

PHP soporta cuatro estructuras para ciclos: while (mientras…), do while (hacer y mientras…), for (para…) y foreach (para cada…).

while

En español significa «mientras», y es el tipo de ciclo más básico. Este ciclo se itera mientras la condición de la expresión sea verdadera, por lo general la condición se controla con un contador:

<?php
$contador = 0;

while ($contador < 6) {
  echo $contador . "\n";
  $contador += 1;
}
do while

Esta estructura es similar a while, pero se ejecuta al menos una vez. Si la condición de while resulta false desde un principio, el ciclo no se ejecuta, en tanto que do while sí que lo hará al menos una.

<?php
$contador = 0;

// Nunca entrará debido a que el contador vale 0
while ($contador > 1 && $contador < 6) {
  echo $contador . "\n";
  $contador += 1;
}

// Se ejecutará al menos una vez
do {
  echo $contador . "\n";
  $contador += 1;
} while ($contador < 6)
for

Es el ciclo por excelencia para iterar sobre contadores y estructuras iterables. Es parecido a while, pero con una estructura que permite declarar el contador y la condición de iteración en una sóla línea, lo que favorece la construcción de cliclos elegates.

<?php
for($i = 0; $i < 6; $i++) {
  echo $contador . "\n";
}

La expresión $i++ utiliza el operador unitario ++, que sirve como una abreviatura de $i += 1;

Muchas veces el for se utiliza para recorrer arreglos u objetos y por tanto la condición de iteración está dada por el tamaño del arreglo:

<?php
$birras = ['rubia', 'mestiza', 'morena'];
$limite = count($birras);

for($i = 0; $i < $limite; $i++) {
  echo 'Que buena es la cerveza ' . $birras[$i] . "\n";
}
foreach

Como se mencionó antes, los arreglos son tipos iterables, tipos que se comportan bien como vectores (arreglos indexados) y como diccionarios (arreglos de pares clave y valor). El ciclo foreach permite iterar sin necesidad de contadores sobre cualquier elemento que implemente la interfaz Iterable.

<?php
$birras = ['rubia', 'mestiza', 'morena'];
$cervezas = [
  'rubias' => ['artesanal', 'nacional', 'extranjera'],
  'mestizas' => ['artesanal', 'nacional'],
  'morena' => 'artesanal'
];

foreach($birras as $birra) {
  echo $birra;
}

foreach($cervezas as $clave => $alor) {
  echo $clave . ' ' . $valor;
}

Funciones

Las funciones en PHP son herederas de las funciones matemáticas, son construcciones que esperan una entrada, realizan un proceso y devuelven una salida. Es decir, empaquetan una tarea o rutina.

Valga decir que no todas las funciones operan bajo el principio de entradaprocesosalida; existen funciones que operan directamente sobre los argumentos de entrada y no devuelven nada, y otras que no esperan argumentos pero sí que retornan alguna salida. No obstante, la gran mayoría se ciñen al esquema básico descrito.

PHP dispone de un amplio número de funciones predefinidas y también permite la construcción de nuevas funciones por parte de lo(a)s programadores.

Para definir funciones en PHP se emplea la sentecia function, que antecede al nombre de la función, y tras el cual se definen (de ser necesario) entre paréntesis los parámetros que esperará como argumentos la función y, finalmente, el cuerpo de la función que siempre será un bloque entre llaves.

A partir de PHP 5.x se soporta declarar el tipo de los parámetros, y desde PHP 7.0 se soporta definir el tipo de retorno de la función mediante : <tipo> donde <tipo> puede ser cualquier tipo primitivo soportado por PHP o bien, cualquier tipo definido por el(la) desarrollar(a) como clase o interfaz.

Para invocar una función simplemente se emplea su nombre seguido de los argumentos correspondientes entre paréntesis.

<?php

function sumarEnteros(int $n1, int $n2) : int {
    return $n1 + $n2;
}

echo sumarEnteros(2, 6); // → 8

Parámetros y argumentos

Como se indicó en el apartado anterior, a las funciones es posible asignarles una lista opcional de parámetros. Cada parámetro se separa por coma y para cada parámetro es posible declarar un tipo (primitivo o definido) a fin de que los argumentos proveídos estén restringidos a dicho tipo.

<?php

function mostrarTipos(int $ene, string $cadena, bool $vof, $cualquiera) {
  echo gettype($ene);
  echo gettype($cadena);
  echo gettype($vof);
  echo gettype($cualquiera);
}

mostrarTipos(6, "birra", false, new \stdClass());
mostrarTipos("6", "birra", false, new \stdClass()); // lanzará error

En ocasiones para una función se podría esperar una lista arbitraria de parámetros a fin de que durante la llamada se establezcan, bien una lista separada por comas, bien una lista en un arreglo, un conjunto cuantitativamente arbitrario de argumentos. A partir de PHP 5.6 es posible declarar que se espera dicho tipo de listas mediante el token como prefijo al parámetro que contendrá el listado.

<?php

function sumar(int ...$sumandos) : int {
  $r = 0;
  foreach($sumandos as $s) {
      $r += $s;
  }

  return $r;
}

echo sumar(1, 2, 3, 4); // → 10

El depurador Xdebug

Una de las herramientas más útiles en el desarrollo de software es un buen depurador. Permite trazar el flujo de ejecución del código y monitorear los contenidos de la pila de ejecución. Xdebug, el depurador de PHP, puede ser utilizado por varios IDE’s para proveer puntos de quiebre y pilas de inspección. También permite que herramientas como PHPUnit y KCacheGrind realicen un análisis y seguimiento del código.

Si un desarrollador se encuentra en un punto ciego, devolviendo cosas con var_dump()/print_r(), y aun así no puede encontrar la solución, quizá lo que necesite sea un depurador.

Instalar Xdebug puede ser engorroso, pero una de sus características más importantes es «la depuración remota», si tu desarrollo es local y probado en una máquina virtual o en otro serwidor, la depuración remota es la característica que querrás tener habilitada.

Tradicionalmente, en Apache es necesario modificar el VHost o el archivo .htacces con los siguientes valores:

php_value xdebug.remote_host 192.168.?.?
php_value xdebug.remote_port 9000

Las propiedades remote_host y remote_port corresponden con la computadora local y el puerto que se ha de configurar en un IDE para que lo escuche. Entonces se vuelve sólo cuestión de configurar el IDE en modo de «escucha de conexiones» y cargar la URL:

http://tu-proyecto.ejemplo.dev/index.php?XDEBUG_SESSION_START=1

El IDE entonces comenzará a interceptar el estado actual del script en ejecución, permitiendo a los desarrolladores establecer puntos de quiebre y evaluar los valores en memoria.

Los depuradores gráficos facilitan dar seguimiento al código, inspecionar variables, y evaluar el código contra la ejecución en vivo. Muchos IDEs tienen preempaquetados o soportado mediante extensiones la depuración gráfica con Xdebug.