Functions

A function is a reusable block of code that, given an input, performs some actions and, optionally, returns some result. You already know several predefined functions like empty, in_array, or var_dump. Those functions come with PHP so you do not have to reinvent the wheel, but you can create your own very easily. You can define functions when you identify portions of your application that have to be executed several times, or just to encapsulate some functionality.

Function declaration

Declaring a function means writing it down so it can be used later. A function has a name, takes some arguments, and has a block of code. Optionally, it can define what kind of value is to be returned. The name of the function has to follow the same rules as variable names, that is, it has to start with a letter or an underscore, and can contain any letters, numbers, or underscore. It cannot be a reserved word.

Let's see a simple example:

function addNumbers($a, $b) {
    $sum = $a + $b;
    return $sum;
}
$result = addNumbers(2, 3);

The preceding function's name is addNumbers, and it takes two arguments: $a and $b. The block of code defines a new variable $sum, which is the sum of both arguments, and then returns its content with return. In order to use this function, you just need to call it by its name while sending all the required arguments, as shown in the highlighted line.

PHP does not support overloaded functions. Overloading refers to the ability of declaring two or more functions with the same name but different arguments. As you can see, you can declare the arguments without knowing what their types are, so PHP would not be able to decide which function to use.

Another important thing to note is the variable scope. We are declaring a variable $sum inside the block of code, so once the function ends, the variable will not be accessible any more. That means that the scope of variables declared inside the function is just the function itself. Furthermore, if you had a variable $sum declared outside the function, it would not be affected at all since the function cannot access that variable unless we send it as an argument.

Function arguments

A function gets information from outside via arguments. You can define any number of arguments—including 0 (none). These arguments need at least a name so they can be used inside the function; there cannot be two arguments with the same name. When invoking the function, you need to send the arguments in the same order as declared.

A function may contain optional arguments, that is, you are not forced to provide a value for those arguments. When declaring the function, you need to provide a default value for those arguments. So, in case the user does not provide a value, the function will use the default one.

function addNumbers($a, $b, $printResult = false) {
    $sum = $a + $b;
    if ($printResult) {
        echo 'The result is ' . $sum;
    }
    return $sum;
}

$sum1 = addNumbers(1, 2);
$sum1 = addNumbers(3, 4, false);
$sum1 = addNumbers(5, 6, true); // it will print the result

This new function in the last example takes two mandatory arguments and an optional one. The default value of the optional argument is false, and it is then used normally inside the function. The function will print the result of the sum if the user provides true as the third argument, which happens only the third time that the function is invoked. For the first two, $printResult is set to false.

The arguments that the function receives are just copies of the values that the user provided. That means that if you modify these arguments inside the function, it will not affect the original values. This feature is known as sending arguments by value. Let's see an example:

function modify($a) {
    $a = 3;
}

$a = 2;
modify($a);
var_dump($a); // prints 2

We are declaring a variable $a with value 2, and then calling the modify method sending that $a. The modify method modifies the argument $a, setting its value to 3, but this does not affect the original value of $a, which remains 2 as you can see from var_dump.

If what you want is to actually change the value of the original variable used in the invocation, you need to pass the argument by reference. To do that, you add an ampersand (&) before the argument when declaring the function:

function modify(&$a) {
    $a = 3;
}

Now, on invoking the function modify, $a will always be 3.

Note

Arguments by value versus by reference

PHP allows you to do it, and in fact, some native functions of PHP use arguments by reference. Remember the array sorting functions? They did not return the sorted array, but sorted the array provided instead. But using arguments by reference is a way of confusing developers. Usually, when someone uses a function, they expect a result, and they do not want the arguments provided by them to be modified. So try to avoid it; people will be grateful!

The return statement

You can have as many return statements as you want inside your function, but PHP will exit the function as soon as it finds one. That means that if you have two consecutive return statements, the second one will never be executed. Still, having multiple return statements can be useful if they are inside conditionals. Add this function inside your functions.php file:

function loginMessage() {
    if (isset($_COOKIE['username'])) {
        return "You are " . $_COOKIE['username'];
    } else {
        return "You are not authenticated.";
    }
}

And let's use the last example in your index.php file by replacing the highlighted content (note that to save some trees, I replaced most of the code that was not changed at all with //…):

//...
<body>
    <p><?php echo loginMessage(); ?></p>
<?php if (isset($_GET['title']) && isset($_GET['author'])): ?>
//...

Additionally, you can omit the return statement if you do not want the function to return anything. In this case, the function will end once it reaches the end of the block of code.

Type hinting and return types

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!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.134.17