In many cases when developing functions, you might reuse the same library of functions in other projects. Also, if you work with a team, your code might be used by other developers. In order to control the use of your code, it might be appropriate to make use of a type hint. This involves specifying the data type your function expects for that particular parameter.
TypeError is thrown. The following example requires an array, an instance of DateTime, and an anonymous function:function someTypeHint(Array $a, DateTime $t, Callable $c)
{
$message = '';
$message .= 'Array Count: ' . count($a) . PHP_EOL;
$message .= 'Date: ' . $t->format('Y-m-d') . PHP_EOL;
$message .= 'Callable Return: ' . $c() . PHP_EOL;
return $message;
}You don't have to provide a type hint for every single parameter. Use this technique only where supplying a different data type would have a negative effect on the processing of your function. As an example, if your function uses a foreach() loop, if you do not supply an array, or something which implements Traversable, an error will be generated.
declare() directive is made, scalar (that is, integer, float, boolean, and string) type hints are allowed. Another function demonstrates how this is accomplished. At the top of the code library file which contains the function in which you wish to use scalar type hinting, add this declare() directive just after the opening PHP tag:declare(strict_types=1);
function someScalarHint(bool $b, int $i, float $f, string $s)
{
return sprintf("\n%20s : %5s\n%20s : %5d\n%20s " .
": %5.2f\n%20s : %20s\n\n",
'Boolean', ($b ? 'TRUE' : 'FALSE'),
'Integer', $i,
'Float', $f,
'String', $s);
}TypeError will be thrown! However, the incoming value will automatically be converted to the boolean data type once passed into the function. If you pass any data type other than scalar (that is, array or object) a TypeError will be thrown. Here is an example of a function that defines a boolean data type. Note that the return value will be automatically converted to a boolean:function someBoolHint(bool $b)
{
return $b;
}First of all, you can place the three functions, someTypeHint(), someScalarHint(), and someBoolHint(), into a separate file to be included. For this example, we will name the file chap_03_developing_functions_type_hints_library.php. Don't forget to add declare(strict_types=1) at the top!
In our calling code, you would then include the file:
include (__DIR__ . DIRECTORY_SEPARATOR . 'chap_03_developing_functions_type_hints_library.php');
To test someTypeHint(), call the function twice, once with the correct data types, and the second time with incorrect types. This will throw a TypeError, however, so you will need to wrap the function calls in a try { ... } catch () { ...} block:
try {
$callable = function () { return 'Callback Return'; };
echo someTypeHint([1,2,3], new DateTime(), $callable);
echo someTypeHint('A', 'B', 'C');
} catch (TypeError $e) {
echo $e->getMessage();
echo PHP_EOL;
}As you can see from the output shown at the end of this sub-section, when passing the correct data types there is no problem. When passing the incorrect types, a TypeError is thrown.
In PHP 7, certain errors have been converted into an Error class, which is processed in a somewhat similar manner to an Exception. This means you can catch an Error. TypeError is a specific descendant of Error that is thrown when incorrect data types are passed to functions.
All PHP 7 Error classes implement the Throwable interface, as does the Exception class. If you are not sure if you need to catch an Error or an Exception, you can add a block which catches Throwable.
Next you can test someScalarHint(), calling it twice with correct and incorrect values, wrapping the calls in a try { ... } catch () { ...} block:
try {
echo someScalarHint(TRUE, 11, 22.22, 'This is a string');
echo someScalarHint('A', 'B', 'C', 'D');
} catch (TypeError $e) {
echo $e->getMessage();
}As expected, the first call to the function works, and the second throws a TypeError.
When type hinting for boolean values, any scalar value passed will not cause a TypeError to be thrown! Instead, the value will be interpreted into its boolean equivalent. If you subsequently return this value, the data type will be changed to boolean.
To test this, call the someBoolHint() function defined previously, and pass any scalar value in as an argument. The var_dump() method reveals that the data type is always boolean:
try {
// positive results
$b = someBooleanHint(TRUE);
$i = someBooleanHint(11);
$f = someBooleanHint(22.22);
$s = someBooleanHint('X');
var_dump($b, $i, $f, $s);
// negative results
$b = someBooleanHint(FALSE);
$i = someBooleanHint(0);
$f = someBooleanHint(0.0);
$s = someBooleanHint('');
var_dump($b, $i, $f, $s);
} catch (TypeError $e) {
echo $e->getMessage();
}If you now try the same function call, but pass in a non-scalar data type, a TypeError is thrown:
try {
$a = someBoolHint([1,2,3]);
var_dump($a);
} catch (TypeError $e) {
echo $e->getMessage();
}
try {
$o = someBoolHint(new stdClass());
var_dump($o);
} catch (TypeError $e) {
echo $e->getMessage();
}