1
0
mirror of https://github.com/php/doc-pl.git synced 2026-04-24 15:28:04 +02:00
Files
Maciej Sobaczewski 756e3c51ff Sync with EN
2025-02-17 04:31:51 +01:00

1749 lines
48 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: f4f96ef8b2a95283c92ea2183fe1dedf06f3ad22 Maintainer: sobak Status: ready -->
<!-- CREDITS: cyb0org, pirate -->
<chapter xml:id="language.functions" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Funkcje</title>
<sect1 xml:id="functions.user-defined">
<title>Funkcje definiowane przez użytkownika</title>
<para>
Funkcja może być definiowana przy użyciu następującej składni:
</para>
<para>
<example>
<title>Pseudokod demonstrujący użycie funkcji</title>
<programlisting role="php">
<![CDATA[
<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
echo "Przykładowa funkcja.\n";
return $retval;
}
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Każdy poprawny kod może być użyty wewnątrz funkcji,
łącznie z definicjami innych funkcji i
<link linkend="language.oop5.basic.class">klas</link>.
</simpara>
<para>
Nazwy funkcji obowiązują identyczne zasady, jak w przypadku wszystkich innych etykiet w PHP.
Poprawna nazwa funkcji zaczyna się od litery lub podkreślnika, po których następuje
dowolna ilość liter, cyfr i podkreślników. Jako wyrażenie regularne, określone
zostałoby to następująco:
<code>'^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$</code>.
</para>
&tip.userlandnaming;
<simpara>
Funkcje nie muszą być zdefiniowane przed odniesieniem się do nich,
<emphasis>oprócz</emphasis> sytuacji, w których funkcja jest
zdefiniowana warunkowo jak w dwóch poniższych przykładach.
</simpara>
<para>
Kiedy funkcja jest zdefiniowana warunkowo, jak w dwóch poniższych przykładach,
jej definicja musi być przetworzona <emphasis>przed</emphasis>
jej wywołaniem.
</para>
<para>
<example>
<title>Funkcje zdefiniowane warunkowo</title>
<programlisting role="php">
<![CDATA[
<?php
$makefoo = true;
/* Nie możemy tu wywołać foo()
ponieważ jeszcze nie istnieje,
ale możemy wywołać bar() */
bar();
if ($makefoo) {
function foo()
{
echo "Nie istnieję, dopóki nie zostanę wykonana.\n";
}
}
/* Teraz możemy bezpiecznie wywołać foo()
ponieważ $makefoo ma wartość logiczną 1 */
if ($makefoo) foo();
function bar()
{
echo "Istnieję od początku działania skryptu.\n";
}
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title>Funkcje wewnątrz funkcji</title>
<programlisting role="php">
<![CDATA[
<?php
function foo()
{
function bar()
{
echo "Nie istnieję, dopóki foo() nie jest wywołana.\n";
}
}
/* Nie możemy tu wywołać bar()
ponieważ jeszcze nie istnieje. */
foo();
/* Teraz możemy wywołać bar(),
wykonanie foo() spodowało
że jest to już możliwe. */
bar();
?>
]]>
</programlisting>
</example>
</para>
<para>
Wszystkie funkcje i klasy w PHP mają globalny zasięg - mogą być
wykonane poza funkcją, nawet jeśli były zdefiniowane wewnątrz niej, i odwrotnie.
</para>
<simpara>
PHP nie umożliwia przeładowywania funkcji, nie jest też możliwe
usunięcie jej definicji lub redefiniowanie poprzednio określonych funkcji.
</simpara>
<note>
<simpara>
Nazwy funkcji nie rozróżniają wielkości liter dla znaków ASCII od <literal>A</literal> do <literal>Z</literal>, ale dobrym zwyczajem jest
wywoływanie ich w formie, w której zostały zdefiniowane.
</simpara>
</note>
<simpara>
Zarówno <link linkend="functions.variable-arg-list">przyjmowanie różnej ilości
argumentów</link> jak i <link linkend="functions.arguments.default">wartości domyślne
argumentów</link> są obsługiwane w funkcjach. Zobacz także opisy
funkcji
<function>func_num_args</function>,
<function>func_get_arg</function>, i
<function>func_get_args</function> aby uzyskać więcej informacji.
</simpara>
<para>
W PHP jest możliwe wykonywanie rekurencyjnych funkcji.
<example>
<title>Funkcje rekurencyjne</title>
<programlisting role="php">
<![CDATA[
<?php
function recursion($a)
{
if ($a < 20) {
echo "$a\n";
recursion($a + 1);
}
}
?>
]]>
</programlisting>
</example>
<note>
<simpara>
Rekurencyjne wywoływanie funkcji/metod z ponad 100-200 poziomami rekurencji
może spowodować przepełnienie stosu i zakończenie wykonywania skryptu. W
szczególności nieskończona rekurencja jest uznawana za błąd programistyczny.
</simpara>
</note>
</para>
</sect1>
<sect1 xml:id="functions.arguments">
<title>Argumenty i parametry funkcji</title>
<simpara>
Parametry funkcji są deklarowane w sygnaturze funkcji.
Dane mogą być przekazywane do funkcji przez listę argumentów,
która jest listą oddzielonych przecinkami wyrażeń. Argumenty są wykonywane
od prawej do lewej, a wynik jest przypisywany do parametrów
funkcji jeszcze przed faktycznym wykonaniem funkcji
(ang. <literal><emphasis>eager</emphasis> evaluation</literal>).
</simpara>
<para>
PHP obsługuje podawanie argumentów jako wartości (domyślnie), <link
linkend="functions.arguments.by-reference">przez
referencję</link>, oraz <link
linkend="functions.arguments.default">domyślne wartości
argumentów</link>. <link linkend="functions.variable-arg-list">zmienna ilość
argumentów</link> oraz <link linkend="functions.named-arguments">nazwane argumenty</link>
są także wspierane.
</para>
<para>
<example>
<title>Tablica jako argument funkcji</title>
<programlisting role="php">
<![CDATA[
<?php
function takes_array($input)
{
echo "$input[0] + $input[1] = ", $input[0]+$input[1];
}
?>
]]>
</programlisting>
</example>
</para>
<para>
Od PHP 8.0.0 lista parametrów funkcji może kończyć się przecinkiem, który zostanie
zignorowany. Jest to szczególnie przydatne w wypadkach, gdy lista parametrów jest
długa lub zawiera długie nazwy zmiennych, przez co wygodne byłoby podanie listy parametrów pionowo.
</para>
<example>
<title>Lista parametrów funkcji zakończona przecinkiem</title>
<programlisting role="php">
<![CDATA[
<?php
function przyjmuje_wiele_argumentow(
$pierwszy_argument,
$drugi_argument,
$bardzo_dluga_nazwa_zmiennej_z_argumentem,
$argument_z_wartoscia_domyslna = 5,
$znowu = 'domyślny string', // Ten przecinek na końcu nie był dozwolony przed 8.0.0.
)
{
// ...
}
?>
]]>
</programlisting>
</example>
<sect2 xml:id="functions.arguments.by-reference">
<title>Podawanie argumentów jako referencji</title>
<simpara>
Domyślnie, argumenty funkcji podawane są jako wartości (kiedy
wartość argumentu wewnątrz funkcji się zmienia, nie wpływa
to na wartość zmiennej poza funkcją). Aby pozwolić funkcji na modyfikację jej
jej argumentów, muszą one być podane przez referencję.
</simpara>
<para>
Aby argument zawsze był podawany przez referencję, poprzedź nazwę
parametru znakiem (&amp;) w definicji funkcji:
</para>
<para>
<example>
<title>Podawanie argumentów funkcji przez referencję</title>
<programlisting role="php">
<![CDATA[
<?php
function add_some_extra(&$string)
{
$string .= 'i coś ekstra.';
}
$str = 'To jest ciąg znaków, ';
add_some_extra($str);
echo $str; // wypisuje 'To jest ciąg znaków, i coś ekstra.'
?>
]]>
</programlisting>
</example>
</para>
<para>
Przekazywanie wyrażenia stałego jako argument do parametru, który powinien być przekazany przez referencję jest błędem.
</para>
</sect2>
<sect2 xml:id="functions.arguments.default">
<title>Domyślne wartości parametrów</title>
<para>
Funkcja może zdefiniować domyślne wartości dla parametrów, używając składni podobnej
do przypisania zmiennej. Domyślna wartość jest używana tylko, gdy argument parametru nie jest
określony. Należy zauważyć, że przekazanie &null; <emphasis>nie</emphasis>
ustawia domyślnej wartości.
</para>
<para>
<example>
<title>Użycie domyślnych wartości argumentów w funkcji</title>
<programlisting role="php">
<![CDATA[
<?php
function makecoffee($type = "cappuccino")
{
return "Robię filiżankę $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("espresso");
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Robię filiżankę cappuccino.
Robię filiżankę .
Robię filiżankę espresso.
]]>
</screen>
</example>
</para>
<para>
Domyślne wartości parametrów mogą być wartościami skalarnymi, tablicami (<type>array</type>),
specjalnym typem &null;, a od PHP 8.1.0 obiektami przy użyciu składni
<link linkend="language.oop5.basic.new">new ClassName()</link>.
</para>
<para>
<example>
<title>Użycie nie-skalarnych typów jako domyślnych wartości</title>
<programlisting role="php">
<![CDATA[
<?php
function makecoffee($types = array("cappuccino"), $coffeeMaker = NULL)
{
$device = is_null($coffeeMaker) ? "rąk" : $coffeeMaker;
return "Robię kubek ".join(", ", $types)." za pomocą $device.\n";
}
echo makecoffee();
echo makecoffee(array("cappuccino", "lavazza"), "czajnika");?>
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Robię kubek cappuccino za pomocą rąk.
Robię kubek cappuccino, lavazza za pomocą czajnika.
]]>
</screen>
</example>
</para>
<para>
<example>
<title>Użycie obiektów jako domyślnych wartości (od PHP 8.1.0)</title>
<programlisting role="php">
<![CDATA[
<?php
class DefaultCoffeeMaker {
public function brew() {
return "Robię kawę.\n";
}
}
class FancyCoffeeMaker {
public function brew() {
return "Parzę przepyszną kawę specjalnie dla ciebie.\n";
}
}
function makecoffee($coffeeMaker = new DefaultCoffeeMaker)
{
return $coffeeMaker->brew();
}
echo makecoffee();
echo makecoffee(new FancyCoffeeMaker);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Robię kawę.
Parzę przepyszną kawę specjalnie dla ciebie.
]]>
</screen>
</example>
</para>
<simpara>
Domyślna wartość musi być wyrażeniem stałym, a nie np.
zmienną, właściwością klasy czy wywołaniem funkcji.
</simpara>
<para>
Zauważ że parametry opcjonalne powinny być zdefiniowane po
parametrach wymaganych, w przeciwnym razie nie będzie można ich pominąć przy wywołaniu funkcji.
Spójrz na poniższy przykład:
</para>
<para>
<example>
<title>Niepoprawne użycie domyślnych parametrów funkcji</title>
<programlisting role="php">
<![CDATA[
<?php
function jogurt($pojemnik = "kubek", $smak)
{
return "Robię $container jogurtu o smaku $flavour.\n";
}
echo makeyogurt("truskawek"); // "truskawek" to $pojemnik, a nie $smak
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Fatal error: Uncaught ArgumentCountError: Too few arguments
to function jogurt(), 1 passed in example.php on line 42
]]>
</screen>
</example>
</para>
<para>
A teraz porównaj to z tym przykładem:
</para>
<para>
<example>
<title>Poprawne użycie domyślnych parametrów funkcji</title>
<programlisting role="php">
<![CDATA[
<?php
function jogurt($smak, $pojemnik = "kubek")
{
return "Robię $container jogurtu o smaku $flavour.\n";
}
echo makeyogurt("truskawek"); // "truskawek" to $smak
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Robię kubek jogurtu o smaku truskawek.
]]>
</screen>
</example>
</para>
<para>
Od PHP 8.0.0 można użyć <link linkend="functions.named-arguments">nazwanych argumentów</link>
aby pominąć opcjonalne argumenty.
</para>
<para>
<example>
<title>Poprawne użycie domyślnych parametrów funkcji</title>
<programlisting role="php">
<![CDATA[
<?php
function jogurt($smak = "truskawek", $pojemnik = "kubek", $typu = "greckiego")
{
return "Robię $container jogurtu $typu o smaku $flavour.\n";
}
echo makeyogurt(style: "natural");
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Robię kubek jogurtu naturalnego o smaku truskawek.
]]>
</screen>
</example>
</para>
<para>
Począwszy od PHP 8.0.0, deklarowanie parametrów wymaganych po opcjonalnych
jest <emphasis>zdeprecjonowane</emphasis>. Zazwyczaj można rozwiązać ten problem
przez usunięcie domyślnej wartości, ponieważ i tak nie byłaby ona nigdy użyta.
Wyjątkiem od tej reguły są parametry w postaci
<code>Typ $parametr = null</code>, gdzie domyślna wartość &null; czyni typ niejawnie
pozwalającym na null. Taki zapis jest przestarzały od PHP 8.4.0 i powinien być użyty
wprost <link linkend="language.types.declarations.nullable">typ pozwalający na null</link>.
<example>
<title>Deklarowanie parametrów opcjonalnych po wymaganych</title>
<programlisting role="php">
<![CDATA[
<?php
function foo($a = [], $b) {} // Domyślna wartość nieużywana; zdeprecjonowane od PHP 8.0.0
function foo($a, $b) {} // Zachowuje się identycznie, brak ostrzeżenia o przestarzałym zapisie
function bar(A $a = null, $b) {} // Od PHP 8.1.0, parametr $a jest niejawnie wymagany
// (gdyż został zdeklarowany przed wymaganym parametrem),
// ale też niejawnie dopuszcza null (przestarzałe od PHP 8.4.0),
// ponieważ jego domyślną wartością jest null
function bar(?A $a, $b) {} // Zalecane
?>
]]>
</programlisting>
</example>
</para>
<note>
<simpara>
Od PHP 7.1.0 pominięcie parametru, który nie ma domyślnej wartości,
rzuca <classname>ArgumentCountError</classname>; w poprzednich wersjach
powodowało błąd typu <constant>E_WARNING</constant>.
</simpara>
</note>
<note>
<simpara>
Parametry przekazywane przez referencję mogą mieć wartość domyślną.
</simpara>
</note>
</sect2>
<sect2 xml:id="functions.variable-arg-list">
<title>Podawanie zmiennej ilości argumentów</title>
<simpara>
PHP wspiera użycie różnej ilości argumentów dla
funkcji definiowanych przez użytkownika. Jest to możliwe dzięki użyciu
tokena <literal>...</literal>
</simpara>
<para>
Lista parametrów może zawierać token
<literal>...</literal>, który oznacza, że funkcja akceptuje
zmienną ilość argumentów. Argumenty zostaną przekazane do
do podanej zmiennej jako tablica, na przykład:
<example>
<title>Użycie <literal>...</literal> do zmiennej ilości argumentów</title>
<programlisting role="php">
<![CDATA[
<?php
function suma(...$liczby) {
$wynik = 0;
foreach ($liczby as $liczba) {
$wynik += $liczba;
}
return $wynik;
}
echo suma(1, 2, 3, 4);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
10
]]>
</screen>
</example>
</para>
<para>
<literal>...</literal> może być też użyte podczas wywoływania funkcji, aby rozpakować
tablicę (<type>array</type>) lub <classname>Traversable</classname>, albo literal
do listy argumentów:
<example>
<title>Użycie <literal>...</literal> do dostarczenia argumentów</title>
<programlisting role="php">
<![CDATA[
<?php
function dodaj($a, $b) {
return $a + $b;
}
echo dodaj(...[1, 2])."\n";
$a = [1, 2];
echo dodaj(...$a);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
3
3
]]>
</screen>
</example>
</para>
<para>
Możesz określić normalne parametry pozycyjne przed tokenem
<literal>...</literal>. W tym wypadku tylko końcowe argumenty,
które nie pasują do żadnego argumentu pozycyjnego, zostaną dodane do tablicy
generowanej przez <literal>...</literal>.
</para>
<para>
Jest także możliwe dodanie
<link linkend="language.types.declarations">określenia typu</link> przez tokenem
<literal>...</literal>. Jeżeli typ jest obecny, to wszystkie argumenty
pokrywane przez <literal>...</literal> muszą być obiektami wskazanej klasy.
<example>
<title>Różna ilość argumentów z określeniem typu</title>
<programlisting role="php">
<![CDATA[
<?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).' dni';
// Jest to błędem, ponieważ null nie jest obiektem klasy DateInterval.
echo total_intervals('d', null);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
3 dni
Catchable fatal error: Argument 2 passed to total_intervals() must be an instance of DateInterval, null given, called in - on line 14 and defined in - on line 2
]]>
</screen>
</example>
</para>
<para>
W końcu, możesz podać także różną ilość argumentów
<link linkend="functions.arguments.by-reference">przez referencję</link>
poprzedzając <literal>...</literal> znakiem ampersand
(<literal>&amp;</literal>).
</para>
</sect2>
<sect2 xml:id="functions.named-arguments">
<title>Nazwane argumenty</title>
<para>
PHP 8.0.0 dodało wsparcie dla nazwanych argumentów jako rozszerzenie istniejących
argumentów pozycyjnych. Nazwane argumenty pozwalają przekazanie argumentów do
funkcji na podstawie nazwy parametru, a nie jego pozycji.
To sprawia, że znaczenie argumentu jest samodokumentujące się, sprawia, że
argumenty są niezależne od ich kolejności i pozwala na pomijanie dowolnych domyślnych wartości.
</para>
<para>
Nazwane argumenty są przekazywane przez poprzedzenie wartości nazwą parametru
zakończoną dwukropkiem. Użycie słów zastrzeżonych jako nazw parametrów jest dozwolone.
Nazwa parametru musi być identyfikatorem, tworzenie jej dynamicznie
nie jest dozwolone.
</para>
<example>
<title>Składnia nazwanych argumentów</title>
<programlisting role="php">
<![CDATA[
<?php
funkcja(nazwaArgumentu: $wartosc);
array_foobar(array: $wartosc);
// NIE wspierane
function_name($zmiennaPrzechowujacaNazweArgumentu: $wartosc);
?>
]]>
</programlisting>
</example>
<example>
<title>Argumenty pozycyjne vs. argumenty nazwane</title>
<programlisting role="php">
<![CDATA[
<?php
// Z użyciem argumentów pozycyjnych:
array_fill(0, 100, 50);
// Z użyciem nazwanych argumentów:
array_fill(start_index: 0, count: 100, value: 50);
?>
]]>
</programlisting>
</example>
<para>
Kolejność, w której są przekazywane nazwane argumenty nie ma znaczenia.
</para>
<example>
<title>Ten sam przykład co wyżej, z inną kolejnością argumentów</title>
<programlisting role="php">
<![CDATA[
<?php
array_fill(value: 50, count: 100, start_index: 0);
?>
]]>
</programlisting>
</example>
<para>
Nazwane argumenty mogą być używane razem z argumentami pozycyjnymi. W tym wypadku
nazwane argumenty muszą być podane po argumentach pozycyjnych.
Jest też możliwe żeby określić tylko część opcjonalnych argumentów
funkcji, niezależnie od ich kolejności.
</para>
<example>
<title>Łączenie nazwanych argumentów z argumentami pozycyjnymi</title>
<programlisting role="php">
<![CDATA[
<?php
htmlspecialchars($string, double_encode: false);
// To samo co
htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8', false);
?>
]]>
</programlisting>
</example>
<para>
Przekazanie argumentu do tego samego nazwanego parametru wiele razy skutkuje
wyjątkiem klasy <classname>Error</classname>.
</para>
<example>
<title>Błąd przy przekazaniu argumentu do tego samego nazwanego parametru wiele razy</title>
<programlisting role="php">
<![CDATA[
<?php
function foo($parametr) { ... }
foo(parametr: 1, parametr: 2);
// Error: Named parameter $parametr overwrites previous argument
foo(1, parametr: 2);
// Error: Named parameter $parametr overwrites previous argument
?>
]]>
</programlisting>
</example>
<para>
Od PHP 8.1.0 jest możliwe użycie nazwanych argumentów po rozpakowaniu argumentów.
Nazwany argument <emphasis>nie może</emphasis> odpisywać już rozpakowanego argumentu.
</para>
<example>
<title>Użycie nazwanych argumentów po rozpakowaniu</title>
<programlisting role="php">
<![CDATA[
<?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
?>
]]>
</programlisting>
</example>
</sect2>
</sect1>
<sect1 xml:id="functions.returning-values">
<title>Zwracanie wartości</title>
<para>
Wartości zwracane są przy użyciu opcjonalnego wyrażenia return. Wszystkie
typy mogą być zwracane, łącznie z tablicami i obiektami. Powoduje to natychmiastowe
zakończenie wykonywania funkcji i wznowienie wykonywania skryptu od linijki w której
funkcja została wywołana. Zobacz <function>return</function>
aby uzyskać więcej informacji.
</para>
<note>
<para>
Jeżeli <function>return</function> zostanie pominięte, zwrócona będzie
wartość &null;,
</para>
</note>
<sect2>
<title>Użycie return</title>
<para>
<example>
<title>Użycie <function>return</function></title>
<programlisting role="php">
<![CDATA[
<?php
function kwadrat($liczba)
{
return $liczba * $liczba;
}
echo kwadrat(4); // wypisuje '16'.
?>
]]>
</programlisting>
</example>
</para>
<para>
Funkcja nie może zwracać wielu wartości, ale podobny efekt
może zostać osiągnięty poprzez zwracanie tablicy.
</para>
<para>
<example>
<title>Zwracanie tablicy</title>
<programlisting role="php">
<![CDATA[
<?php
function small_numbers()
{
return array (0, 1, 2);
}
// Destrukturyzacja tablicy przypisze każdy element tablicy do osobnej zmiennej
[$zero, $one, $two] = small_numbers();
// Przed PHP 7.1.0, jedyną alternatywą było użycie konstrukcji list()
list ($zero, $one, $two) = small_numbers();
?>
]]>
</programlisting>
</example>
</para>
<para>
Aby zwrócić referencję, użyj operatora &amp; zarówno
w deklaracji funkcji, jak i podczas przypisywania zwracanej wartości
zmiennej:
</para>
<para>
<example>
<title>Zwracanie referencji</title>
<programlisting role="php">
<![CDATA[
<?php
function &returns_reference()
{
return $someref;
}
$newref =& returns_reference();
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Aby uzyskać więcej informacji o referencjach, przejdź do <link
linkend="language.references">Wyjaśnienie Referencji</link>.
</simpara>
</sect2>
</sect1>
<sect1 xml:id="functions.variable-functions">
<title>Funkcje zmiennych</title>
<para>
PHP obsługuje opcję funkcji zmiennych. Oznacza to, że jeśli
do nazwy zmiennej dodane są nawiasy, PHP postara się znaleźć
funkcję o nazwie takiej jak wartość zmiennej
i spróbuje ją wykonać. Między innymi, może to służyć do
zaimplementowania tzw. callbacks, tablic funkcji, a także wielu innych rzeczy.
</para>
<para>
Funkcje zmiennych nie zadziałają z takimi elementami języka
jak <function>echo</function>, <function>print</function>,
<function>unset</function>, <function>isset</function>,
<function>empty</function>, <function>include</function>,
<function>require</function> i podobnymi. Używaj okrężnych funkcji
aby skorzystać z któregoś z powyższych elementów języka jako funkcji zmiennych.
</para>
<para>
<example>
<title>Przykład funkcji zmiennych</title>
<programlisting role="php">
<![CDATA[
<?php
function foo() {
echo "W foo()<br />\n";
}
function bar($arg = '')
{
echo "W bar(); argumentem było '$arg'.<br />\n";
}
// To jest funkcja okrężna dla "echo"
function echoit($string)
{
echo $string;
}
$func = 'foo';
$func(); // Wywołuje foo()
$func = 'bar';
$func('test'); // Wywołuje bar()
$func = 'echoit';
$func('test'); // Wywołuje echoit()
?>
]]>
</programlisting>
</example>
</para>
<para>
Jako funkcje zmiennych mogą być także wywoływane metody obiektów.
<example>
<title>Przykład metod zmiennych</title>
<programlisting role="php">
<![CDATA[
<?php
class Foo
{
function Zmienna()
{
$name = 'Bar';
$this->$name(); // Wywołuje metodę Bar()
}
function Bar()
{
echo "To jest Bar";
}
}
$foo = new Foo();
$funcname = "Zmienna";
$foo->$funcname(); // Wywołuje $foo->Zmienna()
?>
]]>
</programlisting>
</example>
</para>
<para>
Gdy wywołuje się metody statyczne, wywołanie funkcji jest mocniejsze niż operator właściwości statycznej:
<example>
<title>Przykład zmiennej metody z właściwościami statycznymi</title>
<programlisting role="php">
<![CDATA[
<?php
class Foo
{
static $zmienna = 'właściwość statyczna';
static function Zmienna()
{
echo 'Wywołano metodę Zmienna';
}
}
echo Foo::$zmienna; // Wyświetli 'właściwość statyczna'. Potrzebna jest $zmienna w tym zasięgu.
$zmienna = "Zmienna";
Foo::$variable(); // Wywoła $foo->Zmienna() odczytując $zmienna w tym zasięgu.
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title>Kompleksowy przykład callables</title>
<programlisting role="php">
<![CDATA[
<?php
class Foo
{
static function bar()
{
echo "bar\n";
}
function baz()
{
echo "baz\n";
}
}
$func = array("Foo", "bar");
$func(); // wyświetli "bar"
$func = array(new Foo, "baz");
$func(); // wyświetli "baz"
$func = "Foo::bar";
$func(); // wyświetli "bar"
?>
]]>
</programlisting>
</example>
</para>
<sect2 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><function>is_callable</function></member>
<member><function>call_user_func</function></member>
<member><function>function_exists</function></member>
<member><link linkend="language.variables.variable">zmienne zmiennych</link></member>
</simplelist>
</para>
</sect2>
</sect1>
<sect1 xml:id="functions.internal">
<title>Wewnętrzne (wbudowane) funkcje</title>
<para>
PHP zapewnia wiele wbudowanych funkcji i konstrukcji. Istnieją także
funkcje wymagające wkompilowania specyficznych rozszerzeń PHP, w przeciwnym wypadku
wywołanie ich skutkuje błędami "undefined function". Na przykładd, aby użyć funkcji
<link linkend="ref.image">obrazków</link> takich jak
<function>imagecreatetruecolor</function>, PHP musi być skompilowane z obsługą
<productname>GD</productname>. Aby użyć
<function>mysqli_connect</function>, PHP musi być skompilowane z obsługą
<link linkend="book.mysqli">MySQLi</link>. Jest wiele funkcji wbudowanych
w rdzeń każdej wersji PHP, takich jak funkcje
<link linkend="ref.strings">typu string</link> oraz
<link linkend="ref.var">zmiennych</link>. Wywołanie
to <function>phpinfo</function> lub
<function>get_loaded_extensions</function> pokaże, które rozszerzenia
PHP są załadowane. Zauważ, że wiele rozszerzeń jest domyślnie załadowanych i
podręcznik PHP jest podzielony według rozszerzeń. Zobacz rozdziały o
<link linkend="configuration">konfiguracji</link>,
<link linkend="install">instalacji</link>, a także te dotyczące
poszczególnych rozszerzeń, aby dowiedzieć się jak uruchomić PHP.
</para>
<para>
Czytanie i rozumienie prototypów funkcji wyjaśnione jest w rozdziale
podręcznika zatytułowanym <link linkend="about.prototypes">jak czytać
definicje funkcji</link>. Ważne jest zrozumienie, czy funkcja zwraca konkretną wartość
czy operuje bezpośrednio na podanej zmiennej. Na przykład,
<function>str_replace</function> zwróci zmodyfikowany obiekt typu string, podczas gdy
<function>usort</function> pracuje bezpośrednio na podanej zmiennej.
Każda funkcja posiada swoją stronę w podręczniku PHP, która podaje informacje takie jak
parametry funkcji, jej zachowanie, wartości zwracane po poprawnym wykonaniu i w przypadku błędu,
a także dane dotyczące jej dostępności.
Znanie tych ważnych (chociaż często drobnych) różnic jest kluczowe podczas
pisania kodu w PHP.
</para>
<note>
<simpara>
Jeśli parametry podane funkcji nie są takie, jak spodziewane, na przykład
tablica(<type>array</type>) podawana jest w miejscu, gdzie oczekiwana jest zmienna typu <type>string</type>,
wartość zwracana przez funkcję nie jest zdefiniowana. W takim wypadku funkcja prawdopodobnie
zwróci &null; ale jest to jedynie konwencja,
a nie zasada, na której można się opierać.
Od PHP 8.0.0 w tej sytuacji będzie rzucony wyjątek <classname>TypeError</classname>.
</simpara>
</note>
<note>
<para>
Dla wbudowanych w PHP funkcji typy skalarne domyślnie akceptują null (poza strict mode).
Od PHP 8.1.0 przekazanie &null; do wbudowanej funkcji, który nie akceptuje wartości null,
jest niezalecane i emituje komunikat <constant>E_DEPRECATED</constant> w trybie nie-ścisłym, tak aby uzyskać spójne zachowaine z funkcjami deklarowanymi przez użytkownika,
gdzie typy skalarne muszą być wprost oznaczone jako takie, które akceptują wartość null.
</para>
<para>
Przykładowo, <function>strlen</function> oczekuje parametru <literal>$string</literal>,
który będzie typem &string; i nie będzie nullem.
Ze względów historycznych PHP pozwala na przekazanie &null; jako wartości tego parametru (poza trybem ścisłym) i parametr taki
jest niejawnie rzutowany na typ <type>string</type>, co skutkuje w przekazaniu wartości <literal>""</literal> do funkcji.
W trybie ścisłym (strict mode) rzucany jest <classname>TypeError</classname>.
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
var_dump(strlen(null));
// "Deprecated: Passing null to parameter #1 ($string) of type string is deprecated" as of PHP 8.1.0
// int(0)
var_dump(str_contains("foobar", null));
// "Deprecated: Passing null to parameter #2 ($needle) of type string is deprecated" as of PHP 8.1.0
// bool(true)
?>
]]>
</programlisting>
</informalexample>
</note>
<sect2 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><function>function_exists</function></member>
<member><link linkend="funcref">listę funkcji</link></member>
<member><function>get_extension_funcs</function></member>
<member><function>dl</function></member>
</simplelist>
</para>
</sect2>
</sect1>
<sect1 xml:id="functions.anonymous">
<title>Funkcje anonimowe</title>
<simpara>
Funkcje anonimowe, znane także jako <literal>closures</literal> (pol. domknięcia), pozwalają
na utworzenie funkcji, które nie mają określonej nazwy. Są najbardziej użyteczne jako
wartość parametrów typu <type>callable</type>,
ale mają też wiele innych zastosowań.
</simpara>
<simpara>
Funkcje anonimowe są zaimplementowane przy użyciu klasy <link linkend="class.closure">Closure</link>.
</simpara>
<example>
<title>Przykład funkcji anonimowej</title>
<programlisting role="php">
<![CDATA[
<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
return strtoupper($match[1]);
}, 'hello-world');
// wyświetli helloWorld
?>
]]>
</programlisting>
</example>
<simpara>
Domknięcia mogą zostać użyte także jako wartości zmiennych; PHP automatycznie
konwertuje takie wyrażenia na instancje
wewnętrznej klasy <classname>Closure</classname>. Przypisanie domknięcia do
zmiennej korzysta z takiej samej składni jak każde inne przypisanie, włączając w to
średnik na końcu:
</simpara>
<example>
<title>Przypisanie funkcji anonimowej do zmiennej</title>
<programlisting role="php">
<![CDATA[
<?php
$greet = function($name) {
printf("Witaj %s\r\n", $name);
};
$greet('Świecie');
$greet('PHP');
?>
]]>
</programlisting>
</example>
<simpara>
Domknięcia mogą także dziedziczyć zmienne z zasięgu nadrzędnego. Każda taka
musi być przekazana za pomocą kontrukcji <literal>use</literal>.
Od PHP 7.1 jako takie zmienne nie mogą zostać użyte &link.superglobals;,
<varname>$this</varname> oraz zmienne o nazwach takich jak parametry.
Deklaracja zwracanego typu musi zostać umieszczona <emphasis>po</emphasis>
słowie kluczowym <literal>use</literal>.
</simpara>
<example>
<title>Dziedziczenie zmiennych z nadrzędnego zakresu</title>
<programlisting role="php">
<![CDATA[
<?php
$message = 'hello';
// Brak "use"
$example = function () {
var_dump($message);
};
$example();
// Odziedzicz $message
$example = function () use ($message) {
var_dump($message);
};
$example();
// Wartość jest dziedziczona podczas definiowania funkcji,
// a nie jej wykonywania
$message = 'world';
$example();
// Zresetuj wiadomosć
$message = 'hello';
// Odziedzicz przez referencje
$example = function () use (&$message) {
var_dump($message);
};
$example();
// Zmieniona wartość w zasięgu nadrzędnym jest
// brana pod uwagę wewnątrz wywołania funkcji
$message = 'world';
$example();
// Domknięcia mogą także przyjmować normalne argumenty
$example = function ($arg) use ($message) {
var_dump($arg . ' ' . $message);
};
$example("hello");
// Deklaracja zwracanego typu jest umieszczona po słowie kluczowym use
$example = function () use ($message): string {
return "hello $message";
};
var_dump($example());
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Notice: Undefined variable: message in /example.php on line 6
NULL
string(5) "hello"
string(5) "hello"
string(5) "hello"
string(5) "world"
string(11) "hello world"
string(11) "hello world"
]]>
</screen>
</example>
<para>
Od PHP 8.0.0, lista argumentów przekazanych do konstrukcji <literal>list</literal> może kończyć się
przecinkiem, który zostanie zignorowany.
</para>
<simpara>
Dziedziczenie zmiennych z zasięgu nadrzędnego to <emphasis>nie</emphasis>
to samo co użycie zmiennych globalnych.
Zmienne globalne istnieją w zasięgu globalnym, który jest jednakowy
bez względu na wykonywaną funkcję. Nadrzędnym zasięgiem domknięcia jest
funkcja, w której domknięcie zostało zadeklarowane (niekoniecznie funkcja,
z której zostało wykonane). Zobacz poniższy przykład:
</simpara>
<example>
<title>Domknięcia i zasięg</title>
<programlisting role="php">
<![CDATA[
<?php
// Podstawowy koszyk sklepowy, który zawiera listę dodanych produktów
// i ilość każdego z nich. Zawiera metodę, która
// liczy całkowitą cenę produktów w koszyku używając
// funkcji anonimowej jako callbacku.
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;
// Dodaj produkty do koszyka
$my_cart->add('butter', 1);
$my_cart->add('milk', 3);
$my_cart->add('eggs', 6);
// Wyświetl całkowitą cenę z 5% podatkiem.
print $my_cart->getTotal(0.05) . "\n";
// Wynik to 54.29
?>
]]>
</programlisting>
</example>
<example>
<title>Automatyczne przypisanie <literal>$this</literal></title>
<programlisting role="php">
<![CDATA[
<?php
class Test
{
public function testing()
{
return function() {
var_dump($this);
};
}
}
$object = new Test;
$function = $object->testing();
$function();
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
object(Test)#1 (0) {
}
]]>
</screen>
</example>
<para>
Gdy funkcja anonimowa jest zadeklarowana w kontekście klasy,
obecna klasa jest automatycznie do niej przypisywana, sprawiając, że w zakresie
funkcji jest dostępna zmienna <literal>$this</literal>. Jeśli to automatyczne
powiązywanie jest niepożądane, można w zamian użyć
<link linkend="functions.anonymous-functions.static">statycznych funkcji
anonimowych</link>.
</para>
<sect2 xml:id="functions.anonymous-functions.static">
<title>Statyczne funkcje anonimowe</title>
<para>
Funkcje anonimowe mogą być zadeklarowane jako statyczne.
Zapobiega to przed automatycznym przypisaniem do nich obecnej klasy.
Nie można też przypisać do nich obiektów w czasie wykonywania skryptu.
</para>
<para>
<example>
<title>Próba użycia <literal>$this</literal> wewnątrz statycznej funkcji anonimowej</title>
<programlisting role="php">
<![CDATA[
<?php
class Foo {
{
function __construct()
{
$func = static function() {
var_dump($this);
};
$func();
}
};
new Foo();
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Notice: Undefined variable: this in %s on line %d
NULL
]]>
</screen>
</example>
</para>
<para>
<example>
<title>Próba przypisania obiektu do statycznej funkcji anonimowej</title>
<programlisting role="php">
<![CDATA[
<?php
$func = static function() {
// ciało funkcji
};
$func = $func->bindTo(new stdClass);
$func();
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Warning: Cannot bind an instance to a static closure in %s on line %d
]]>
</screen>
</example>
</para>
</sect2>
<sect2 role="changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>8.3.0</entry>
<entry>
Domknięcia utworzone z <link linkend="language.oop5.magic">metod
magicznych</link> mogą przyjmować nazwane parametry.
</entry>
</row>
<row>
<entry>7.1.0</entry>
<entry>
Funkcje anonimowe nie mogą używać &link.superglobals;,
<varname>$this</varname> oraz zmiennych o nazwach takich
jak parametry.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</sect2>
<sect2 role="notes">
&reftitle.notes;
<note>
<simpara>
Wewnątrz funkcji anonimowej można używać <function>func_num_args</function>,
<function>func_get_arg</function> i <function>func_get_args</function>.
</simpara>
</note>
</sect2>
</sect1>
<sect1 xml:id="functions.arrow">
<title>Funkcje strzałkowe (arrow functions)</title>
<simpara>
Funkcje strzałkowe zostały wprowadzone w PHP 7.4 jako bardziej zwięzła składnia dla
<link linkend="functions.anonymous">funkcji anonimowych</link>.
</simpara>
<simpara>
Zarówno funkcje anonimowe jak i strzałkowe są zaimplementowane przy użyciu
klasy <link linkend="class.closure"><classname>Closure</classname></link>.
</simpara>
<simpara>
Funkcje strzałkowe mają podstawową składnię
<code>fn (lista_argumentów) =&gt; wyrażenie</code>.
</simpara>
<simpara>
Funkcje strzałkowe wspierają takie same funkcjonalności jak
<link linkend="functions.anonymous">funkcje anonimowe</link>,
z tym że użycie zmiennych z zasięgu rodzica jest zawsze automatyczne.
</simpara>
<simpara>
Kiedy zmienna użyta w wyrażeniu jest zdefiniowana w zasięgu rodzica,
będzie automatycznie widoczna (przez wartość, nie przez referencję).
W następującym przykładzie funkcje <varname>$fn1</varname> i
<varname>$fn2</varname> działają identycznie.
</simpara>
<para>
<example>
<title>Funkcje strzałkowe automatycznie przejmują wartości zmiennych</title>
<programlisting role="php">
<![CDATA[
<?php
$y = 1;
$fn1 = fn($x) => $x + $y;
// odpowiednik użycia $y jak poniżej:
$fn2 = function ($x) use ($y) {
return $x + $y;
};
var_export($fn1(3));
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
4
]]>
</screen>
</example>
</para>
<simpara>
Działa to także gdy funkcje strzałkowe są zagnieżdżone:
</simpara>
<para>
<example>
<title>Funkcje strzałkowe automatycznie przejmują wartości zmiennych, nawet gdy zagnieżdżone</title>
<programlisting role="php">
<![CDATA[
<?php
$z = 1;
$fn = fn($x) => fn($y) => $x * $y + $z;
// Wyświetla 51
var_export($fn(5)(10));
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Podobnie jak w funkcjach anonimowych
funkcje strzałkowe pozwalają na dowolną sygnaturę funkcji,
w tym na typy parametrów, typ zwracanej wartości, wartości domyślne,
przyjmowanie zmiennej ilości argumentów, a także przyjmowanie i zwracanie
wartości przez referencję.
Wszystkie poniższe są prawidłowymi przykładami funkcji strzałkowych:
</simpara>
<para>
<example>
<title>Przykłady funkcji strzałkowych</title>
<programlisting role="php">
<![CDATA[
<?php
fn(array $x) => $x;
static fn($x): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$pozostale) => $pozostale;
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Funkcje strzałkowe przekazują wartości zmiennych (a nie referencje do nich).
Jest to w zasadzie odpowiednikiem użycia <code>use($x)</code> dla każdej
zmiennej <varname>$x</varname> użytej wewnątrz funkcji strzałkowej.
Przekazywanie przez wartość oznacza, że nie jest możliwe zmodyfikowanie wartości
z zewnętrznego zakresu zmiennych.
W celu przekazania zmiennych przez referencję można skorzystać z
<link linkend="functions.anonymous">funkcji anonimowych</link>.
</simpara>
<para>
<example>
<title>Wartości z zewnętrznego zakresu nie mogą być modyfikowane przez funkcje strzałkowe</title>
<programlisting role="php">
<![CDATA[
<?php
$x = 1;
$fn = fn() => $x++; // Nie ma wpływu na $x
$fn();
var_export($x); // Wyświetli 1
?>
]]>
</programlisting>
</example>
</para>
<sect2 role="changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>7.4.0</entry>
<entry>
Dodano obsługę funkcji strzałkowych.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</sect2>
<sect2 role="notes">
&reftitle.notes;
<note>
<simpara>
Wewnątrz funkcji strzałkowej można używać <function>func_num_args</function>,
<function>func_get_arg</function> i <function>func_get_args</function>.
</simpara>
</note>
</sect2>
</sect1>
<sect1 xml:id="functions.first_class_callable_syntax">
<title>Obsługa callable przy użyciu dedykowanej składni (first-class)</title>
<para>
PHP 8.1.0 wprowadziło dedykowaną składnię, aby umożliwić tworzenie <link linkend="functions.anonymous">funkcji anonimowych</link> z typu <link linkend="language.types.callable">callable</link>.
Ta składnia jest rekomendowana zamiast wcześniejszych składni korzystających z tablic lub specjalnych ciągów znaków.
Zaletą użycia dedykowanej składni jest jej zrozumiałość dla narzędzi wykonujących analizę statyczną oraz użycie zakresu w momencie tworzenia callable.
</para>
<para>
Składnia <code>WyrażenieCallable(...)</code> jest używana do stworzenia obiektu <classname>Closure</classname> z callable. <code>WyrażenieCallable</code> może być dowolnym wyrażeniem, które może zostać bezpośrednio wywołane wg gramatyki PHP:
<example>
<title>Prosta składnia dedykowana (first-class) dla callable</title>
<programlisting role="php">
<![CDATA[
<?php
class Foo {
public function method() {}
public static function staticmethod() {}
public function __invoke() {}
}
$obj = new Foo();
$nazwaKlasy = 'Foo';
$nazwaMetody = 'method';
$nazwaMetodyStatycznej = 'staticmethod';
$f1 = strlen(...);
$f2 = $obj(...); // obiekt wywoływalny (__invoke)
$f3 = $obj->method(...);
$f4 = $obj->$nazwaMetody(...);
$f5 = Foo::staticmethod(...);
$f6 = $nazwaKlasy::$nazwaMetodyStatycznej(...);
// tradycyjna składnia przy użyciu ciągu znaków lub tablicy
$f7 = 'strlen'(...);
$f8 = [$obj, 'method'](...);
$f9 = [Foo::class, 'staticmethod'](...);
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
Znaki <code>...</code> są częścią składni, a nie pomięciem.
</para>
</note>
<para>
<code>WyrażenieCallable(...)</code> ma taką samą semantykę jak <methodname>Closure::fromCallable</methodname>.
To znaczy, w przeciwieństwie do składni callable korzystającej z ciągów znaków lub tablic, <code>WyrażenieCallable(...)</code> bierze pod uwagę zakres widoczności w chwili, gdy jest tworzone:
<example>
<title>Porównanie zakresu widoczności dla <code>WyrażenieCallable(...)</code> i tradycyjnej składni callable</title>
<programlisting role="php">
<![CDATA[
<?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
// Dzieje się tak ponieważ wywołanie odbywa się spoza klasy Foo i modyfikator widoczności metody będzie sprawdzony
class Foo1 {
public function getPrivateMethod() {
// Używa zakresu widoczności w momencie tworzenia callable.
return $this->privateMethod(...); // odpowiednik Closure::fromCallable([$this, 'privateMethod']);
}
private function privateMethod() {
echo __METHOD__, "\n";
}
}
$foo1 = new Foo1;
$privateMethod = $foo1->getPrivateMethod();
$privateMethod(); // Foo1::privateMethod
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
Tworzenie obiektów przy użyciu tej składni (np. <code>new Foo(...)</code>) nie jest obsługiwane, ponieważ składnia <code>new Foo()</code> nie jest uznawana za wywołanie.
</para>
</note>
<note>
<para>
Dedykowanej składni do obsługi callable nie można łączyć z <link linkend="language.oop5.basic.nullsafe">operatorem nullsafe</link>. Oba z poniższych zakończą się błędem w trakcie kompilacji skryptu:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$obj?->method(...);
$obj?->prop->method(...);
?>
]]>
</programlisting>
</informalexample>
</para>
</note>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->