mirror of
https://github.com/php/doc-ru.git
synced 2025-08-16 18:22:04 +00:00

git-svn-id: https://svn.php.net/repository/phpdoc/ru/trunk@322591 c90b9560-bf6c-de11-be94-00142212c4b1
838 lines
32 KiB
XML
838 lines
32 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- EN-Revision: 85c790a244dbf8b711aa381db1025dd2fab4db94 Maintainer: shein Status: ready -->
|
||
<!-- Reviewed: no -->
|
||
<!-- $Revision$ -->
|
||
<chapter xml:id="language.functions" xmlns="http://docbook.org/ns/docbook">
|
||
<title>Функции</title>
|
||
|
||
<sect1 xml:id="functions.user-defined">
|
||
<title>Функции, определяемые пользователем</title>
|
||
|
||
<para>
|
||
Приведем пример синтаксиса, используемого для описания функций:
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Псевдокод для демонстрации использования функций</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
|
||
{
|
||
echo "Example function.\n";
|
||
return $retval;
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
|
||
<simpara>
|
||
Внутри функции можно использовать любой корректный PHP-код,
|
||
в том числе другие функции и даже объявления <link linkend="keyword.class">классов</link>.
|
||
</simpara>
|
||
<para>
|
||
Имена функций следуют тем же правилам, что и другие метки в PHP.
|
||
Корректное имя функции начинается с буквы или знака подчеркивания,
|
||
за которым следует любое количество букв, цифр или знаков
|
||
подчеркивания. В качестве регулярного выражения оно может быть
|
||
выражено так:
|
||
<literal>[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*</literal>.
|
||
</para>
|
||
&tip.userlandnaming;
|
||
<simpara>
|
||
Функции не обязаны быть определены до их использования, <emphasis>исключая</emphasis>
|
||
тот случай, когда функции определяются условно, как это показано
|
||
в двух последующих примерах.
|
||
</simpara>
|
||
<para>
|
||
В случае, когда функция определяется в зависимости от какого-либо условия, например,
|
||
как это показано в двух приведенных ниже примерах, обработка описания функции
|
||
должна <emphasis>предшествовать</emphasis> ее вызову.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Функции, зависящие от условий</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$makefoo = true;
|
||
|
||
/* Мы не можем вызвать функцию foo() в этом месте,
|
||
поскольку она еще не определена, но мы можем
|
||
обратиться к bar() */
|
||
|
||
bar();
|
||
|
||
if ($makefoo) {
|
||
function foo()
|
||
{
|
||
echo "Я не существую до тех пор, пока выполнение программы меня не достигнет.\n";
|
||
}
|
||
}
|
||
|
||
/* Теперь мы благополучно можем вызывать foo(),
|
||
поскольку $makefoo была интерпретирована как true */
|
||
|
||
if ($makefoo) foo();
|
||
|
||
function bar()
|
||
{
|
||
echo "Я существую сразу с начала старта программы.\n";
|
||
}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Вложенные функции</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function foo()
|
||
{
|
||
function bar()
|
||
{
|
||
echo "Я не существую пока не будет вызвана foo().\n";
|
||
}
|
||
}
|
||
|
||
/* Мы пока не можем обратиться к bar(),
|
||
поскольку она еще не определена. */
|
||
|
||
foo();
|
||
|
||
/* Теперь мы можем вызвать функцию bar(),
|
||
обработка foo() сделала ее доступной. */
|
||
|
||
bar();
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
Все функции и классы PHP имеют глобальную область видимости -
|
||
они могут быть вызваны вне функции, даже если были определены
|
||
внутри и наоборот.
|
||
</para>
|
||
<simpara>
|
||
PHP не поддерживает перегрузку функции, также отсутствует возможность
|
||
переопределить или удалить объявленную ранее функцию.
|
||
</simpara>
|
||
<note>
|
||
<simpara>
|
||
Имена функций регистронезависимы, тем не менее, более предпочтительно
|
||
вызывать функции так, как они были объявлены.
|
||
</simpara>
|
||
</note>
|
||
<simpara>
|
||
Функции PHP поддерживают как <link linkend="functions.variable-arg-list">
|
||
списки аргументов переменной длины</link>, так и
|
||
<link linkend="functions.arguments.default">значения аргументов по умолчанию</link>.
|
||
Смотрите также описания функций
|
||
<function>func_num_args</function>,
|
||
<function>func_get_arg</function>, и
|
||
<function>func_get_args</function> для более детальной информации.
|
||
</simpara>
|
||
|
||
<para>
|
||
Можно также вызывать функции PHP рекурсивно. Однако, пытайтесь
|
||
избегать вызовов рекурсивных функций/методов с более чем 100-200
|
||
уровней рекурсии, так как это сильно бьет по стэку и может вызвать
|
||
крах выполняемого скрипта.
|
||
<example>
|
||
<title>Рекурсивные функции</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function recursion($a)
|
||
{
|
||
if ($a < 20) {
|
||
echo "$a\n";
|
||
recursion($a + 1);
|
||
}
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.arguments">
|
||
<title>Аргументы функции</title>
|
||
|
||
<simpara>
|
||
Функция может принимать информацию в виде списка аргументов,
|
||
который является списком разделенных запятыми выражений. Аргументы
|
||
вычисляются слева направо.
|
||
</simpara>
|
||
<para>
|
||
PHP поддерживает передачу аргументов по значению (по умолчанию), <link
|
||
linkend="functions.arguments.by-reference">передачу аргументов по ссылке</link>,
|
||
и <link linkend="functions.arguments.default">значения по умолчанию</link>.
|
||
<link linkend="functions.variable-arg-list">Списки аргументов переменной длины
|
||
</link> также поддерживаются, смотрите также описания функций
|
||
<function>func_num_args</function>,
|
||
<function>func_get_arg</function> и
|
||
<function>func_get_args</function> для более детальной информации.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Передача массива в функцию</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function takes_array($input)
|
||
{
|
||
echo "$input[0] + $input[1] = ", $input[0]+$input[1];
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
|
||
<sect2 xml:id="functions.arguments.by-reference">
|
||
<title>Передача аргументов по ссылке</title>
|
||
|
||
<simpara>
|
||
По умолчанию аргументы в функцию передаются по значению (это означает, что
|
||
если вы измените значение аргумента внутри функции, то вне ее значение
|
||
все равно останется прежним). Если вы хотите разрешить функции
|
||
модифицировать свои аргументы, вы должны передавать их по ссылке.
|
||
</simpara>
|
||
<para>
|
||
Если вы хотите, что бы аргумент всегда передавался по ссылке,
|
||
вы можете указать амперсанд (&) перед именем аргумента в описании
|
||
функции:
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Передача аргументов по ссылке</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function add_some_extra(&$string)
|
||
{
|
||
$string .= 'и кое-что еще.';
|
||
}
|
||
$str = 'Это строка, ';
|
||
add_some_extra($str);
|
||
echo $str; // выведет 'Это строка, и кое-что еще.'
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2 xml:id="functions.arguments.default">
|
||
<title>Значения аргументов по умолчанию</title>
|
||
|
||
<para>
|
||
Функция может определять значения по умолчанию в стиле C++ для
|
||
скалярных аргументов, например:
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Использование значений по умолчанию в определении функции</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function makecoffee($type = "капуччино")
|
||
{
|
||
return "Готовим чашку $type.\n";
|
||
}
|
||
echo makecoffee();
|
||
echo makecoffee(null);
|
||
echo makecoffee("эспрессо");
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Готовим чашку капуччино.
|
||
Готовим чашку .
|
||
Готовим чашку эспрессо.
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
PHP также позволяет использовать массивы (<type>array</type>) и специальный тип &null; в
|
||
качестве значений по умолчанию, например:
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Использование нескалярных типов в качестве значений по умолчанию</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function makecoffee($types = array("капуччино"), $coffeeMaker = NULL)
|
||
{
|
||
$device = is_null($coffeeMaker) ? "вручную" : $coffeeMaker;
|
||
return "Готовлю чашку ".join(", ", $types)." $device.\n";
|
||
}
|
||
echo makecoffee();
|
||
echo makecoffee(array("капуччино", "лавацца"), "в чайнике");
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
</para>
|
||
<simpara>
|
||
Значение по умолчанию должно быть константным выражением, а не
|
||
(к примеру) переменной или вызовом функции/метода класса.
|
||
</simpara>
|
||
<para>
|
||
Обратите внимание, что все аргументы, для которых установлены
|
||
значения по умолчанию, должны находиться правее аргументов,
|
||
для которых значения по умолчанию не заданы, в противном случае
|
||
ваш код может работать не так, как вы этого ожидаете. Рассмотрим
|
||
следующий пример:
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Некорректное использование значений по умолчанию</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function makeyogurt($type = "ацидофил", $flavour)
|
||
{
|
||
return "Готовим чашку из бактерий $type со вкусом $flavour.\n";
|
||
}
|
||
|
||
echo makeyogurt("малины"); // Не будет работать так, как мы могли бы ожидать
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Warning: Missing argument 2 in call to makeyogurt() in
|
||
/usr/local/etc/httpd/htdocs/phptest/functest.html on line 41
|
||
Готовим чашку из бактерий малины со вкусом .
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
Теперь сравним эго со следующим примером:
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Корректное использование значений по умолчанию</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function makeyogurt($flavour, $type = "ацидофил")
|
||
{
|
||
return "Готовим чашку из бактерий $type со вкусом $flavour.\n";
|
||
}
|
||
|
||
echo makeyogurt("малины"); // отрабатывает правильно
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Готовим чашку из бактерий ацидофил со вкусом малины.
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
<note>
|
||
<simpara>
|
||
Начиная с PHP 5, значения по умолчанию могут быть переданны по ссылке.
|
||
</simpara>
|
||
</note>
|
||
|
||
</sect2>
|
||
|
||
<sect2 xml:id="functions.variable-arg-list">
|
||
<title>Списки аргументов переменной длины</title>
|
||
|
||
<simpara>
|
||
PHP поддерживает списки аргументов переменной длины для функций,
|
||
определяемых пользователем. Реализация этой возможности достаточно прозрачна
|
||
и заключается в использовании функций <function>func_num_args</function>,
|
||
<function>func_get_arg</function> и
|
||
<function>func_get_args</function>.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Необходимости в специфическом синтаксисе нет, при этом список аргументов
|
||
также может быть указан явно и будет обладать тем же поведением.
|
||
</simpara>
|
||
|
||
</sect2>
|
||
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.returning-values">
|
||
<title>Возврат значений</title>
|
||
|
||
<para>
|
||
Значения возвращаются при помощи необязательного оператора возврата.
|
||
Возвращаемые значения могут быть любого типа, в том числе это могут
|
||
быть массивы и объекты. Возврат приводит к завершению выполнения функции и передаче
|
||
управления обратно к той строке кода, в которой данная функция была
|
||
вызвана. Для получения более детальной информации ознакомьтесь с описанием
|
||
<function>return</function>.
|
||
</para>
|
||
<note>
|
||
<para>
|
||
Если конструкция <function>return</function> не указана, то функция вернет
|
||
значение &null;.
|
||
</para>
|
||
</note>
|
||
<para>
|
||
<example>
|
||
<title>Использование конструкции <function>return</function></title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function square($num)
|
||
{
|
||
return $num * $num;
|
||
}
|
||
echo square(4); // выводит '16'.
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
|
||
<para>
|
||
Функция не может возвращать несколько значений, но аналогичного
|
||
результата можно добиться, возвращая массив.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Возврат нескольких значений в виде массива</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function small_numbers()
|
||
{
|
||
return array (0, 1, 2);
|
||
}
|
||
list ($zero, $one, $two) = small_numbers();
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
Для того, чтобы функция возвращала результат по ссылке, вам
|
||
необходимо использовать оператор & и при описании функции,
|
||
и при присвоении переменной возвращаемого значения:
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Возврат результата по ссылке</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function &returns_reference()
|
||
{
|
||
return $someref;
|
||
}
|
||
|
||
$newref =& returns_reference();
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<simpara>
|
||
Для получения более детальной информации о ссылках обратитесь
|
||
к разделу документации <link linkend="language.references">Подробно о ссылках</link>.
|
||
</simpara>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.variable-functions">
|
||
<title>Обращение к функциям через переменные</title>
|
||
|
||
<para>
|
||
PHP поддерживает концепцию переменных функций. Это означает, что
|
||
если к имени переменной присоединены круглые скобки, PHP ищет
|
||
функцию с тем же именем, что и результат вычисления переменной, и
|
||
пытается ее выполнить. Эту возможность можно использовать для
|
||
реализации обратных вызовов, таблиц функций и множества других вещей.
|
||
</para>
|
||
<para>
|
||
Переменные функции не будут работать с такими языковыми конструкциями
|
||
как <function>echo</function>, <function>print</function>,
|
||
<function>unset</function>, <function>isset</function>,
|
||
<function>empty</function>, <function>include</function>,
|
||
<function>require</function> и другими подобными им операторами.
|
||
Вам необходимо реализовывать свою функцию-обертку (wrapper) для того,
|
||
чтобы приведенные выше конструкции могли работать с переменными
|
||
функциями.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Работа с функциями посредством переменных</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function foo() {
|
||
echo "In foo()<br />\n";
|
||
}
|
||
|
||
function bar($arg = '')
|
||
{
|
||
echo "In bar(); argument was '$arg'.<br />\n";
|
||
}
|
||
|
||
// Функция-обертка для echo
|
||
function echoit($string)
|
||
{
|
||
echo $string;
|
||
}
|
||
|
||
$func = 'foo';
|
||
$func(); // Вызывает функцию foo()
|
||
|
||
$func = 'bar';
|
||
$func('test'); // Вызывает функцию bar()
|
||
|
||
$func = 'echoit';
|
||
$func('test'); // Вызывает функцию echoit()
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
Вы также можете вызвать методы объекта, используя возможности PHP
|
||
для работы с переменными функциями.
|
||
<example>
|
||
<title>Обращение к методам класса посредством переменных</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?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()
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
При вызове статических методов, вызов функции "сильнее"
|
||
чем оператор доступа к статическому свойству:
|
||
<example>
|
||
<title>Пример вызова переменного метода со статическим свойством</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
class Foo
|
||
{
|
||
static $variable = 'static property';
|
||
static function Variable()
|
||
{
|
||
echo 'Method Variable called';
|
||
}
|
||
}
|
||
|
||
echo Foo::$variable; // Это выведет 'static property'. Переменная $variable будет разрешена в нужной области видимости.
|
||
$variable = "Variable";
|
||
Foo::$variable(); // Это вызовет $foo->Variable(), прочитав $variable из этой области видимости.
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
|
||
<para>
|
||
Смотрите также <function>call_user_func</function>,
|
||
<link linkend="language.variables.variable">Переменные переменные</link> и
|
||
<function>function_exists</function>.
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.internal">
|
||
<title>Встроенные функции</title>
|
||
|
||
<para>
|
||
В самом PHP содержится достаточно большое количество встроенных функций
|
||
и языковых конструкций. Также есть функции, которые требуют, чтобы PHP был
|
||
собран со специфическими расширениями, в противном случае вы получите
|
||
сообщение о фатальной ошибке, вызванной использованием неизвестной функции.
|
||
Например, для того чтобы использовать <link linkend="ref.image">функции для работы с изображениями</link>,
|
||
например, <function>imagecreatetruecolor</function>, вам необходимо собрать PHP с
|
||
поддержкой <productname>GD</productname>. Или же для того, чтобы воспользоваться
|
||
функцией <function>mysql_connect</function>, вам необходима поддержка модуля
|
||
<link linkend="ref.mysql">MySQL</link>. Тем не менее, есть много встроенных
|
||
функций, которые доступны всегда: например <link linkend="ref.strings">функции обработки строк</link> и
|
||
<link linkend="ref.var">функции для работы с переменными</link>.
|
||
Вызвав <function>phpinfo</function> или <function>get_loaded_extensions</function>,
|
||
вы можете узнать, поддержка каких модулей есть в используемом вами PHP.
|
||
Также следует учесть, что поддержка некоторых дополнительных расширений
|
||
включена по умолчанию, и что сама документация к PHP разбита по расширениям.
|
||
Ознакомьтесь с разделами <link linkend="configuration">Конфигурация</link>,
|
||
<link linkend="install">Установка</link>, а также с документацией
|
||
непосредственно к дополнительным расширениям для получения более детальной
|
||
информации о том, как настроить ваш PHP.
|
||
</para>
|
||
<para>
|
||
Более подробную информацию о том, как следует читать и интерпретировать
|
||
прототипы функций, вы можете найти в разделе <link linkend="about.prototypes">Как правильно
|
||
читать описания функций</link>. Очень важно понимать, что возвращает функция,
|
||
или как именно она модифицирует передаваемые аргументы. Например,
|
||
функция <function>str_replace</function> возвращает модифицированную строку,
|
||
в то время как функция <function>usort</function> работает с фактически
|
||
переданной переменной. Каждая страница документации также содержит
|
||
информацию, которая специфична для данной функции, например, информацию о
|
||
передаваемых параметрах, изменениях в поведении, возвращаемых
|
||
значениях в случае как удачного, так и неудачного выполнения, доступности
|
||
функции в различных версиях. Знание и применение этих (порой даже незаметных)
|
||
нюансов очень важно для написания корректного PHP-кода.
|
||
</para>
|
||
<note>
|
||
<simpara>
|
||
Если в функцию передаются не те аргументы, которые она ожидает,
|
||
например, массив (<type>array</type>) вместо строки (<type>string</type>),
|
||
возвращаемое значение функции не определено. Скорее всего
|
||
в этом случае будет возвращен &null;, но это просто соглашение,
|
||
на него нельзя полагаться.
|
||
</simpara>
|
||
</note>
|
||
<para>
|
||
Ознакомьтесь также с описанием функции <function>function_exists</function>,
|
||
<link linkend="funcref">справочником функций</link> и функциями
|
||
<function>get_extension_funcs</function> и
|
||
<function>dl</function>.
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.anonymous">
|
||
<title>Анонимные функции</title>
|
||
|
||
<simpara>
|
||
Анонимные функции, также известные как замыкания (<literal>closures</literal>),
|
||
позволяют создавать функции, не имеющие определенных имен.
|
||
Они наиболее полезны в качестве значений
|
||
<link linkend="language.types.callback">callback</link>-параметров,
|
||
но также могут иметь и множество других применений.
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Пример анонимной функции</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
echo preg_replace_callback('~-([a-z])~', function ($match) {
|
||
return strtoupper($match[1]);
|
||
}, 'hello-world');
|
||
// выведет helloWorld
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<simpara>
|
||
Замыкания также могут быть использованы в качестве значений
|
||
переменных; PHP автоматически преобразует такие выражения
|
||
в экземпляры внутреннего класса <classname>Closure</classname>.
|
||
Присвоение замыкания переменной использует тот же синтаксис,
|
||
что и для любого другого присвоения, включая завершающую
|
||
точку с запятой:
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Пример присвоения анонимной функции переменной</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$greet = function($name)
|
||
{
|
||
printf("Hello %s\r\n", $name);
|
||
};
|
||
|
||
$greet('World');
|
||
$greet('PHP');
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<simpara>
|
||
Замыкания могут также наследовать переменные из родительской
|
||
области видимости. Любая подобная переменная должна быть
|
||
объявлена в заголовке функции. Наследование переменных из
|
||
родительской области видимости <emphasis>не</emphasis> то же
|
||
самое, что использование глобальных переменных.
|
||
Глобальные переменные существуют в глобальной области видимости,
|
||
которая не меняется, вне зависимости от того, какая функция
|
||
выполняется в данный момент. Родительская область видимости
|
||
- это функция, в которой было объявлено замыкание (не обязательно
|
||
та же самая, из которой оно было вызвано). Смотрите следующий
|
||
пример:
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Замыкания и область видимости</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
// Базовая корзина покупок, содержащая список добавленных
|
||
// продуктов и количество каждого продукта. Включает метод,
|
||
// вычисляющий общую цену элементов корзины с помощью
|
||
// callback-замыкания.
|
||
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
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<simpara>
|
||
Анонимные функции реализованы с помощью класса
|
||
<link linkend="class.closure">
|
||
<classname>Closure</classname></link>.
|
||
</simpara>
|
||
|
||
<sect2 role="changelog">
|
||
&reftitle.changelog;
|
||
<para>
|
||
<informaltable>
|
||
<tgroup cols="2">
|
||
<thead>
|
||
<row>
|
||
<entry>&Version;</entry>
|
||
<entry>&Description;</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>5.4.0</entry>
|
||
<entry>
|
||
Стало возможным использовать <varname>$this</varname>
|
||
в анонимных функциях.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>5.3.0</entry>
|
||
<entry>
|
||
Появление анонимных функций.
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2 role="notes">
|
||
&reftitle.notes;
|
||
<note>
|
||
<simpara>
|
||
Совместно с замыканиями можно использовать функции
|
||
<function>func_num_args</function>,
|
||
<function>func_get_arg</function> и <function>func_get_args</function>.
|
||
</simpara>
|
||
</note>
|
||
</sect2>
|
||
|
||
</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
|
||
-->
|