EasyТеория3 min

Основы функций

Объявление, параметры, return types, named arguments

Объявление функций

<?php
declare(strict_types=1);

// Basic function
function greet(string $name): string
{
    return "Hello, {$name}!";
}

echo greet('Alice');  // Hello, Alice!

// Functions are case-insensitive (but use consistent case!)
echo GREET('Bob');  // Works, but bad practice

// Functions can be called before declaration (hoisting)
echo sayHi();  // Works!
function sayHi(): string { return 'Hi!'; }

// But NOT inside conditionals
if (true) {
    function conditionalFunc(): string { return 'test'; }
}
// conditionalFunc() exists only after the if block executes

Ловушка экзамена: Функции PHP объявленные на верхнем уровне "всплывают" (hoisted) — их можно вызвать до объявления. Но функции, объявленные внутри условий или других функций, доступны ТОЛЬКО после выполнения этого блока.

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

Типы параметров

<?php
declare(strict_types=1);

// Type hints
function add(int $a, int $b): int
{
    return $a + $b;
}

// Nullable type
function find(int $id): ?string
{
    return $id > 0 ? 'Found' : null;
}

// Union types (PHP 8.0+)
function format(int|float $number): string
{
    return number_format($number, 2);
}

// Intersection types (PHP 8.1+)
function process(Countable&Iterator $data): void
{
    foreach ($data as $item) {
        echo $item;
    }
}

// Default values
function connect(string $host = 'localhost', int $port = 3306): void
{
    echo "Connecting to {$host}:{$port}";
}
connect();              // localhost:3306
connect('db.prod');     // db.prod:3306
connect('db.prod', 5432); // db.prod:5432

// Variadic parameters
function sum(int ...$numbers): int
{
    return array_sum($numbers);
}
echo sum(1, 2, 3, 4, 5);  // 15

Named Arguments (PHP 8.0+)

<?php
declare(strict_types=1);

function createUser(
    string $name,
    string $email,
    int $age = 0,
    bool $active = true,
    string $role = 'user',
): void {
    echo "Created: {$name} ({$email}), age: {$age}, role: {$role}";
}

// Positional arguments
createUser('Alice', '[email protected]', 25, true, 'admin');

// Named arguments — can skip defaults, any order
createUser(name: 'Alice', email: '[email protected]', role: 'admin');

// Mixed: positional first, then named
createUser('Alice', '[email protected]', role: 'admin');

// Spread with named arguments
$args = ['name' => 'Bob', 'email' => '[email protected]', 'role' => 'editor'];
createUser(...$args);

// Named arguments in built-in functions
$arr = [3, 1, 2];
sort(array: $arr, flags: SORT_NUMERIC);

echo implode(separator: ', ', array: ['a', 'b', 'c']);

Ловушка экзамена: Именованные аргументы НЕЛЬЗЯ использовать ПЕРЕД позиционными: createUser(name: 'Alice', '[email protected]') — ошибка. Позиционные всегда первые, затем именованные в любом порядке.

Возвращаемые типы

<?php
declare(strict_types=1);

// Return type declaration
function divide(float $a, float $b): float
{
    if ($b == 0.0) {
        throw new DivisionByZeroError('Division by zero');
    }
    return $a / $b;
}

// void — function MUST NOT return a value
function logMessage(string $msg): void
{
    error_log($msg);
    // return;  // OK (bare return)
    // return null;  // ERROR! void cannot return null
}

// never — function never returns (PHP 8.1+)
function halt(string $message): never
{
    throw new RuntimeException($message);
    // OR exit($message);
    // Function must ALWAYS throw or exit
}

// mixed — any type (PHP 8.0+)
function getValue(string $key): mixed
{
    return $_GET[$key] ?? null;
}

// Static return type (PHP 8.0+)
class Builder
{
    public function setName(string $name): static
    {
        $this->name = $name;
        return $this;  // Returns instance of current class
    }
}

Запомни: void означает "функция не возвращает значение". never означает "функция НИКОГДА не завершается нормально" (throw или exit). void функция может иметь return; без значения, never — не может иметь return вообще.

Функции как значения

<?php
declare(strict_types=1);

// Functions as variables
$fn = 'strtoupper';
echo $fn('hello');  // HELLO

// Check if callable
var_dump(is_callable('strtoupper'));  // true
var_dump(is_callable('nonexistent')); // false

// function_exists
var_dump(function_exists('array_map'));  // true

// Variable functions
function add(int $a, int $b): int { return $a + $b; }
function subtract(int $a, int $b): int { return $a - $b; }

$operation = 'add';
echo $operation(5, 3);  // 8

$operation = 'subtract';
echo $operation(5, 3);  // 2

// First-class callable syntax (PHP 8.1+)
$fn = strlen(...);
echo $fn('Hello');  // 5

$fn = strtoupper(...);
echo $fn('hello');  // HELLO

$arr = [3, 1, 2];
usort($arr, strcmp(...));  // Not ideal, just example

Вопросы с экзамена ZCE

Проверь себя

5 из 20

Что выведет следующий код? ```php function a($a) { echo $a . "&"; } function b($a) { echo "-" . $a; } $a = "!"; $b = &$a; echo a(b($b)); ```

В чём разница `void` и `never`?

Какая инструкция вернёт ТРЕТИЙ параметр, переданный функции?

Какие из утверждений о функциях PHP являются ЛОЖНЫМИ?

Можно ли вызвать функцию до её объявления?