<? phpukraine ДОКУМЕНТАЦІЯ
⌕Пошук по платформі
Документація українською

Переклад офіційної документації українською. Кожен розділ показує стан готовності: недоперекладене позначене відкрито, а не приховане.

МОВА · ПЕРЕКЛАДЕНО оновлено 18 вересня 2026

Функції · PHP Manual

Функції, визначені користувачем

Функцію визначають за допомогою ключового слова function, імені, списку параметрів (він може бути порожнім), розділених комами (,) і взятих у круглі дужки, а далі йде тіло функції у фігурних дужках, як тут:

Оголошення нової функції з іменем foo

<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
    echo "Example function.\n";
    return $retval;
}

Примітка. Починаючи з PHP 8.0.0, список параметрів може мати кому в кінці:

<?php
function foo($arg_1, $arg_2,) { }

У тілі функції може бути будь-який коректний PHP-код, зокрема інші функції та означення класів.

Імена функцій підпорядковані тим самим правилам, що й інші мітки в PHP. Коректне ім'я функції починається з літери або підкреслення, за якими йде будь-яка кількість літер, цифр чи підкреслень. Регулярним виразом це записується так: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$.

Порада. Дивіться також Userland Naming Guide.

Функції не обов'язково визначати до того, як на них посилаються, за винятком випадку, коли функція визначається умовно, як у двох прикладах нижче.

Коли функція визначається умовно, як показано у двох прикладах, її означення має бути опрацьоване до виклику.

Умовно визначені функції

<?php
$makefoo = true;

/* Тут ми ще не можемо викликати foo(),
   бо її поки не існує,
   але можемо викликати bar() */
if (function_exists('foo')) {
    foo();
} else {
    echo "Function foo does not exist (yet).\n";
}

bar();

if ($makefoo) {
  function foo()
  {
    echo "I don't exist until program execution reaches me.\n";
  }
}

/* Тепер можна безпечно викликати foo(),
   бо $makefoo дорівнював true */

if ($makefoo) foo();

function bar() 
{
  echo "I exist immediately upon program start.\n";
}

Функції всередині функцій

<?php
function foo() 
{
  function bar() 
  {
    echo "I don't exist until foo() is called.\n";
  }
}

/* Ми ще не можемо викликати bar(),
   бо її не існує. */
if (function_exists('bar')) {
    bar();
}

foo();

/* Тепер bar() можна викликати:
   виконання foo() зробило її
   доступною. */

bar();

Усі функції та класи в PHP мають глобальну область видимості - їх можна викликати поза функцією, навіть якщо їх було визначено всередині неї, і навпаки.

PHP не підтримує перевантаження функцій, а також не дозволяє скасувати означення чи перевизначити вже оголошену функцію.

Примітка. Імена функцій нечутливі до регістру для ASCII-символів від A до Z, хоча зазвичай гарним тоном є викликати функції так, як вони записані в оголошенні.

Функції підтримують і змінну кількість аргументів, і аргументи за замовчуванням. Докладніше дивіться в описі функцій func_num_args(), func_get_arg() та func_get_args().

У PHP можна викликати рекурсивні функції.

Рекурсивні функції

<?php
function recursion($a)
{
    if ($a < 20) {
        echo "$a\n";
        recursion($a + 1);
    }
}

recursion(17);

Примітка. Рекурсивні виклики функцій або методів із понад 100-200 рівнями рекурсії можуть переповнити стек і призвести до аварійного завершення поточного скрипта. Зокрема, нескінченна рекурсія вважається помилкою програмування.

Параметри та аргументи функції

Параметри функції оголошуються в її сигнатурі. Інформацію можна передати у функцію через список аргументів - розділений комами список виразів. Аргументи обчислюються зліва направо, і результат присвоюється параметрам функції ще до того, як функцію буде фактично викликано (жадібне обчислення).

PHP підтримує передавання аргументів за значенням (це поведінка за замовчуванням), передавання за посиланням та значення аргументів за замовчуванням. Також підтримуються списки аргументів змінної довжини та іменовані аргументи.

Примітка. Починаючи з PHP 7.3.0, у списку аргументів виклику функції може бути кома в кінці:

<?php
$v = foo(
    $arg_1,
    $arg_2,
);

