Return en PHP: Tips, Patrones y Mejores Prácticas
06-10-2025 | PHP function 7 min
- Devolver objetos
- Diferencias entre return e impresión directa
- Early Return
- Tipado de retorno
- Más detalles sobre return
Cuando pensamos en funciones en PHP, es común que lo primero que venga a la mente sea la palabra reservada return. Sin embargo, su uso y significado van mucho más allá de simplemente devolver un valor. En este artículo revisaremos en detalle su uso, mejores prácticas y algunos patrones comunes que te ayudarán a escribir un código más limpio y eficiente.
Comencemos con lo más sencillo, vimos en Funciones en PHP explicadas de forma simple que return
se usa dentro de una función o método para devolver un valor. Esto es lo básico:
function greet($name): string {
return "Hello, $name!";
}
echo greet('Graaan'); // Imprime "Hello, Graaan!"
En este caso:
greet
es la función que devuelve un string.echo
imprime el valor devuelto.
Y como puedes imaginar, podemos devolver o retornar cualquier tipo de dato: int
, string
, array
, object
, etc.
function getInteger(): int {
return 39;
}
function getArray(): array {
return [1, 2, 3];
}
// Etc.
Devolver objetos
Tenemos quizás el caso más interesante, que es devolver un objeto. Aquí un ejemplo simple con una clase Person
y una función que devuelve una instancia de esa clase:
class Person
{
public function __construct(
public string $name,
) {}
}
function getPerson(): Person {
return new Person('Graaan');
}
$person = getPerson();
echo $person->name; // Imprime "Graaan"
getPerson
es nuestra función encargada de crear y devolver un objeto Person
.
return
e impresión directa
Diferencias entre Esta es una duda muy común. En PHP podemos utilizar echo
, print
u otras instrucciones que muestran directamente un resultado. En cambio, return
tiene un propósito distinto: devuelve un valor que puede ser almacenado en una variable o utilizado dentro de otra expresión.
Puntualmente:
return
termina la ejecución de la función y devuelve un valor.echo
y similares simplemente imprimen un valor de forma directa e inmediata.
Para visualizar esta diferencia con mayor claridad, analicemos el resultado usando var_dump
:
function testReturn(): int {
return 39;
}
function testEcho(): void {
echo 39;
}
var_dump(testReturn()); // Imprime int(39)
var_dump(testEcho()); // Imprime 39NULL
Aquí podemos comprobar que testReturn
no imprime, devuelve el valor para ser usado, mientras que testEcho
imprime 39 y luego NULL
, precisamente porque no tiene la palabra clave return
.
Early Return
Esta es una técnica ampliamente utilizada en desarrollo profesional para mejorar la legibilidad y el control del flujo del código. Su principio es simple: salir de la función tan pronto como sea necesario cuando se cumple una condición específica.
Veamos un ejemplo. Supongamos que tenemos una función que realiza la división entre dos números (sí, la clásica división con el famoso 0
). Si el divisor es cero, la función debe devolver false
para evitar el error Fatal error: Uncaught DivisionByZeroError: Division by zero in ...
.
En este caso, aplicar early return
nos permite manejar esta situación especial desde el inicio de la función, evitando anidaciones innecesarias y haciendo el código más claro y seguro:
function div(int $a, int $b): float|bool {
if ($b === 0) {
return false;
}
return $a / $b;
}
var_dump(div(9, 3)); // Imprime float(3)
var_dump(div(9, 0)); // Imprime bool(false)
Tipado de retorno
Y aunque ya lo hemos visto en Funciones en PHP explicadas de forma simple en la seccion tipos de parámetros y retorno, te quiero mostrar el tipo null
, void
, mixed
, never
y union types.
function testNull(): ?string {
return null; // o puede devolver un string
}
function testVoid(): void {
echo 'This function returns nothing.';
}
function testMixed(mixed $input): mixed {
return $input;
}
function testNever(): never {
throw new Exception('This function never returns.');
}
function testUnion(int|string $input): int|string {
return $input;
}
Aquí la explicación de cada una de ellas:
?string
indica que la función puede devolver un string o null, la sintaxis es?Type
.void
significa vacío o nulo, no devuelve ningún valor.mixed
significa mezclado o variado. En nuestro ejemplo, devuelve el mismo tipo que recibe.never
se usa cuando la función nunca devuelve un valor, generalmente para interrumpir el flujo. Por ejemplo, si siempre se lanza una excepción.- Con
int|string
conseguimos el ejemplo de union types, y nos dice que la función puede devolver unint
o unstring
.
Y por supuesto, podemos retornar un objeto como en el ejemplo anterior unido a la posibilidad de retornar null
:
// ...
function getPerson(int $id): ?Person {
return Person::find($id);
}
En este ejemplo simulamos que Person::find($id)
puede devolver un objeto Person
o null
si no se encuentra el registro en la base de datos. Este comportamiento es muy común en proyectos desarrollados con Laravel o frameworks que implementan patrones similares, donde los métodos de búsqueda retornan una instancia del modelo cuando el registro existe, o null
en caso contrario.
return
Más detalles sobre Este es un tema que da para mucho, pero quiero mostrarte dos patrones muy comunes en desarrollo profesional: Method Chaining y Fluent Interface. Nos salimos un poco del contexto de funciones, pero es importante que lo conozcas porque un método cuenta con la misma estructura de una función.
Trabajemos en la clase Str
que para nuestro ejemplo, permite manipular strings de forma encadenada:
class Str
{
public string $text;
public function text(string $text): self
{
$this->text = $text;
return $this;
}
public function upper(): self
{
$this->text = strtoupper($this->text);
return $this;
}
public function replace(string $search, string $replace): self
{
$this->text = str_replace($search, $replace, $this->text);
return $this;
}
public function truncate(int $length, string $suffix = '...'): self
{
if (strlen($this->text) > $length) {
$this->text = substr($this->text, 0, $length) . $suffix;
}
return $this;
}
public function get(): string
{
return $this->text;
}
}
En un próximo artículo profundizaré en el tema de clases y objetos. Por ahora, basta con entender que la clase Str
permite manipular cadenas de texto de forma encadenada gracias al uso de return $this;
.
Veamos dos conceptos importantes que surgen a partir de esta idea:
- Method Chaining: Es una técnica que permite llamar a múltiples métodos de un mismo objeto en una sola línea de código. Y lo logramos precisamente con
return $this;
. - Fluent Interface: Es un estilo de diseño que busca que el código sea más legible y expresivo. Se aplica cuando hacemos uso de la clase y sus métodos de forma encadenada.
Ejemplo 1:
$str = new Str();
$result = $str->text('Esto es una gran prueba')
->upper()
->replace('gran', '---')
->truncate(10)
->get();
echo $result; // Imprime "ESTO ES U..."
Ejemplo 2:
$str = new Str();
$result = $str->text('Esto es otra prueba')
->upper()
->get();
echo $result; // Imprime "ESTO ES OTRA PRUEBA"
Resumen visual:
- Con
return $this;
se activa el Method Chaining. - El uso encadenado de métodos (
->method()->method()
) crea una Fluent Interface.
Otro detalle importante es que una función puede tener múltiples sentencias return
, pero solo se ejecutará una de ellas, dependiendo de las condiciones que se cumplan:
function checkNumber(int $num): string {
if ($num > 0) {
return 'Positive';
} elseif ($num < 0) {
return 'Negative';
} else {
return 'Zero';
}
}
echo checkNumber(9); // Imprime Positive
echo checkNumber(-1); // Imprime Negative
echo checkNumber(0); // Imprime Zero
Como puedes ver, una vez que se ejecuta algún return
, la función finaliza de inmediato. En otras palabras, cualquier línea de código que aparezca después no se ejecutará:
function example() {
echo 'Esto se imprimirá';
return;
echo 'Esto NO se imprimirá'; // Nunca se ejecutará
}
Y si necesitas devolver varios valores desde una misma función, puedes hacerlo utilizando un array. De esta forma, podrás empaquetar múltiples resultados y acceder a ellos fácilmente desde quien llama a la función:
function data(): array {
return [1, 2, 3, 'four', true];
}