Функции

// самый базовый вариант
function foo(){
  return 'Hello World!';
}
echo foo();
// последовательность не важна, можно сначала вызывать функцию, а ниже уже написать ее
// но если мы определяем функцию по какому то условию, то тогда порядок будет важен
if(true){
  function foo(){}; //доступна только после выполнения условия
}

Вложенные функции

foo();
bar(); // сработает только если ранее вызывалась foo() - иначе бан

function foo(){
  echo 'foo';
  
  function bar(){
    echo 'bar';
  }

}

Тип возвращаемого значения

function foo(): int {
  return 1; // при строгой типизации все должно совпадать
}

function foo(): void {
  return; // void - ничего не ждем для возврата, по умолчанию вернется NULL (в любом случае)
}

function foo(): ?int {
  return null; // ? перед типом говорит о том что кроме реальных данных допустим и null 
}

function foo(): int|float|array {
  return 1; // c 8й версии можно указывать несколько типов
}

function foo(): mixed {
  return 1; // доступно с 8й версии, работает с любыми типами
            // ?mixed использовать нельзя
}

Параметры функции

function foo($x, $y){ // $x и $y это параметры
  return $x * $y;  
}

echo foo(5, 10); // 50, 5 и 10 передаваемые аргументы функции
                 // по умолчанию аргументы передаются по значению

$x = 10; $y = 5;
function foo(&$x, $y){ $x = $x * 2 }; // передача по ссылке
echo foo($x,$y);                      // в таком случае изменится и оригинальное значение

function foo(int $x, int $y) // ожидаемые типы аргументов

function foo(int $x, ?int $y); // в данном случе $y может быть либо int либо null 
                               // а $x только int
                               
function foo(int|float $x) // c php 8 можно указывать несколько типов
function foo($x, $y = 10) // $y имеет дефолтное значение 
                          // на случай если в вызове функции нет соответствующего аргумента
                          // указывать можно только точные значения
                          // порядок важен, сначала обязательные параметры

Вариативные функции (splat operator)

function sum(...$numbers) { // $numbers - массив переданных аргументов
  return array_sum($numbers);
}

function foo($x, $y, int|float ...$other) // допустимый вариант, как и с ожиданием типов

$numbers = [1,2,3,4];
echo sum(...$numbers) // можно и с этой стороный зайти, ... оператор распаковки

Именованные аргументы

function foo($x, $y){
  return $x + $y;
}
$x = 1; $y = 2;
echo foo($x,$y); // ожидаемый вариант использования до версии 8

echo foo(y: $y, x: $x); // с php 8 можно указывать имена заранее
                        // удобно для передачи только нужных аргументов
                        // если другие имеют дефолтные значения
                        
$arr = ['x' => 1, 'y' => 2]; 
echo foo(...$arr); // сработает так же как с именоваными аргументами $x = 1 а $y = 2

[1, 'x' => 2] // так нельзя, ибо на 1й позиции и так ожидается x
              // а мы его снова определяем на 2й позиции

Переменные функции

function sum(...$numbers){
  return array_sum($numbers);
}

$x = 'sum';
echo $x(1,2,3); // поиск функции с именем sum и передача аргументов

is_callable($x); // желательно проверять, доступна ли функция

Анонимные функции

$sum = function (...$numbers){
  return array_sum($numbers);
}; // не забываем закрывать, тут уже надо

echo $sum(1,2,3);


$x = 1;
$sum = function (...$numbers) use ($x){ // use() позволяет использовать родительские переменные
                                        // копируется по значению дефолтно, но можно и ссылку
                                        // тип возврата указываем после use() :int|float
  echo $x; 
  return array_sum($numbers);
};

Функции обратного вызова — Callback

// это функция, которая передаётся в качестве аргумента другой функции
// таких функций много, в примере разберем array_map  - перебор массива с действием
$array = [1,2,3,4];

$array2 = array_map(function($element){
  return $element * 2;
},$array);

//другой вариант

$x = function($element){
  return $element * 2;
};

$array2 = array_map($x,$array);
// и еще вариант

function foo($element){
  return $element * 2;
}
$array2 = array_map('foo',$array); // c поиском существующей функции

//передача в виде аргумента

$sum = function(callable $callback, ...$numbers){
  return $callback(array_sum($numbers));
}

function foo($element){
  return $element * 2;
}

echo $sum('foo',1,2,3,4); // в результате 20

Стрелочные функции

$array = [1,2,3,4];
$y = 2;
$array2 = array_map(fn($number)=> $number * $y, $array);
// можно использовать переменные уровнем выше без использования use($y)
// но при этом со ссылками работать нельзя
// в стрелочных функциях нельзя использовать многострочные выражения