Починаючи з PHP 8.0.0, список параметрів функції може містити кому в кінці, яку буде проігноровано. Це зручно, коли список параметрів довгий або містить довгі імена змінних і параметри хочеться перелічити вертикально.

Список параметрів функції з комою в кінці

<?php
function takes_many_args(
    $first_arg,
    $second_arg,
    $a_very_long_argument_name,
    $arg_with_default = 5,
    $again = 'a default string', // Ця кома в кінці не дозволялася до 8.0.0.
)
{
    // ...
}

Передавання аргументів за посиланням

За замовчуванням аргументи функції передаються за значенням (тому зміна значення аргументу всередині функції не змінює його за її межами). Щоб функція могла змінювати свої аргументи, їх треба передавати за посиланням.

Щоб аргумент завжди передавався за посиланням, поставте амперсанд (&) перед іменем параметра в означенні функції:

Передавання аргументів функції за посиланням

<?php
function add_some_extra(&$string)
{
    $string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str;    // виводить 'This is a string, and something extra.'

Передавати константний вираз як аргумент для параметра, який очікує передавання за посиланням, - помилка.

Значення параметрів за замовчуванням

Функція може задавати значення параметрів за замовчуванням синтаксисом, схожим на присвоєння змінної. Значення за замовчуванням використовується лише тоді, коли аргумент для цього параметра не передано. Зверніть увагу: передавання null не призводить до підстановки значення за замовчуванням.

Використання параметрів за замовчуванням у функціях

<?php
function makecoffee($type = "cappuccino")
{
    return "Making a cup of $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("espresso");

Наведений вище приклад виведе:

Making a cup of cappuccino.
Making a cup of .
Making a cup of espresso.

Значеннями параметрів за замовчуванням можуть бути скалярні значення, масиви (array), спеціальне значення null, а починаючи з PHP 8.1.0 - об'єкти, створені синтаксисом new ClassName().

Використання нескалярних типів як значень за замовчуванням

<?php
function makecoffee($types = array("cappuccino"), $coffeeMaker = NULL)
{
    $device = is_null($coffeeMaker) ? "hands" : $coffeeMaker;
    return "Making a cup of ".join(", ", $types)." with $device.\n";
}
echo makecoffee();
echo makecoffee(array("cappuccino", "lavazza"), "teapot");

Наведений вище приклад виведе:

Making a cup of cappuccino with hands.
Making a cup of cappuccino, lavazza with teapot.

Використання об'єктів як значень за замовчуванням (починаючи з PHP 8.1.0)

<?php
class DefaultCoffeeMaker {
    public function brew() {
        return "Making coffee.\n";
    }
}
class FancyCoffeeMaker {
    public function brew() {
        return "Crafting a beautiful coffee just for you.\n";
    }
}
function makecoffee($coffeeMaker = new DefaultCoffeeMaker)
{
    return $coffeeMaker->brew();
}
echo makecoffee();
echo makecoffee(new FancyCoffeeMaker);

Наведений вище приклад виведе:

Making coffee.
Crafting a beautiful coffee just for you.

Значення за замовчуванням має бути константним виразом, а не (наприклад) змінною, членом класу чи викликом функції.

Зверніть увагу, що будь-які необов'язкові параметри слід вказувати після обов'язкових, інакше їх не можна буде пропустити у викликах. Розгляньте такий приклад:

Неправильне використання параметрів функції за замовчуванням

<?php
function makeyogurt($container = "bowl", $flavour)
{
    return "Making a $container of $flavour yogurt.\n";
}

echo makeyogurt("raspberry"); // "raspberry" потрапляє в $container, а не в $flavour

Наведений вище приклад виведе:

Deprecated: makeyogurt(): Optional parameter $container declared before required parameter $flavour is implicitly treated as a required parameter in script on line 2

Fatal error: Uncaught ArgumentCountError: Too few arguments to function makeyogurt(), 1 passed in script on line 7 and exactly 2 expected in script:2
Stack trace:
#0 script(7): makeyogurt('raspberry')
#1 {main}
  thrown in script on line 2

Тепер порівняйте наведене вище з таким:

Правильне використання параметрів функції за замовчуванням

<?php
function makeyogurt($flavour, $container = "bowl")
{
    return "Making a $container of $flavour yogurt.\n";
}

echo makeyogurt("raspberry"); // "raspberry" потрапляє в $flavour

Наведений вище приклад виведе:

Making a bowl of raspberry yogurt.

Починаючи з PHP 8.0.0, іменовані аргументи дозволяють пропускати кілька необов'язкових параметрів.

Правильне використання параметрів функції за замовчуванням

<?php
function makeyogurt($container = "bowl", $flavour = "raspberry", $style = "Greek")
{
    return "Making a $container of $flavour $style yogurt.\n";
}

echo makeyogurt(style: "natural");

Наведений вище приклад виведе:

Making a bowl of raspberry natural yogurt.

Починаючи з PHP 8.0.0, оголошення обов'язкових параметрів після необов'язкових є застарілим. Зазвичай це виправляється видаленням значення за замовчуванням, бо воно однаково ніколи не використається. Один виняток із цього правила - параметри вигляду Type $param = null, де значення за замовчуванням null робить тип неявно nullable. Таке використання є застарілим із PHP 8.4.0, натомість слід явно вказувати nullable-тип.

Оголошення необов'язкових параметрів після обов'язкових

<?php
function foo($a = [], $b) {}     // Значення за замовчуванням не використовується; застаріле з PHP 8.0.0
function foo($a, $b) {}          // Функціонально еквівалентно, без повідомлення про застарілість

function bar(A $a = null, $b) {} // Починаючи з PHP 8.1.0, $a є неявно обов'язковим
                                 // (бо стоїть перед обов'язковим параметром),
                                 // але неявно nullable (застаріле з PHP 8.4.0),
                                 // бо значення параметра за замовчуванням - null
function bar(?A $a, $b) {}       // Рекомендований варіант

Примітка. Починаючи з PHP 7.1.0, пропуск параметра, який не має значення за замовчуванням, спричиняє ArgumentCountError; у попередніх версіях це було попередження (Warning).

Примітка. Параметри, які очікують аргумент за посиланням, можуть мати значення за замовчуванням.

Списки аргументів змінної довжини

PHP підтримує списки аргументів змінної довжини у функціях, визначених користувачем, за допомогою токена ....

Список параметрів може містити токен ..., який позначає, що функція приймає змінну кількість аргументів. Аргументи будуть передані у відповідну змінну як масив (array):

Використання ... для доступу до змінних аргументів

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);

Наведений вище приклад виведе:

10

Токен ... можна також використовувати під час виклику функцій, щоб розпакувати масив (array) чи змінну або літерал типу Traversable у список аргументів:

Використання ... для передавання аргументів

<?php
function add($a, $b) {
    return $a + $b;
}

echo add(...[1, 2])."\n";

$a = [1, 2];
echo add(...$a);

Наведений вище приклад виведе:

3
3

Перед токеном ... можна вказати звичайні позиційні параметри. У цьому разі в масив, створений токеном ..., потраплять лише ті кінцеві аргументи, які не відповідають жодному позиційному параметру.

Перед токеном ... також можна додати оголошення типу. Якщо воно є, то всі аргументи, захоплені ..., мають відповідати типу цього параметра.

Змінні аргументи з оголошеним типом

<?php
function total_intervals($unit, DateInterval ...$intervals) {
    $time = 0;
    foreach ($intervals as $interval) {
        $time += $interval->$unit;
    }
    return $time;
}

$a = new DateInterval('P1D');
$b = new DateInterval('P2D');
echo total_intervals('d', $a, $b).' days';

// Це завершиться помилкою, бо null не є об'єктом DateInterval.
echo total_intervals('d', null);

Наведений вище приклад виведе:

3 days
Fatal error: Uncaught TypeError: total_intervals(): Argument #2 must be of type DateInterval, null given, called in script on line 15 and defined in script:2
Stack trace:
#0 script(15): total_intervals('d', NULL)
#1 {main}
  thrown in script on line 2

Нарешті, змінні аргументи можна передавати також за посиланням, поставивши перед ... амперсанд (&).

Іменовані аргументи

PHP 8.0.0 запровадив іменовані аргументи як розширення наявних позиційних параметрів. Іменовані аргументи дозволяють передавати аргументи у функцію за іменем параметра, а не за його позицією. Завдяки цьому призначення аргументу стає самодокументованим, порядок аргументів перестає мати значення, а значення за замовчуванням можна пропускати довільно.

Іменований аргумент передається так: перед значенням ставиться ім'я параметра, після якого йде двокрапка. Використовувати зарезервовані ключові слова як імена параметрів дозволено. Ім'я параметра має бути ідентифікатором, задавати його динамічно не можна.

Синтаксис іменованих аргументів

<?php
myFunction(paramName: $value);
array_foobar(array: $value);

// НЕ підтримується.
function_name($variableStoringParamName: $value);

Позиційні аргументи проти іменованих

<?php
// З позиційними аргументами:
array_fill(0, 100, 50);

// З іменованими аргументами:
array_fill(start_index: 0, count: 100, value: 50);

Порядок, у якому передаються іменовані аргументи, значення не має.

Той самий приклад з іншим порядком параметрів

<?php
array_fill(value: 50, count: 100, start_index: 0);

Іменовані аргументи можна поєднувати з позиційними. У цьому разі іменовані мають іти після позиційних. Також можна вказати лише частину необов'язкових аргументів функції, незалежно від їхнього порядку.

Поєднання іменованих аргументів із позиційними

<?php
htmlspecialchars($string, double_encode: false);
// Те саме, що
htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8', false);

Передавання аргументу для того самого іменованого параметра кілька разів спричиняє виняток Error.

Помилка при передаванні аргументу для того самого іменованого параметра кілька разів

<?php
function foo($param) { ... }

foo(param: 1, param: 2);
// Error: Named parameter $param overwrites previous argument

foo(1, param: 2);
// Error: Named parameter $param overwrites previous argument

Починаючи з PHP 8.1.0, іменовані аргументи можна використовувати після розпакування аргументів. Іменований аргумент не повинен перезаписувати вже розпакований аргумент.

Використання іменованих аргументів після розпакування

<?php
function foo($a, $b, $c = 3, $d = 4) {
  return $a + $b + $c + $d;
}

var_dump(foo(...[1, 2], d: 40)); // 46
var_dump(foo(...['b' => 2, 'a' => 1], d: 40)); // 46

var_dump(foo(...[1, 2], b: 20)); // Fatal error. Named parameter $b overwrites previous argument

Повернення значень

Значення повертаються за допомогою необов'язкової інструкції return. Повернути можна значення будь-якого типу, зокрема масиви та об'єкти. Це негайно завершує виконання функції й передає керування назад у рядок, з якого її було викликано. Докладніше дивіться return.

Примітка. Якщо return пропущено, буде повернуто значення null.

Використання return

Використання return

<?php
function square($num)
{
    return $num * $num;
}
echo square(4);   // виводить '16'.

Функція не може повернути кілька значень, але схожого результату можна досягти, повернувши масив.

Повернення масиву для отримання кількох значень

<?php
function small_numbers()
{
    return [0, 1, 2];
}
// Деструктуризація масиву збере кожен його елемент окремо
[$zero, $one, $two] = small_numbers();
var_dump($zero, $one, $two);

// До 7.1.0 єдиною еквівалентною альтернативою була конструкція list()
list($zero, $one, $two) = small_numbers();

Щоб повернути з функції посилання, використовуйте оператор посилання & і в оголошенні функції, і під час присвоєння поверненого значення змінній:

Повернення посилання з функції

<?php
function &returns_reference()
{
    return $someref;
}

$newref =& returns_reference();

Докладніше про посилання дивіться в розділі Пояснення посилань.

Змінні функції

PHP підтримує концепцію змінних функцій. Це означає, що коли до імені змінної додано круглі дужки, PHP шукатиме функцію з таким іменем, як значення цієї змінної, і спробує її виконати. Серед іншого це можна використовувати для реалізації колбеків, таблиць функцій тощо.

Змінні функції не працюють із мовними конструкціями на кшталт echo, print, unset(), isset(), empty(), include, require і подібними. Щоб скористатися будь-якою з цих конструкцій як змінною функцією, застосовуйте функції-обгортки.

Приклад змінної функції

<?php
function foo() {
    echo "In foo()\n";
}

function bar($arg = '')
{
    echo "In bar(); argument was '$arg'.\n";
}

// Це функція-обгортка навколо echo
function echoit($string)
{
    echo $string;
}

$func = 'foo';
$func();        // Це викликає foo()

$func = 'bar';
$func('test');  // Це викликає bar()

$func = 'echoit';
$func('test');  // Це викликає echoit()

Синтаксисом змінних функцій можна також викликати методи об'єктів.

Приклад змінного методу

<?php
class Foo
{
    function Variable()
    {
        $name = 'Bar';
        $this->$name(); // Це викликає метод Bar()
    }
    
    function Bar()
    {
        echo "This is Bar";
    }
}

$foo = new Foo();
$funcname = "Variable";
$foo->$funcname();  // Це викликає $foo->Variable()

Під час виклику статичних методів виклик функції має вищий пріоритет, ніж оператор статичної властивості.

Приклад змінного методу зі статичними властивостями

<?php
class Foo
{
    static $variable = 'static property';
    static function Variable()
    {
        echo "Method Variable called\n";
    }
}

echo Foo::$variable ."\n"; // Це виводить 'static property'. Змінна $variable у цій області видимості не потрібна.
$variable = "Variable";
Foo::$variable();  // Це викликає $foo->Variable(), читаючи $variable у цій області видимості.

Наведений вище приклад виведе:

static property
Method Variable called

Складені callable-значення

<?php
class Foo
{
    static function bar()
    {
        echo "bar\n";
    }
    function baz()
    {
        echo "baz\n";
    }
}

$func = array("Foo", "bar");
$func(); // виводить "bar"
$func = array(new Foo, "baz");
$func(); // виводить "baz"
$func = "Foo::bar";
$func(); // виводить "bar"

Дивіться також

Внутрішні (вбудовані) функції

PHP постачається зі стандартним набором багатьох функцій і конструкцій. Є також функції, які потребують скомпільованих у PHP окремих розширень, інакше з'являться фатальні помилки «undefined function». Наприклад, щоб користуватися функціями для роботи із зображеннями, як-от imagecreatetruecolor(), PHP має бути скомпільований із підтримкою GD. А щоб скористатися mysqli_connect(), потрібна підтримка MySQLi. Є багато базових функцій, які входять до кожної версії PHP, наприклад функції для роботи з рядками і змінними. Виклик phpinfo() або get_loaded_extensions() покаже, які розширення завантажені в PHP. Зауважте також, що багато розширень увімкнено за замовчуванням, а сам посібник PHP поділено за розширеннями. Про те, як налаштувати PHP, дивіться розділи конфігурація, встановлення та розділи про окремі розширення.

Як читати й розуміти прототип функції, пояснено в розділі посібника як читати означення функції. Важливо усвідомлювати, що саме функція повертає і чи працює вона безпосередньо з переданим значенням. Наприклад, str_replace() повертає змінений рядок, тоді як usort() працює із самою переданою змінною. Кожна сторінка посібника також містить конкретні відомості про функцію: інформацію про параметри, зміни в поведінці, значення, що повертаються в разі успіху й невдачі, та дані про доступність. Знання цих важливих (хоч часто й малопомітних) відмінностей є вирішальним для написання коректного PHP-коду.

Примітка. Якщо передані функції параметри не такі, як вона очікує, наприклад передано масив (array) там, де очікується рядок (string), значення, яке повертає функція, є невизначеним. Найімовірніше, вона поверне null, але це лише домовленість, і покладатися на неї не можна. Починаючи з PHP 8.0.0, у такому разі має викидатися виняток TypeError.

Примітка. У режимі приведення типів скалярні типи вбудованих функцій за замовчуванням є nullable. Починаючи з PHP 8.1.0, передавання null у параметр внутрішньої функції, не оголошений як nullable, не рекомендується і спричиняє повідомлення про застарілість у режимі приведення типів - для узгодження з поведінкою функцій, визначених користувачем, де скалярні типи потрібно явно позначати як nullable.

Наприклад, функція strlen() очікує, що параметр $string буде не-nullable рядком (string). З історичних причин PHP дозволяє передавати null для цього параметра в режимі приведення типів, і параметр неявно приводиться до типу string, даючи значення "". Натомість у строгому режимі буде згенеровано TypeError.

<?php
var_dump(strlen(null));
// "Deprecated: Passing null to parameter #1 ($string) of type string is deprecated" починаючи з PHP 8.1.0
// int(0)

var_dump(str_contains("foobar", null));
// "Deprecated: Passing null to parameter #2 ($needle) of type string is deprecated" починаючи з PHP 8.1.0
// bool(true)

Дивіться також

Анонімні функції

Анонімні функції, відомі також як closures (замикання), дозволяють створювати функції без заданого імені. Найчастіше вони стають у пригоді як значення параметрів типу callable, але мають і багато інших застосувань.

Анонімні функції реалізовано за допомогою класу Closure.

Приклад анонімної функції

<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
    return strtoupper($match[1]);
}, 'hello-world');
// виводить helloWorld

