1
0
mirror of https://github.com/php/doc-ru.git synced 2026-04-23 07:18:12 +02:00
Files
archived-doc-ru/language/control-structures/match.xml
T
2024-05-29 00:39:01 +03:00

342 lines
10 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: 6c71b05df89358d7760a4740ed3fcfa1682eadb6 Maintainer: rjhdby Status: ready -->
<!-- Reviewed: no -->
<sect1 xml:id="control-structures.match" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>match</title>
<?phpdoc print-version-for="match"?>
<para>
Выражение <literal>match</literal> предназначено для ветвления потока исполнения на
основании проверки совпадения значения с заданным условием.
Аналогично оператору <literal>switch</literal>, выражение
<literal>match</literal> принимает на вход выражение, которое сравнивается
с множеством альтернатив. Но, в отличие от <literal>switch</literal>,
оно обрабатывает значение в стиле, больше похожем на тернарный оператор.
Также, в отличие от <literal>switch</literal>, используется строгое сравнение
(<code>===</code>), а не слабое (<code>==</code>).
Выражение match доступно начиная с PHP 8.0.0.
</para>
<example>
<title>Структура выражения <literal>match</literal></title>
<programlisting role="php">
<![CDATA[
<?php
$return_value = match (subject_expression) {
single_conditional_expression => return_expression,
conditional_expression1, conditional_expression2 => return_expression,
};
?>
]]>
</programlisting>
<example>
<title>Простой пример использования <literal>match</literal></title>
<programlisting role="php">
<![CDATA[
<?php
$food = 'cake';
$return_value = match ($food) {
'apple' => 'На столе лежит яблоко',
'banana' => 'На столе лежит банан',
'cake' => 'На столе стоит торт',
};
var_dump($return_value);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
string(35) "На столе стоит торт"
]]>
</screen>
</example>
<example>
<title>Пример использования выражения <literal>match</literal> с операторами сравнения</title>
<programlisting role="php">
<![CDATA[
<?php
$age = 18;
$output = match (true) {
$age < 2 => "Младенец",
$age < 13 => "Ребёнок",
$age <= 19 => "Подросток",
$age > 19 => "Молодой человек",
$age >= 40 => "Пожилой человек"
};
var_dump($output);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
string(8) "Подросток"
]]>
</screen>
</example>
<note>
<simpara>
Результат <literal>match</literal> использовать не обязательно.
</simpara>
</note>
<note>
<simpara>
Выражение <literal>match</literal> <emphasis>должно</emphasis> завершаться
точкой с запятой <literal>;</literal>.
</simpara>
</note>
</example>
<para>
Выражение <literal>match</literal> похоже на оператор
<literal>switch</literal> за исключением некоторых ключевых отличий:
<itemizedlist>
<listitem>
<simpara>
В отличие от switch, в <literal>match</literal> используется строгое сравнение (<code>===</code>).
</simpara>
</listitem>
<listitem>
<simpara>
Выражение <literal>match</literal> возвращает результат.
</simpara>
</listitem>
<listitem>
<simpara>
В <literal>match</literal> исполняется только одна, первая подошедшая, ветвь кода, тогда как
в <literal>switch</literal> происходит сквозное исполнение начиная с подошедшего условия и
до первого встретившегося оператора <literal>break</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Выражение <literal>match</literal> должно быть исчерпывающим.
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
Как и оператор <literal>switch</literal>, выражение <literal>match</literal>
последовательно проверяет на совпадение с заданными условиями.
Выполнение кода условий происходит лениво, т. е. код следующего условия выполняется только
если все предыдущие проверки провалились. Будет выполнена только одна ветвь кода,
соответствующая подошедшему условию.
Пример:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$result = match ($x) {
foo() => ...,
$this->bar() => ..., // $this->bar() не будет выполнен, если foo() === $x
$this->baz => beep(), // beep() будет выполнен только если $x === $this->baz
// и т. д.
};
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Условия в <literal>match</literal> могут быть множественными. В этом случае их следует разделять запятыми.
Множественные условия работают по принципу логического ИЛИ и, по сути, являются
сокращённой формой для случаев, когда несколько условий должны обрабатываться идентично.
</para>
<para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$result = match ($x) {
// Множественное условие:
$a, $b, $c => 5,
// Аналогично трём одиночным:
$a => 5,
$b => 5,
$c => 5,
};
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Также можно использовать шаблон <literal>default</literal>.
Этот шаблон совпадает с чем угодно, для чего не нашлось совпадений раньше.
К примеру:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$expressionResult = match ($condition) {
1, 2 => foo(),
3, 4 => bar(),
default => baz(),
};
?>
]]>
</programlisting>
</informalexample>
<note>
<simpara>
Использование нескольких шаблонов default приведёт к фатальной ошибке
<constant>E_FATAL_ERROR</constant>.
</simpara>
</note>
</para>
<para>
Выражение <literal>match</literal> должно быть исчерпывающим. Если
проверяемое выражение не совпало ни с одним из условий, то будет
выброшено исключение <classname>UnhandledMatchError</classname>.
</para>
<example>
<title>Пример необработанного выражения</title>
<programlisting role="php">
<![CDATA[
<?php
$condition = 5;
try {
match ($condition) {
1, 2 => foo(),
3, 4 => bar(),
};
} catch (\UnhandledMatchError $e) {
var_dump($e);
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
object(UnhandledMatchError)#1 (7) {
["message":protected]=>
string(33) "Unhandled match value of type int"
["string":"Error":private]=>
string(0) ""
["code":protected]=>
int(0)
["file":protected]=>
string(9) "/in/ICgGK"
["line":protected]=>
int(6)
["trace":"Error":private]=>
array(0) {
}
["previous":"Error":private]=>
NULL
}
]]>
</screen>
</example>
<sect2>
<title>Использование match для проверки сложных условий</title>
<para>
Выражение <literal>match</literal> можно использовать не только для проверки идентичности,
но и для любых выражений, возвращающих логическое значение. В этом случае в качестве входного
параметра передаётся выражение <code>true</code>.
</para>
<example>
<title>Использование match для ветвления в зависимости от вхождения в диапазоны целых чисел</title>
<programlisting role="php">
<![CDATA[
<?php
$age = 23;
$result = match (true) {
$age >= 65 => 'пожилой',
$age >= 25 => 'взрослый',
$age >= 18 => 'совершеннолетний',
default => 'ребёнок',
};
var_dump($result);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
string(11) "совершеннолетний"
]]>
</screen>
</example>
<example>
<title>Использование match для ветвления в зависимости от содержимого строки</title>
<programlisting role="php">
<![CDATA[
<?php
$text = 'Bienvenue chez nous';
$result = match (true) {
str_contains($text, 'Welcome') || str_contains($text, 'Hello') => 'en',
str_contains($text, 'Bienvenue') || str_contains($text, 'Bonjour') => 'fr',
// ...
};
var_dump($result);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
string(2) "fr"
]]>
</screen>
</example>
</sect2>
</sect1>
<!-- 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
-->