1
0
mirror of https://github.com/php/doc-ru.git synced 2026-03-27 17:22:14 +01:00
Files
archived-doc-ru/reference/funchand/functions/create-function.xml
2022-04-06 14:51:28 +03:00

347 lines
13 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: 39752929cd4ab78db8a7310dfb328444c558df99 Maintainer: shein Status: ready -->
<!-- Reviewed: no -->
<refentry xml:id="function.create-function" xmlns="http://docbook.org/ns/docbook">
<refnamediv>
<refname>create_function</refname>
<refpurpose>Создаёт функцию динамически, оценивая строку кода</refpurpose>
</refnamediv>
<refsynopsisdiv>
&warn.deprecated.function-7-2-0.removed-8-0-0;
</refsynopsisdiv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<type>string</type><methodname>create_function</methodname>
<methodparam><type>string</type><parameter>args</parameter></methodparam>
<methodparam><type>string</type><parameter>code</parameter></methodparam>
</methodsynopsis>
<para>
Создаёт функцию динамически из переданных параметров
и возвращает её уникальное имя.
</para>
<caution>
<para>
Функция внутри себя делает вызов функции <function>eval</function>, а значит
имеет такие же проблемы с безопасностью, как и <function>eval</function>.
Также у неё плохие характеристики производительности и использования памяти,
поскольку созданные функции являются глобальными и не могут быть освобождены.
</para>
<para>
Используйте
<link linkend="functions.anonymous">анонимные функции</link>.
</para>
</caution>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
Обычно рекомендуется передавать параметры в виде строк
<link linkend="language.types.string.syntax.single">с одинарной кавычкой</link>.
При использовании строк <link linkend="language.types.string.syntax.double">с двойной кавычкой</link>
имена переменных в коде должны быть тщательно экранированы,
например, вот так: <literal>\$somevar</literal>.
<variablelist>
<varlistentry>
<term><parameter>args</parameter></term>
<listitem>
<para>
Аргументы функции в виде строки, разделённой запятыми.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>code</parameter></term>
<listitem>
<para>
Код функции.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Возвращает уникальное имя функции в виде строки&return.falseforfailure;.
Обратите внимание, что имя содержит непечатаемый символ (<literal>"\0"</literal>),
поэтому следует соблюдать осторожность при печати имени или включении его в любую другую строку.
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title>
Создание функции динамически с помощью <function>create_function</function> или анонимных функций
</title>
<para>
Вы можете использовать динамически созданную функцию, чтобы, например,
создать функцию на основе информации, собранной во время выполнения.
Во-первых, используя функцию <function>create_function</function>:
</para>
<programlisting role="php">
<![CDATA[
<?php
$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo $newfunc(2, M_E) . "\n";
?>
]]>
</programlisting>
<para>
Теперь тот же код, используя <link linkend="functions.anonymous">анонимную функцию</link>;
обратите внимание, что код и аргументы больше не содержатся в строках:
</para>
<programlisting role="php">
<![CDATA[
<?php
$newfunc = function($a,$b) { return "ln($a) + ln($b) = " . log($a * $b); };
echo $newfunc(2, M_E) . "\n";
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
ln(2) + ln(2.718281828459) = 1.6931471805599
]]>
</screen>
</example>
</para>
<para>
<example>
<title>
Создание общей функции-обработчика с помощью <function>create_function</function> или анонимных функций
</title>
<para>
Другим вариантом использования может быть общая функция-обработчик,
которая может применять набор операций к списку параметров:
</para>
<programlisting role="php">
<![CDATA[
<?php
function process($var1, $var2, $farr)
{
foreach ($farr as $f) {
echo $f($var1, $var2) . "\n";
}
}
// создаём кучу математических функций
$farr = array(
create_function('$x,$y', 'return "тригонометрия: ".(sin($x) + $x*cos($y));'),
create_function('$x,$y', 'return "гипотенуза: ".sqrt($x*$x + $y*$y);'),
create_function('$a,$b', 'if ($a >=0) {return "b*a^2 = ".$b*sqrt($a);} else {return false;}'),
create_function('$a,$b', "return \"min(b^2+a, a^2,b) = \".min(\$a*\$a+\$b,\$b*\$b+\$a);"),
create_function('$a,$b', 'if ($a > 0 && $b != 0) {return "ln(a)/b = ".log($a)/$b; } else { return false; }')
);
echo "\nИспользование первого массива динамических функций\n";
echo "Параметры: 2.3445, M_PI\n";
process(2.3445, M_PI, $farr);
// теперь создаём кучу функций обработки строк
$garr = array(
create_function('$b,$a', 'if (strncmp($a, $b, 3) == 0) return "** \"$a\" '.
'и \"$b\"\n** для меня одинаковы! (смотря по первым 3 символам)";'),
create_function('$a,$b', 'return "CRCs: " . crc32($a) . ", ".crc32($b);'),
create_function('$a,$b', 'return "similar(a,b) = " . similar_text($a, $b, $p) . "($p%)";')
);
echo "\nИспользование второго массива динамических функций\n";
process("Варкалось. Хливкие шорьки пырялись по наве", "Варан ползёт", $garr);
?>
]]>
</programlisting>
<para>
И снова, тот же самый код с использованием <link linkend="functions.anonymous">анонимных функций</link>.
Обратите внимание, что имена переменных в коде больше не нужно экранировать,
поскольку они не заключены в строку.
</para>
<programlisting role="php">
<![CDATA[
<?php
function process($var1, $var2, $farr)
{
foreach ($farr as $f) {
echo $f($var1, $var2) . "\n";
}
}
// создаём кучу математических функций
$farr = array(
function($x,$y) { return "тригонометрия: ".(sin($x) + $x*cos($y)); },
function($x,$y) { return "гипотенуза: ".sqrt($x*$x + $y*$y); },
function($a,$b) { if ($a >=0) {return "b*a^2 = ".$b*sqrt($a);} else {return false;} },
function($a,$b) { return "min(b^2+a, a^2,b) = " . min($a*$a+$b, $b*$b+$a); },
function($a,$b) { if ($a > 0 && $b != 0) {return "ln(a)/b = ".log($a)/$b; } else { return false; } }
);
echo "\nИспользование первого массива динамических функций\n";
echo "Параметры: 2.3445, M_PI\n";
process(2.3445, M_PI, $farr);
// теперь создаём кучу функций обработки строк
$garr = array(
function($b,$a) { if (strncmp($a, $b, 3) == 0) return "** \"$a\" " .
"и \"$b\"\n** для меня одинаковы! (смотря по первым 3 символам)"; },
function($a,$b) { return "CRCs: " . crc32($a) . ", ".crc32($b); },
function($a,$b) { return "similar(a,b) = " . similar_text($a, $b, $p) . "($p%)"; }
);
echo "\nИспользование второго массива динамических функций\n";
process("Варкалось. Хливкие шорьки пырялись по наве", "Варан ползёт", $garr);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Использование первого массива динамических функций
Параметры: 2.3445, M_PI
тригонометрия: -1.6291725057799
гипотенуза: 3.9199852871011
b*a^2 = 4.8103313314525
min(b^2+a, a^2,b) = 8.6382729035898
ln(a)/b = 0.27122299212594
Использование второго массива динамических функций
** "Варан ползёт" и "Варкалось. Хливкие шорьки пырялись по наве"
** для меня одинаковы! (смотря по первым 3 символам)
CRCs: 2672527412, 2269828269
similar(a,b) = 16(31.683168316832%)
]]>
</screen>
</example>
</para>
<para>
<example>
<title>Использование динамических функций в качестве callback-функций</title>
<para>
Возможно, самым распространённым использованием динамических функций
является передача их в качестве callback-функций, например,
при использовании <function>array_walk</function> или <function>usort</function>.
</para>
<programlisting role="php">
<![CDATA[
<?php
$av = array("the ", "a ", "that ", "this ");
array_walk($av, create_function('&$v,$k', '$v = $v . "mango";'));
print_r($av);
?>
]]>
</programlisting>
<para>
Преобразование приведённого выше кода в <link linkend="functions.anonymous">анонимную функцию</link>:
</para>
<programlisting role="php">
<![CDATA[
<?php
$av = array("о, ", "эх, ", "то ", "это ");
array_walk($av, create_function('&$v,$k', '$v = $v . "манго";'));
print_r($av);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[0] => о, манго
[1] => эх, манго
[2] => то манго
[3] => это манго
)
]]>
</screen>
<para>
Сортировка строк от самой длинной до самой короткой с помощью <function>create_function</function>:
</para>
<programlisting role="php">
<![CDATA[
<?php
$sv = array("мало", "много", "большая строка", "строка строка строка");
echo "Оригинальный массив:\n";
print_r($sv);
echo "Отсортированный:\n";
usort($sv, create_function('$a,$b','return strlen($b) - strlen($a);'));
print_r($sv);
?>
]]>
</programlisting>
<para>
Преобразование приведённого выше кода в <link linkend="functions.anonymous">анонимную функцию</link>:
</para>
<programlisting role="php">
<![CDATA[
<?php
$sv = array("мало", "много", "большая строка", "строка строка строка");
echo "Оригинальный массив:\n";
print_r($sv);
echo "Отсортированный:\n";
usort($sv, function($a,$b) { return strlen($b) - strlen($a); });
print_r($sv);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Оригинальный массив:
Array
(
[0] => мало
[1] => много
[2] => большая строка
[3] => строка строка строка
)
Отсортированный:
Array
(
[0] => строка строка строка
[1] => большая строка
[2] => много
[3] => мало
)
]]>
</screen>
</example>
</para>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><link linkend="functions.anonymous">Анонимные функции</link></member>
</simplelist>
</para>
</refsect1>
</refentry>
<!-- 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
-->