Chat in Telegram

Functions in PHP

04.12.2022 at 10:24
502
+1

Hi all! In this lesson, we will get acquainted with such a concept as functions in the PHP language. Functions are pretty simple things. It is a piece of code that takes certain parameters and returns some result at the output. It is possible to write a function once and then use it in different places. This way you won't need to duplicate code if something needs to be done twice, or thrice, or any number of times. In general, functions in PHP can be compared to functions in mathematics.

PHP comes with a huge number of built-in functions. This is a very strong point of this language - there is a ready-made function for almost any of your needs. Let's try some functions in practice.

For example, we need the cosine of 3.14. Easily! To do this, PHP has a function cos.

<?php

echo cos(3.14);

Result:

-0.99999873172754

There are a lot of functions for working with strings. For example, you can replace some characters in a string with others, for this there is a function str_replace. For example, let's replace all the letters "a" with "o" in the string “abracadabra”.

<?php

$string = 'abracadabra';

echo str_replace('a', 'o', $string);

Result:

obrocodobro

The documentation on the standard function library (SPL) is available on the official website - http://php.net/manual/en/funcref.php. Of course, it is impossible to remember all of them, but you need to be able to find them. And this is usually not difficult. For example, if you type in “replace characters in a php string” into google, then the output will contain a link to the official documentation, look there.

In general, googling and taking ready-made code is a good approach that saves you time. There is nothing wrong with this - most likely you will find a better solution to the problem than the one that you would write yourself. Learn from ready-made examples, and over time, remember the most common approaches for different cases. The main thing here is regular practice.

User functions: writing our first function

I think about what functions are and where to find ready-made ones, I explained. But the coolest thing is that you can define functions yourself! In general, the definition of any function looks like this:

function funcName(arg1, arg2)
{
    some actions;
    return result;
}

The function must have a name. All functions must have different names and your function name cannot be named the same as a PHP built-in function. There can be any number of arguments, including 0. A function can return something, for this, the word return is written before the result. After that, the function terminates. Or it may not return, but, for example, change its arguments, or display information on the screen. Functions are named the same as variables - camelCase. You need to name them just as meaningful - what the function does, then you need to write in the name.

Let's look at an example of creating a simple function in PHP. Let it take two numbers as input and return their sum.

<?php

function getSum($x, $y)
{
    return $x + $y;
}

Okay, the function has been written, now you can call it and look at the result of its work.

<?php

function getSum($x, $y)
{
    return $x + $y;
}

$a = 5;
$b = 10;

echo getSum($a, $b) . '<br>';
echo getSum(-3, 4);

Result:

15
1

As we can see, the function worked successfully. So, having written it only once, we can pass different arguments to it, and get different values. A function can only be used after its definition code!

Scopes

Let's now talk about function scope. Everything is really simple here, and it all boils down to the fact that variables inside the function are not accessible from the outside and are called local. After the function ends, all variables declared inside it will cease to exist. In this case, variables outside the function are called global and are not available inside the function. Thus, it is possible to use the same variable names inside the function as outside, but these will be completely different variables.

<?php

function getSum($x, $y)
{
    return $x + $y;
}

$x = 3;
$y = 5;

echo getSum($x, $y);

This code is absolutely working. Here, the variables $x and $y inside the getSum function live on their own, and the variables with the same names outside the function live separately, and they do not know anything about each other. When the function is called, the value of the passed argument will be copied into a local variable, and after the function exits, this value will be deleted. That is, here, when calling getSum, we simply copy the values 3 and 5 into the local variables $x and $y. From that moment on, inside the function, external variables cease to exist, and it only knows about its own variables.

Function parameters: passing arguments by reference and by value

So far, in the cases we are considering, the arguments to the function have been passed by value. This means that when the function was called, the value passed as an argument was simply copied into a local variable.

Passing parameters by reference

However, you can pass the argument by reference. This is done by using the & sign before the argument name.

function func(&$x)

This does not copy the value to a local variable. Another link appears for the same value, but with a different name. And now, by changing the value of this variable inside the function, we will change the original, passed value. Let's look at an example of passing a value by reference.

<?php

function plus5(&$x)
{
    $x = $x + 5;
}

$a = 3;

plus5($a);

echo $a;

Result:

8

That is, for the value of the variable $a, another name appeared inside the function - $x. Now both of these names point to the same value. And if we change the value of a variable inside the function, it will change outside as well!

And if we passed the variable to the function by value, without using the & sign, we would get a different result.

<?php

function plus5($x)
{
    $x = $x + 5;
}

$a = 3;

plus5($a);

echo $a;

Will output:

3

Here, when the function was called, the value of $a was simply copied into the local variable $x. Inside the function, we changed $x by adding the number 5 to it, and then the function was completed. The local variable $x has ceased to exist, and we have not affected the variable $a in any way.

