match


php128 apg

Behavior similar to switch.

It is available as of PHP 8.0.0

The match expression branches evaluation based on an identity check of a value.

A match expression has a subject expression that is compared against multiple alternatives.

Unlike switch:

1. it will evaluate to a value much like ternary expressions.

2. the comparison is an identity check (===) rather than a weak equality check (==)





The result of a match expression does not need to be used.

A match expression must be terminated by a semicolon.



<?php

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

?>

subject_expression


The expression to be analized.



single_conditional_expression => return_expression


The single conditional expression and the return value for it.



conditional_expression1


The first expression to be analized.



conditional_expression2 => return_expression


The second conditional expression and the return value for it.



  1 EXERCISE   

<?php

function wordify($x) {
    return match (
$x) {
        
=> 'Zero',
        
=> 'One',
        
=> 'Two',
        
=> 'Three',
        
=> 'Four',
        
=> 'Five',
        
=> 'Six',
        
=> 'Seven',
        
=> 'Eight',
        
=> 'Nine',
    };
}

for (
$i 0$i <= 5$i++) {
    print 
wordify($i) . "<br>";
}


?>

 RESULT   

Zero
One
Two
Three
Four
Five

Parse error ...
PHP prior to version 8.0.0.


  2 EXERCISE   

<?php

echo '- - - - - - - - - - - - - - -<br>';

function 
print_bool($bool) {
    echo match (
$bool) {
        
true => "true<br>",
        
false => "false<br>"
    
};
}

print_bool(true);
print_bool(false);

echo 
'- - - - - - - - - - - - - - -<br>';

function 
get_value($i) {
    return match (
$i) {
        
=> 1,
        
=> 2,
        default => 
'default',
    };
}

echo 
get_value(0) . "<br>";
echo 
get_value(1) . "<br>";
echo 
get_value(2) . "<br>";
echo 
get_value(3) . "<br>";

echo 
'- - - - - - - - - - - - - - -<br>';

function 
get_range($i) {
    return match (
true) {
        
$i >= 50 => '50+',
        
$i >= 40 => '40-50',
        
$i >= 30 => '30-40',
        
$i >= 20 => '20-30',
        
$i >= 10 => '10-20',
        default => 
'0-10',
    };
}

echo 
get_range(22) . "<br>";
echo 
get_range(0) . "<br>";
echo 
get_range(59) . "<br>";
echo 
get_range(13) . "<br>";
echo 
get_range(39) . "<br>";
echo 
get_range(40) . "<br>";

echo 
'- - - - - - - - - - - - - - -<br>';

match (
1) {
    
=> print "Executed<br>",
};

echo 
'- - - - - - - - - - - - - - -<br>';

?>

 RESULT   

- - - - - - - - - - - - - - -
true
false
- - - - - - - - - - - - - - -
default
1
2
default
- - - - - - - - - - - - - - -
20-30
0-10
50+
10-20
30-40
40-50
- - - - - - - - - - - - - - -
Executed
- - - - - - - - - - - - - - -

Parse error ...
PHP prior to version 8.0.0.


  3 EXERCISE   

<?php

echo '- - - - - - - - - - - - - - -<br>';

$x = match (true) {};

echo 
'- - - - - - - - - - - - - - -<br>';

?>

 RESULT   

Fatal error ...
PHP version 8.0.0.

Parse error ...
PHP prior to version 8.0.0.

  4 EXERCISE   

<?php

echo '- - - - - - - - - - - - - - -<br>';

function 
get_value1($i) {
    return match (
$i) {
        
=> 1,
        
=> 2,
    };
}

echo 
get_value1(1) . "<br>";
echo 
get_value1(2) . "<br>";
echo 
get_value1(3) . "<br>";

echo 
'- - - - - - - - - - - - - - -<br>';

?>

 RESULT   

- - - - - - - - - - - - - - -
1
2

Fatal error ...
PHP version 8.0.0.

Parse error ...
PHP prior to version 8.0.0.


  5 EXERCISE   

<?php

echo '5.1
<br> - - - <br>'
;

function 
is_working_day($day) {
    return match (
$day) {
        
1=> false,
        
2345=> true,
    };
}

for (
$i 1$i <= 7$i++) {
    
var_dump(is_working_day($i));
    echo 
'<br>';
}

echo 
'<br>5.2
<br> - - -<br>'
;

function 
dump_and_return($string) {
    
var_dump($string);
    echo 
'<br>';
    return 
$string;
}

var_dump(match ('foo') {
    
'foo' => dump_and_return('foo'),
    
'bar' => dump_and_return('bar'),
});

echo 
'<br><br>5.3
<br> - - -<br>'
;

function 
wrong() {
    throw new 
Exception();
}

