PHP.mk документација

match

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

control-structures.match.php PHP.net прокси Преводот се освежува
Оригинал на PHP.net
Патека control-structures.match.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + превод во позадина Кодовите, табелите и белешките остануваат читливи во истиот тек.
match

Референца за `control-structures.match.php` со подобрена типографија и навигација.

control-structures.match.php

match

(PHP 8)

На match изразот гранки за евалуација врз основа на проверка на идентитет на вредност. Слично на switch изјава, еден match израз има субјект израз што се споредува со повеќе алтернативи. За разлика од switch, тој ќе се евалуира до вредност многу како тернарни изрази. За разлика од switch, споредбата е проверка на идентитет (===) наместо слаба проверка на еднаквост (==). Изразите за совпаѓање се достапни од PHP 8.0.0.

Пример #1 Структура на match expression

<?php
$return_value
= match (subject_expression) {
single_conditional_expression => return_expression,
conditional_expression1, conditional_expression2 => return_expression,
};
?>

Пример #2 Основен match usage

<?php
$food
= 'cake';

$return_value = match ($food) {
'apple' => 'This food is an apple',
'bar' => 'This food is a bar',
'cake' => 'This food is a cake',
};

var_dump($return_value);
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

string(19) "This food is a cake"

Пример #3 Пример за користење match со оператори за споредба

<?php
$age
= 18;

$output = match (true) {
$age < 2 => "Baby",
$age < 13 => "Child",
$age <= 19 => "Teenager",
$age >= 40 => "Old adult",
$age > 19 => "Young adult",
};

var_dump($output);
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

string(8) "Teenager"

Забелешка: Резултатот од match изразот не мора да се користи.

Забелешка: Кога е match изразот се користи како самостоен израз, тој must мора да заврши со точка и запирка ;.

На match изразот е сличен на switch изјава, но има некои клучни разлики:

  • А match раката ги споредува вредностите строго (===) наместо лабаво како што прави изјавата switch.
  • А match изразот враќа вредност.
  • match краците не поминуваат до подоцнежните случаи на начинот на кој switch изјавите го прават тоа.
  • А match изразот мора да биде исцрпен.

за листа на сите овие функции и соодветните switch изјави, match изразите се извршуваат од рака до рака. На почетокот, не се извршува никаков код. Условните изрази се проценуваат само ако сите претходни условни изрази не успеале да се совпаднат со изразот на субјектот. Само изразот за враќање што одговара на условниот израз што се совпаѓа ќе биде проценет. На пример:

<?php
$result
= match ($x) {
foo() => 'value',
$this->bar() => 'value', // $this->bar() isn't called if foo() === $x
$this->baz => beep(), // beep() isn't called unless $x === $this->baz
// etc.
};
?>

match краците на изразот може да содржат повеќе изрази разделени со запирка. Тоа е логичко ИЛИ, и е кратенка за повеќе краци за совпаѓање со истата страна од десната страна.

<?php
$result
= match ($x) {
// This match arm:
$a, $b, $c => 5,
// Is equivalent to these three match arms:
$a => 5,
$b => 5,
$c => 5,
};
?>

Посебен случај е default образец. Овој образец совпаѓа со сè што не било претходно совпаднато. На пример:

<?php
$expressionResult
= match ($condition) {
1, 2 => foo(),
3, 4 => bar(),
default =>
baz(),
};
?>

Забелешка: Повеќе стандардни обрасци ќе предизвикаат E_FATAL_ERROR error.

А match изразот мора да биде исцрпен. Ако изразот на субјектот не е обработен од ниту еден крак за совпаѓање, а UnhandledMatchError се фрла.

Пример #4 Пример за нетретиран израз за совпаѓање

<?php
$condition
= 5;

try {
match (
$condition) {
1, 2 => foo(),
3, 4 => bar(),
};
} catch (
\UnhandledMatchError $e) {
var_dump($e);
}
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

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
}

Користење изрази за совпаѓање за обработка на проверки што не се идентитет

Можно е да се користи match израз за обработка на условни случаи што не се идентитет со користење true како израз на субјектот.

Пример #5 Користење генерализирани изрази за совпаѓање за разгранување на опсези на цели броеви

<?php

$age
= 23;

$result = match (true) {
$age >= 65 => 'senior',
$age >= 25 => 'adult',
$age >= 18 => 'young adult',
default =>
'kid',
};

var_dump($result);
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

string(11) "young adult"

Пример #6 Користење генерализирани изрази за совпаѓање за разгранување на содржина на стринг

<?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);
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

string(2) "fr"

Белешки од корисници 10 белешки

darius точка restivan на gmail точка com
пред 4 години
This will allow for a nicer FizzBuzz solution:

<?php

function fizzbuzz($num) {
    print match (0) {
        $num % 15 => "FizzBuzz" . PHP_EOL,
        $num % 3  => "Fizz" . PHP_EOL,
        $num % 5  => "Buzz" . PHP_EOL,
        default   => $num . PHP_EOL,
    };
}

for ($i = 0; $i <=100; $i++)
{
    fizzbuzz($i);
}
Анонимен
пред 4 години
<?php
function days_in_month(string $month, $year): int
{
    return match(strtolower(substr($month, 0, 3))) {
        'jan' => 31,
        'feb' => is_leap($year) ? 29 : 28,
        'mar' => 31,
        'apr' => 30,
        'may' => 31,
        'jun' => 30,
        'jul' => 31,
        'aug' => 31,
        'sep' => 30,
        'oct' => 31,
        'nov' => 30,
        'dec' => 31,
        default => throw new InvalidArgumentException("Bogus month"),
    };
}
?>