Замикання можна також використовувати як значення змінних; PHP автоматично перетворює такі вирази на екземпляри внутрішнього класу Closure. Присвоєння замикання змінній має той самий синтаксис, що й будь-яке інше присвоєння, включно з крапкою з комою в кінці:

Приклад присвоєння анонімної функції змінній

<?php
$greet = function($name) {
    printf("Hello %s\r\n", $name);
};

$greet('World');
$greet('PHP');

Замикання можуть також успадковувати змінні з батьківської області видимості. Такі змінні треба передати мовній конструкції use. Починаючи з PHP 7.1, серед них не може бути суперглобальних змінних, $this або змінних з такими самими іменами, як у параметрів. Оголошення типу, що повертається, ставиться після конструкції use.

Успадкування змінних із батьківської області видимості

<?php
// Змінна, визначена в батьківській області видимості
$message = 'hello';

// $message не успадковується й не визначена
// через відсутність конструкції "use"
$example = function () {
    var_dump($message);
};
$example();

// $message успадковується з батьківської області видимості
// завдяки конструкції "use"
$example = function () use ($message) {
    var_dump($message);
};
$example();

// Значення успадкованої змінної - те, яке було на момент
// визначення функції, а не її виклику
$message = 'world';
$example();

// Скидаємо $message
$message = 'hello';