Functions in which all arguments are passed by value are called pure. It is worth using them whenever possible, since in the absolute majority of cases, passing values by reference is not required and leads to code confusion.

Getting started with type hinting

In new versions of PHP, it became possible to specify the types of arguments in functions, including for scalar types (strings, numbers). In this case, when passing an argument to a function, the passed value will be automatically cast to the desired type. Let's rewrite our function with modern PHP features in mind.

<?php

function getSum(int $x, int $y)
{
    return $x + $y;
}

So, now when passing any values to the function, they will automatically be converted to numbers. Let's check it out - insert a call to the var_dump function inside our function, and see what happens.

<?php

function getSum(int $x, int $y)
{
    var_dump($x);
    var_dump($y);

    return $x + $y;
}

echo getSum(5, 10);

Result:

int 5
int 10
15

Quite expected, you say. After all, we passed integers to the function, and even if the arguments did not have type casting, then there would be integers in the same way. And you will be right. But let's try to pass a floating point number as one of the arguments.

<?php

function getSum(int $x, int $y)
{
    var_dump($x);
    var_dump($y);

    return $x + $y;
}

echo getSum(12.5, 10);

Result:

int 12
int 10
22

That is, at the moment when the argument came to the function, it was already of the required type. Let's try to remove the type indication from the argument:

<?php

function getSum($x, $y)
{
    var_dump($x);
    var_dump($y);

    return $x + $y;
}

echo getSum(12.5, 10);

Now the fractional number will not be reduced to an integer, and we will get a different result:

float 12.5
int 10
22.5

In this course, we will always use type hints. This helps to write more rigorous code and allows for fewer bugs. Judge for yourself - if we work with a specific type, we are more confident in how this or that code will work.

Strict types

As I said, by default, the value of the argument will be automatically cast to the specified type. However, it is possible in PHP to specify explicitly that an argument passed to a function will be of a particular type. This is done with the directive:

declare(strict_types=1);

It is specified at the beginning of the PHP file. Our code will look like this:

<?php
declare(strict_types=1);

function getSum(int $x, int $y)
{
    var_dump($x);
    var_dump($y);

    return $x + $y;
}

echo getSum(12.5, 10);

At the same time, if you run it now, an error with the TypeError type will occur.
Error passing invalid type

As written here, the first argument passed to getSum() must be of type integer, but passed with type float. This is what strict typing is in PHP. We will not use it within the framework of this course, and this functionality is not yet used in professional development in PHP. But I couldn’t help but talk about it, it’s quite possible that this could be asked during a job interview. And now we remove the line declare(strict_types=1); from our code and move on.

Functions with no arguments

As I said, a function may have no arguments at all. Such, for example, is the standard function rand() - it simply returns a random number.

Let's try it in action:

<?php

echo 'Random num: ' . rand();

Result:

Random num: 9582

Let's run the same code again:

Random num: 7324

Works. And now let's write our own function, which also takes no arguments and returns the sine of a random number:

<?php

function getSinOfRandom()
{
    return sin(rand());
}

echo 'Sine of a random number: ' . getSinOfRandom();

Result:

Sine of a random number: 0.6586666790617

Function within a function

Let's now look at what else functions allow us to do. Functions in PHP can be called inside other functions. Let's take an absolutely simple example. For example, we need to find the sum of the cosines of two numbers. Let's write a function for this:

<?php

function getSumOfCos(float $x, float $y)
{
    $cosX = cos($x);
    $cosY = cos($y);
    return $cosX + $cosY;
}

echo getSumOfCos(1.44, 2);

Here we have used the cos() function from the standard library inside our own function. Is it possible to call your own functions from your other functions? Easily!

<?php

function getSum(float $x, float $y)
{
    return $x + $y;
}

function getSumOfCos(float $x, float $y)
{
    $cosX = cos($x);
    $cosY = cos($y);
    return getSum($cosX, $cosY);
}

echo getSumOfCos(1.44, 2);

Here we defined 2 different functions, and in the second one we started using the first one. Of course, these examples are rather artificial. And you might think that using functions here is redundant. After all, you can simply replace this code with the following expression:

<?php

echo cos(1.44) + cos(2);

And you will be absolutely right. But I give such easy examples specifically to make it easier for you to understand how to write functions in general. Let's look at a more realistic example. Let's write a function that will return the larger of the two given numbers.

<?php

function getMax(int $x, int $y)
{
    if ($x > $y) {
        return $x;
    } else {
        return $y;
    }
}

$a = 5;
$b = 8;

echo 'Largest: ' . getMax($a, $b);

Result:

Largest: 8

The code of this function can be simplified, since if $x is not greater than $y, then we will return $y anyway. Therefore, you can remove the else block:

<?php

function getMax(int $x, int $y)
{
    if ($x > $y) {
        return $x;
    }

    return $y;
}

$a = 5;
$b = 8;

