With the release of PHP 7, the language allows the developer to be more specific about what functions are getting and returning. You can—always optionally—specify the type of argument that the function needs (type hinting), and the type of result the function will return (return type). Let's first see an example:
<?php declare(strict_types=1); function addNumbers(int $a, int $b, bool $printSum): int { $sum = $a + $b; if ($printSum) { echo 'The sum is ' . $sum; } return $sum; } addNumbers(1, 2, true); addNumbers(1, '2', true); // it fails when strict_types is 1 addNumbers(1, 'something', true); // it always fails
This preceding function states that the
arguments need to be integer, integer, and Boolean, and that the
result will be an integer. Now, you know that PHP has type
juggling, so it can usually transform a value of one type to its
equivalent value of another type, for example, the string "2" can
be used as integer 2. To stop PHP from using type juggling with the
arguments and results of functions, you can declare the directive
strict_types
as shown in the first
highlighted line. This directive has to be declared at the top of
each file where you want to enforce this behavior.
The three invocations work as follows:
- The first invocation sends two integers and a
Boolean, which is what the function expects, so regardless of the
value of
strict_types
, it will always work. - The second invocation sends an integer, a string, and a Boolean. The string has a valid integer value, so if PHP was allowed to use type juggling, the invocation would resolve just normally. But in this example, it will fail because of the declaration at the top of the file.
- The third invocation will always fail as the string "something" cannot be transformed into a valid integer.
Let's try to use a function within our project.
In our index.php
, we have a foreach
loop that iterates the books and prints
them. The code inside the loop is kind of hard to understand as it
is a mix of HTML with PHP, and there is a conditional too. Let's
try to abstract the logic inside the loop into a function. First,
create the new functions.php
file with
the following content:
<?php function printableTitle(array $book): string { $result = '<i>' . $book['title'] . '</i> - ' . $book['author']; if (!$book['available']) { $result .= ' <b>Not available</b>'; } return $result; }
This file will contain our functions. The first
one, printableTitle
, takes an array
representing a book, and builds a string with a nice representation
of the book in HTML. The code is the same as before, just
encapsulated in a function.
Now index.php
will
have to include the functions.php
file,
and then use the function inside the loop. Let's see how:
<?php require_once 'functions.php' ?> <!DOCTYPE html> <html lang="en"> //... ?> <ul> <?php foreach ($books as $book): ?> <li><?php echo printableTitle($book); ?> </li> <?php endforeach; ?> </ul> //...
Well, now our loop looks way cleaner, right? Also, if we need to print the title of the book somewhere else, we can reuse the function instead of duplicating code!