// Успадкування за посиланням: зміна, зроблена в батьківській області
// видимості після визначення замикання, видима всередині нього
$example = function () use (&$message) {
    var_dump($message);
};
$example();

$message = 'world';
$example();

// Замикання можуть також приймати звичайні аргументи
$example = function ($arg) use ($message) {
    var_dump($arg . ' ' . $message);
};
$example("hello");

// Замикання можуть повертати значення, як і будь-яка інша функція;
// оголошення типу, що повертається, іде після конструкції use
$example = function () use ($message): array {
    return ["hello", $message];
};
var_dump($example());

Наведений вище приклад виведе:

Warning: Undefined variable $message in script on line 8
NULL
string(5) "hello"
string(5) "hello"
string(5) "hello"
string(5) "world"
string(11) "hello world"
array(2) {
  [0]=>
  string(5) "hello"
  [1]=>
  string(5) "world"
}

Починаючи з PHP 8.0.0, список успадкованих з області видимості змінних може містити кому в кінці, яку буде проігноровано.

Успадкування змінних з батьківської області видимості - не те саме, що використання глобальних змінних. Глобальні змінні існують у глобальній області видимості, яка однакова незалежно від того, яка функція виконується. Батьківська область видимості замикання - це функція, у якій замикання було оголошено (не обов'язково та, з якої його викликали). Дивіться такий приклад:

Замикання й області видимості

<?php
// Простий кошик покупок, який містить список доданих товарів
// і кількість кожного з них. Має метод, що обчислює
// загальну вартість товарів у кошику, використовуючи
// замикання як колбек.
class Cart
{
    const PRICE_BUTTER  = 1.00;
    const PRICE_MILK    = 3.00;
    const PRICE_EGGS    = 6.95;

    protected $products = array();
    
    public function add($product, $quantity)
    {
        $this->products[$product] = $quantity;
    }
    
    public function getQuantity($product)
    {
        return isset($this->products[$product]) ? $this->products[$product] :
               FALSE;
    }
    
    public function getTotal($tax)
    {
        $total = 0.00;
        
        $callback =
            function ($quantity, $product) use ($tax, &$total)
            {
                $pricePerItem = constant(__CLASS__ . "::PRICE_" .
                    strtoupper($product));
                $total += ($pricePerItem * $quantity) * ($tax + 1.0);
            };
        
        array_walk($this->products, $callback);
        return round($total, 2);
    }
}

$my_cart = new Cart;

// Додаємо кілька товарів у кошик
$my_cart->add('butter', 1);
$my_cart->add('milk', 3);
$my_cart->add('eggs', 6);

// Виводимо суму з податком з продажу 5%.
print $my_cart->getTotal(0.05) . "\n";
// Результат - 54.29

Автоматична прив'язка $this

<?php
class Test
{
    public function testing()
    {
        return function() {
            var_dump($this);
        };
    }
}

$object = new Test;
$function = $object->testing();
$function();

Наведений вище приклад виведе:

object(Test)#1 (0) {
}