var_dump(match (0) {
    
null => wrong(),
    
false => wrong(),
    
0.0 => wrong(),
    [] => 
wrong(),
    
'' => wrong(),
    
=> 'int',
});

echo 
'<br>';

function 
get_value() {
    return 
0;
}

var_dump(match (get_value()) {
    
null => wrong(),
    
false => wrong(),
    
0.0 => wrong(),
    [] => 
wrong(),
    
'' => wrong(),
    
=> 'int',
    default => 
'default',
});

echo 
'<br><br>5.4
<br> - - -<br>'
;

function 
wrong1() {
    throw new 
Exception();
}

function 
test_int($char) {
    return match (
$char) {
        
=> wrong1(),
        
=> wrong1(),
        
=> wrong1(),
        
=> wrong1(),
        
=> wrong1(),
        
=> wrong1(),
        
=> wrong1(),
        
=> wrong1(),
        
=> wrong1(),
        
=> wrong1(),
        default => 
'Not matched',
    };
}

foreach (
range(09) as $int) {
    
var_dump((string) $int);
    echo 
'<br>';
    
var_dump(test_int((string) $int));
    echo 
'<br>';
}

function 
test_string($int) {
    return match (
$int) {
        
'0' => wrong1(),
        
'1' => wrong1(),
        
'2' => wrong1(),
        
'3' => wrong1(),
        
'4' => wrong1(),
        
'5' => wrong1(),
        
'6' => wrong1(),
        
'7' => wrong1(),
        
'8' => wrong1(),
        
'9' => wrong1(),
        default => 
'Not matched',
    };
}

foreach (
range(09) as $int) {
    
var_dump($int);
    echo 
'<br>';
    
var_dump(test_string($int));
    echo 
'<br>';
}

echo 
'<br>5.5
<br> - - -<br>'
;

function 
wrong2() {
    throw new 
Exception();
}

echo match (
true) {
    
'truthy' => wrong2(),
    [
'truthy'] => wrong2(),
    new 
stdClass() => wrong2(),
    
=> wrong2(),
    
1.0 => wrong2(),
    
true => "true<br>",
};

echo 
'<br>5.6
<br> - - -<br>'
;

function 
wrong3() {
    throw new 
Exception();
}

echo match (
false) {
    
'' => wrong3(),
    [] => 
wrong3(),
    
=> wrong3(),
    
0.0 => wrong3(),
    
false => "false<br>",
};

echo 
'<br>5.7
<br> - - -<br>'
;

$value 1;

echo match (
$value) {
    
=> 1,
    
=> 2,
    
=> 3,
    
=> 4,
    
=> 5,
    
=> 6,
};
echo 
"<br>";

echo match (
$value) {
    
2=> '2, 1',
    
=> 1,
    
=> 3,
    
=> 4,
    
=> 5,
};
echo 
"<br>";

echo match (
$value) {
    
1=> '1, 1',
    
2=> '2, 2',
    
3=> '3, 3',
    
4=> '4, 4',
    
5=> '5, 5',
};
echo 
"<br>";

echo match (
$value) {
    
=> 1,
    
=> 2,
};
echo 
"<br>";

echo match (
$value) {
    
2=> '2, 1',
    
=> 1,
};
echo 
"<br>";

echo match (
$value) {
    
1=> '1, 1',
    
=> 1,
};
echo 
"<br>";

echo 
'<br>5.8
<br> - - -<br>'
;

function 
test($value) {
    echo match (
$value) {
        
=> '1 int',
        
'1' => '1 string',
        
=> '2 int',
        
'2' => '2 string',
        
=> '3 int',
        
'3' => '3 string',
        
=> '4 int',
        
'4' => '4 string',
        
=> '5 int',
        
'5' => '5 string',
    };
    echo 
"<br>";
}

test(1);
test('1');
test(2);
test('2');
test(3);
test('3');
test(4);
test('4');
test(5);
test('5');

echo 
'<br>5.9
<br> - - -<br>'
;


function 
print_bool($bool) {
    echo match (
$bool) {
        
false,
        
0,
            => 
"false<br>",
        
true,
        
1,
            => 
"true<br>",
        default,
            => 
"not bool<br>",
    };
}

print_bool(false);
print_bool(0);
print_bool(true);
print_bool(1);
print_bool(2);
print_bool('foo');

echo 
' - - -<br>';

?>

 RESULT   

5.1
- - -
bool(false)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(false)

5.2
- - -
string(3) "foo"
string(3) "foo"

5.3
- - -
string(3) "int"
string(3) "int"