can be more concisely written as

<?php
function days_in_month(string $month, $year): int
{
    return match(strtolower(substr($month, 0, 3))) {
        'apr', 'jun', 'sep',  'nov'  => 30,        
        'jan', 'mar', 'may', 'jul', 'aug',  'oct', 'dec'  => 31,
        'feb' => is_leap($year) ? 29 : 28,
        default => throw new InvalidArgumentException("Bogus month"),
    };
}
?>
Хејли Вотсон
пред 5 години
As well as being similar to a switch, match expressions can be thought of as enhanced lookup tables — for when a simple array lookup isn't enough without extra handling of edge cases, but a full switch statement would be overweight.

For a familiar example, the following
<?php

function days_in_month(string $month): int
{
    static $lookup = [
    'jan' => 31,
    'feb' => 0,
    'mar' => 31,
    'apr' => 30,
    'may' => 31,
    'jun' => 30,
    'jul' => 31,
    'aug' => 31,
    'sep' => 30,
    'oct' => 31,
    'nov' => 30,
    'dec' => 31
    ];

    $name = strtolower(substr($name, 0, 3));

    if(isset($lookup[$name])) {
        if($name == 'feb') {
            return is_leap($year) ? 29 : 28;
        } else {
            return $lookup[$name];
        }
    }
    throw new InvalidArgumentException("Bogus month");
}

?>

with the fiddly stuff at the end, can be replaced by

<?php
function days_in_month(string $month): int
{
    return match(strtolower(substr($month, 0, 3))) {
        'jan' => 31,
        'feb' => is_leap($year) ? 29 : 28,
        'mar' => 31,
        'apr' => 30,
        'may' => 31,
        'jun' => 30,
        'jul' => 31,
        'aug' => 31,
        'sep' => 30,
        'oct' => 31,
        'nov' => 30,
        'dec' => 31,
        default => throw new InvalidArgumentException("Bogus month"),
    };
}
?>

Which also takes advantage of "throw" being handled as of PHP 8.0 as an expression instead of a statement.
thomas на zuschneid точка de
3 години пред
While match allows chaining multiple conditions with ",", like:
<?php
$result = match ($source) {
    cond1, cond2 => val1,
    default => val2
};
?>
it seems not valid to chain conditions with default, like:
<?php
$result = match ($source) {
    cond1 => val1,
    cond2, default => val2
};
?>
tolga точка ulas на tolgaulas точка com
пред 2 години
Yes it currently does not support code blocks but this hack works:

match ($foo){
    'bar'=>(function(){
        echo "bar";
    })(),
    default => (function(){
        echo "baz";
    })()
};
php на joren точка dev
пред 4 години
If you want to execute multiple return expressions when matching a conditional expression, you can do so by stating all return expressions inside an array.

<?php
    $countries = ['Belgium', 'Netherlands'];
    $spoken_languages = [
        'Dutch' => false,
        'French' => false,
        'German' => false,
        'English' => false,
    ];

    foreach ($countries as $country) {
        match($country) {
            'Belgium' => [
                $spoken_languages['Dutch'] = true,
                $spoken_languages['French'] = true,
                $spoken_languages['German'] = true,
            ],
            'Netherlands' => $spoken_languages['Dutch'] = true,
            'Germany' => $spoken_languages['German'] = true,
            'United Kingdom' => $spoken_languages['English'] = true,
        };
    }

    var_export($spoken_languages); 
    // array ( 'Dutch' => true, 'French' => true, 'German' => true, 'English' => false, )

?>
Ghanshyam Katriya(anshkatriya at gmail)
3 години пред
I use match instead of storing PDOStatement::rowCount() result and chaining if/elseif conditions or use the ugly switch/break :

<?php

$sql = <<<SQL
    INSERT INTO ...
    ON DUPLICATE KEY UPDATE ...
    SQL;

$upkeep = $pdo->prepare($sql);

$count_untouched = 0;
$count_inserted = 0;
$count_updated = 0;

foreach ($data as $record) {
    $upkeep->execute($record);
    match ($upkeep->rowCount()) {
        0 => $count_untouched++,
        1 => $count_inserted++,
        2 => $count_updated++,
    };
}

echo "Untouched rows : {$count_untouched}\r\n";
echo "Inserted rows : {$count_inserted}\r\n";
echo "Updated rows : {$count_updated}\r\n";
mark на manngo точка net
пред 4 години
While you can’t polyfill a language construct, you can mimic the basic behaviour with a simple array.

Using example 2 above:

<?php
    $food = 'apple';
    $return_value = match ($food) {
        'apple' => 'This food is an apple',
        'bar' => 'This food is a bar',
        'cake' => 'This food is a cake',
    };    
    print $return_value;
?>

… you can get something similar with:

<?php
    $food = 'apple';    
    $return_value = [
        'apple' => 'This food is an apple',
        'bar' => 'This food is a bar',
        'cake' => 'This food is a cake',
    ][$food];
    print $return_value;
?>
tm
пред 4 години
If you are using a match expression for non-identity checks as described above make sure whatever you are using is actually returning `true` on success.

Quite often you rely on truthy vs. falsy when using if conditions and that will not work for match (for example `preg_match`). Casting to bool will solve this issue.
yawarmushtaq52 на gmail точка com
1 месец пред
Since `match` is a better alternative in MOST cases for modern software, adding this comment so that if someone googles "`switch` in PHP" then this page also shows in the search results.
На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.