Коли анонімну функцію оголошено в контексті класу, поточний клас автоматично прив'язується до неї, тому $this доступний в області видимості функції. Якщо така автоматична прив'язка поточного класу небажана, натомість можна скористатися статичними анонімними функціями.

Статичні анонімні функції

Анонімні функції можна оголошувати статичними. Це не дає прив'язати до них поточний клас. Об'єкти до них також не можна прив'язати під час виконання.

Спроба використати $this всередині статичної анонімної функції

<?php
class Foo
{
    function __construct()
    {
        $func = static function() {
            var_dump($this);
        };
        $func();
    }
};
new Foo();

Наведений вище приклад виведе:

Fatal error: Uncaught Error: Using $this when not in object context in script:7
Stack trace:
#0 script(9): Foo::{closure:Foo::__construct():6}()
#1 script(12): Foo->__construct()
#2 {main}
  thrown in script on line 7

Спроба прив'язати об'єкт до статичної анонімної функції

<?php
$func = static function() {
    // тіло функції
};
$func = $func->bindTo(new stdClass);
$func();

Наведений вище приклад виведе:

Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in script on line 5

Fatal error: Uncaught Error: Value of type null is not callable in script:6
Stack trace:
#0 {main}
  thrown in script on line 6

Журнал змін

Версія Опис
8.5.0 Замикання тепер можна використовувати в константних виразах (наприклад, значення властивостей за замовчуванням, параметри атрибутів, константи).
8.3.0 Замикання, створені з магічних методів, можуть приймати іменовані параметри.
7.1.0 Анонімні функції не можуть замикати суперглобальні змінні, $this чи будь-яку змінну з таким самим іменем, як у параметра.