echo 'Largest: ' . getMax($a, $b);

The result will be the same. It happens, as I said, that as soon as return is executed in the function, the value will be immediately returned, and the function will complete its work.

Let's pass a larger number as the first argument:

...

$a = 10;
$b = 8;

echo 'Largest: ' . getMax($a, $b);

Result:

Largest: 10

The first condition was met and return $x was called. That's it, it didn't get to return $y.
The simplification lies in the fact that the fewer levels of nesting in the code, the easier it is to read and understand. See how tightly all the studied material intersects? In this case, with the topic conditions.

Recursive functions

Oh, I feel like we're having some fun. Carefully! If your brain starts to boil while reading this section, go to the next lesson, recursion can be mastered at the end of the course. Don't worry, in general, if it doesn't work out, you're not alone =)

Here we learned that it is possible to call one function inside another. However, there are situations when you need to call the same function within itself.

For example, we need to raise a number to a power. Suppose we have a specific function for this. Let's name it power. And let it take 2 arguments:

  • the number to be raised;
  • the power to which you want to raise.

That is, in order to raise the number 2 to the third power, we need to call this function as follows:

power(2, 3)

Agree that power(2, 3) is equivalent to 2 * power(2, 3 - 1). That is, we can multiply the number raised to a power by a call to this function, and at the same time reduce the power by one.

Thus, it turns out that we can call the same function with some additional operations.

We get that:

power($x, $n) = $x * power($x, $n – 1)

Then for raising 2 to the power of 3 we get:

  1. power(2, 3) = 2 * power(2, 2)
  2. power(2, 2) = 2 * power(2, 1)
  3. power(2, 1) = 2 * power(2, 0)

A number to the first power is equal to that number itself. This is where we need to stop.

Let's implement this with code:

<?php

function power(int $x, int $n)
{
    // If the degree is now zero, then return one
    if ($n === 0) {
        return 1;
    }

    // In other cases - multiply the number raised to the power of n - 1 and return it
    return $x * power($x, $n - 1);
}

echo power(2, 3);

Yes, the function will call itself. Thus, we can come to the conclusion that recursion is useful when the evaluation of a function can be reduced to its simpler call, and it to an even simpler one, and so on, until we reach some final value in the arguments (in our example - number 0). To understand how everything works step by step, you can add a call to var_dump at the beginning of the function and see what arguments are passed to it at each step.

<?php

function power(int $x, int $n)
{
    var_dump($x, $n);
    // If the degree is now zero, then return one
    if ($n === 0) {
        return 1;
    }

    // In other cases - multiply the number raised to the power of n - 1 and return it
    return $x * power($x, $n - 1);
}

echo 'Result: ' . power(2, 3);

The output will be as follows:

int 2 int 3
int 2 int 2
int 2 int 1
Result: 8

Thus, we see that the function was called three times, and we see what the values of the arguments were on each call. I hope everything is clear here. If not (and this happens quite often when studying recursion), write your questions in the comments, I will help. You can also analyze the course of the program step by step on a piece of paper - it often helps too.

Let's take another example with recursion to consolidate. For example, we will pass some number $n to the function, and it will calculate the sum of all numbers from one to this number. Let's call this function getSumOfNumbersFromZero($n).

Suppose we need to calculate the sum of all numbers from 1 to 5. Then the function call would be:

getSumOfNumbersFromZero(5);

As you might guess, this call can be represented as:

5 + getSumOfNumbersFromZero(4)

Or in general:

getSumOfNumbersFromZero($n) = $n + getSumOfNumbersFromZero($n - 1)

And so on until $n equals 1.

Let's implement this with a recursive function:

<?php

function getSumOfNumbersFromZero(int $n)
{
    // If it's 1 now, then just return 1
    if ($n == 1) {
        return 1;
    }

    // In other cases, we add the current number to the sum of all previous ones.
    return $n + getSumOfNumbersFromZero($n - 1);
}

echo 'Result: ' . getSumOfNumbersFromZero(5);

Launching...

Result: 15

That's right! Well, enough recursion, otherwise I can already hear how your brains are boiling.
I really hope you enjoyed the lesson. If so, I will be glad if you share it on social networks or tell your friends. This is the best support for the project. Thanks to those who do it. If you have any questions or comments - write about it in the comments. And now we are doing our homework, you can write your solutions in the comments, I will check them and tell you if everything is correct. Bye everyone!

loader
04.12.2022 at 10:24
502
+1
Homework
  • Write a function that will take 3 float arguments and return the minimum value.
  • Write a function that takes two reference arguments as input and multiplies each of them by 2.
  • Write a function that calculates the factorial of a number (the product of integers from one to the given one). Implement with recursion.
  • Write a function that will print integers from 0 to the value passed to the screen. And yes, here you also need to implement it using recursion (in order to get to know it better, despite the fact that the loop option is simpler).
Comments
New comment