Files
php-doc-ru/language/functions.xml
Shein Alexey 1b2a504b74 Updated translation.
git-svn-id: https://svn.php.net/repository/phpdoc/ru/trunk@322591 c90b9560-bf6c-de11-be94-00142212c4b1
2012-01-23 06:11:18 +00:00

838 lines
32 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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>
Если вы хотите, что бы аргумент всегда передавался по ссылке,
вы можете указать амперсанд (&amp;) перед именем аргумента в описании
функции:
</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>
Для того, чтобы функция возвращала результат по ссылке, вам
необходимо использовать оператор &amp; и при описании функции,
и при присвоении переменной возвращаемого значения:
</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
-->