Примітки

Примітка. Усередині замикання можна використовувати func_num_args(), func_get_arg() та func_get_args().

Стрілкові функції

Стрілкові функції з'явилися в PHP 7.4 як лаконічніший синтаксис для анонімних функцій.

І анонімні, і стрілкові функції реалізовано за допомогою класу Closure.

Базова форма стрілкової функції - fn (argument_list) => expr.

Стрілкові функції підтримують ті самі можливості, що й анонімні функції, за винятком того, що використання змінних із батьківської області видимості завжди автоматичне.

Коли змінну, використану у виразі, визначено в батьківській області видимості, вона неявно захоплюється за значенням. У наступному прикладі функції $fn1 і $fn2 поводяться однаково.

Стрілкові функції захоплюють змінні за значенням автоматично

<?php
$y = 1;

$fn1 = fn($x) => $x + $y;
// еквівалентно використанню $y за значенням:
$fn2 = function ($x) use ($y) {
    return $x + $y;
};

var_export($fn1(3));

Наведений вище приклад виведе:

4

Це працює і для вкладених стрілкових функцій:

Стрілкові функції захоплюють змінні за значенням автоматично навіть при вкладенні

<?php
$z = 1;
$fn = fn($x) => fn($y) => $x * $y + $z;
// Виводить 51
var_export($fn(5)(10));