5.4
- - -
string(1) "0"
string(11) "Not matched"
string(1) "1"
string(11) "Not matched"
string(1) "2"
string(11) "Not matched"
string(1) "3"
string(11) "Not matched"
string(1) "4"
string(11) "Not matched"
string(1) "5"
string(11) "Not matched"
string(1) "6"
string(11) "Not matched"
string(1) "7"
string(11) "Not matched"
string(1) "8"
string(11) "Not matched"
string(1) "9"
string(11) "Not matched"
int(0)
string(11) "Not matched"
int(1)
string(11) "Not matched"
int(2)
string(11) "Not matched"
int(3)
string(11) "Not matched"
int(4)
string(11) "Not matched"
int(5)
string(11) "Not matched"
int(6)
string(11) "Not matched"
int(7)
string(11) "Not matched"
int(8)
string(11) "Not matched"
int(9)
string(11) "Not matched"

5.5
- - -
true

5.6
- - -
false

5.7
- - -
1
2, 1
1, 1
1
2, 1
1, 1

5.8
- - -
1 int
1 string
2 int
2 string
3 int
3 string
4 int
4 string
5 int
5 string

5.9
- - -
false
false
true
true
not bool
not bool
- - -

The above results are displayed when the PHP version is 8.0.0 or higher.

When in previous versions, precisely because match is not defined Parse error ... is then displayed.


  6 EXERCISE   

<?php

echo ' - - - <br>';

assert((function () {
    match (
'foo') {
        
'foo''bar' => false,
        
'baz' => 'a',
        default => 
'b',
    };
})());

echo 
' - - -<br>';

?>

  7 EXERCISE   

<?php

echo ' - - - <br>';

// opcache can't be certain 
// Test::usesRef is actually this method
if (!class_exists('Test')) {
    class 
Test {
        public static function 
usesRef(&$x) {
            
$x 'modified';
        }
        public static function 
usesValue($x) {
            echo 
"usesValue $x<br>";
        }
    }
}

function 
main() {
    
$i 0;
    
Test::usesValue(match(true) { true => $i });
    echo 
"i is $i<br>";
    
$j 1;
    
Test::usesRef(match(true) { true => $j });
    echo 
"j is $j<br>";
}
main();

echo 
' - - -<br>';

?>

  8 EXERCISE   

<?php

echo ' - - - <br>';

// opcache can't be certain 
// Test::usesRef is actually this method
if (!class_exists('Test')) {
    class 
Test {
        public static function 
usesRef(&$x) {
            
$x 'modified';
        }
        public static function 
usesValue($x) {
            echo 
"usesValue $x<br>";
        }
    }
}

function 
main(int $i): int {
    
Test::usesValue(match(true) { true => $i });
    
Test::usesValue(match($i) { 42 => $i });
    
var_dump($i);
    
Test::usesRef(match(true) { true => $i });
    
var_dump($i);
}

try {
    
main(42);
} catch (
Error $e) {
    
printf("Caught %s<br>"$e->getMessage());
};

echo 
' - - -<br>';

?>

  9 EXERCISE   

<?php

echo ' - - - <br>';

set_error_handler(function ($errno$message) {
    throw new 
Exception("Custom error handler: $message");
});

echo match (
$undefVar) {
   default => 
"This should not get printed 
   with or without opcache<br>"
,
   
1234=> "Also should not be printed<br>",
};

echo 
"unreachable<br>";

echo 
' - - -<br>';

?>

  10 EXERCISE   

<?php

echo ' - - - <br>';

try {
    
var_dump(match(true) {
        
1234=> 'foo',
    });
} catch (
Error $e) {
    
var_dump((string) $e);
}

echo 
'<br><br>';

try {
    
var_dump(match(6) {
        
1234=> 'foo',
    });
} catch (
Error $e) {
    
var_dump((string) $e);
}

echo 
'<br><br>';

try {
    
var_dump(match('3') {
        
1234=> 'foo',
    });
} catch (
Error $e) {
    
var_dump((string) $e);
}

echo 
'<br><br>';

var_dump(match(3) {
    
1234=> 'foo',
});

echo 
'<br><br>';

var_dump(match(true) {
    
1234=> 'foo',
    default => 
'bar',
});

echo 
'<br><br>';

var_dump(match(6) {
    
1234=> 'foo',
    default => 
'bar',
});

echo 
'<br><br>';

var_dump(match('3') {
    
1234=> 'foo',
    default => 
'bar',
});

echo 
'<br><br>';

var_dump(match(3) {
    
1234=> 'foo',
    default => 
'bar',
});

echo 
'<br>- - -<br>';

?>

  11 EXERCISE   

<?php

echo ' - - - <br>';

match (
1) {
    default => 
'foo',
    
=> 'bar',
    
=> 'baz',
    default => 
'qux',
};

echo 
'<br>- - -<br>';

?>