Як і в анонімних функцій, синтаксис стрілкових функцій дозволяє довільні сигнатури, зокрема типи параметрів і типи, що повертаються, значення за замовчуванням, variadic-параметри, а також передавання й повернення за посиланням. Усе наведене нижче є коректними прикладами стрілкових функцій:

Приклади стрілкових функцій

<?php
fn(array $x) => $x;
static fn($x): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;

Стрілкові функції використовують прив'язку змінних за значенням. Це приблизно еквівалентно виконанню use($x) для кожної змінної $x, використаної всередині стрілкової функції. Прив'язка за значенням означає, що змінити будь-які значення із зовнішньої області видимості неможливо. Для прив'язки за посиланням натомість можна використовувати анонімні функції.

Стрілкові функції не можуть змінювати значення із зовнішньої області видимості

<?php
$x = 1;
$fn = fn() => $x++; // Не має жодного ефекту
$fn();
var_export($x);  // Виводить 1

Журнал змін

Версія Опис
7.4.0 З'явилися стрілкові функції.

Примітки

Примітка. Усередині стрілкової функції можна використовувати func_num_args(), func_get_arg() та func_get_args().

Синтаксис first class callable зʼявився в PHP 8.1.0 як спосіб створювати анонімні функції з callable. Він заміщає наявний синтаксис callable через рядки й масиви. Перевага цього синтаксису в тому, що він доступний для статичного аналізу і використовує область видимості в тій точці, де callable отримано.

Синтаксис CallableExpr(...) створює обʼєкт Closure з callable. CallableExpr приймає будь-який вираз, який у граматиці PHP можна викликати напряму:

Приклад: простий синтаксис first class callable

<?php
class Foo {
   public function method() {}
   public static function staticmethod() {}
   public function __invoke() {}
}

$obj = new Foo();
$classStr = 'Foo';
$methodStr = 'method';
$staticmethodStr = 'staticmethod';


$f1 = strlen(...);
$f2 = $obj(...);  // обʼєкт, який можна викликати
$f3 = $obj->method(...);
$f4 = $obj->$methodStr(...);
$f5 = Foo::staticmethod(...);
$f6 = $classStr::$staticmethodStr(...);

// традиційний callable через рядок, масив
$f7 = 'strlen'(...);
$f8 = [$obj, 'method'](...);
$f9 = [Foo::class, 'staticmethod'](...);

... - частина синтаксису, а не пропуск.

CallableExpr(...) має ту саму семантику, що й Closure::fromCallable(). Тобто, на відміну від callable через рядки й масиви, CallableExpr(...) враховує область видимості в точці свого створення:

Приклад: порівняння області видимості CallableExpr(...) і традиційного callable

<?php
class Foo {
    public function getPrivateMethod() {
        return [$this, 'privateMethod'];
    }

    private function privateMethod() {
        echo __METHOD__, "\n";
    }
}

$foo = new Foo;
$privateMethod = $foo->getPrivateMethod();
$privateMethod();
// Fatal error: Call to private method Foo::privateMethod() from global scope
// Так стається тому, що виклик виконується поза Foo, і видимість перевіряється саме з цієї точки.
<?php
class Foo1 {
    public function getPrivateMethod() {
        // Використовує область видимості, де отримано callable.
        return $this->privateMethod(...); // те саме, що Closure::fromCallable([$this, 'privateMethod']);
    }

    private function privateMethod() {
        echo __METHOD__, "\n";
    }
}

$foo1 = new Foo1;
$privateMethod = $foo1->getPrivateMethod();
$privateMethod();  // Foo1::privateMethod

Створення обʼєкта таким синтаксисом (наприклад, new Foo(...)) не підтримується, бо синтаксис new Foo() не вважається викликом.

Синтаксис first-class callable не можна поєднувати з nullsafe-оператором. Обидва наведені нижче варіанти дають помилку на етапі компіляції:

<?php
$obj?->method(...);
$obj?->prop->method(...);

Журнал змін

Версія Опис
8.5.0 First-class callable тепер можна використовувати в константних виразах (наприклад, у значеннях властивостей за замовчуванням, параметрах атрибутів, константах).
Стан перекладу

Перекладаємо з офіційної документації, розділ за розділом, і не ховаємо недоперекладене. Помітили неточність у терміні чи реченні: напишіть, виправимо.

48%
Готовності
1
У роботі
15
Ще не перекладено
Глосарій термінів