Issues (125)

src/Helper/RouteMatcher.php (1 issue)

1
<?php
2
3
/**
4
 * It's free open-source software released under the MIT License.
5
 *
6
 * @author Anatoly Nekhay <[email protected]>
7
 * @copyright Copyright (c) 2018, Anatoly Nekhay
8
 * @license https://github.com/sunrise-php/http-router/blob/master/LICENSE
9
 * @link https://github.com/sunrise-php/http-router
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sunrise\Http\Router\Helper;
15
16
use ErrorException;
17
use InvalidArgumentException;
18
use Throwable;
19
use UnexpectedValueException;
20
21
use function is_int;
22
use function preg_last_error;
23
use function preg_last_error_msg;
24
use function preg_match;
25
use function sprintf;
26
27
use const E_WARNING;
28
use const PREG_BAD_UTF8_ERROR;
29
use const PREG_UNMATCHED_AS_NULL;
30
31
/**
32
 * @since 3.0.0
33
 */
34
final class RouteMatcher
35
{
36
    /**
37
     * @param non-empty-string $pattern
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
38
     * @param ?array<string, string> $matches
39
     * @param-out array<string, string> $matches
40
     *
41
     * @throws InvalidArgumentException
42
     * @throws UnexpectedValueException
43
     */
44 14
    public static function matchRoute(string $pattern, string $subject, ?array &$matches = null): bool
45
    {
46
        try {
47 14
            if (($result = @preg_match($pattern, $subject, $matches, PREG_UNMATCHED_AS_NULL)) === false) {
48 14
                throw new ErrorException(preg_last_error_msg(), preg_last_error(), E_WARNING);
49
            }
50 5
        } catch (Throwable) {
51 5
            if (preg_last_error() === PREG_BAD_UTF8_ERROR) {
52 1
                throw new UnexpectedValueException(sprintf(
53 1
                    'The route "%s" could not be matched due to an invalid subject: %s.',
54 1
                    $pattern,
55 1
                    preg_last_error_msg(),
56 1
                ));
57
            }
58
59 4
            throw new InvalidArgumentException(sprintf(
60 4
                'The route "%s" could not be matched due to: %s. ' .
61 4
                'This problem is most likely related to one of the route patterns.',
62 4
                $pattern,
63 4
                preg_last_error_msg(),
64 4
            ), preg_last_error());
65
        }
66
67 9
        foreach ($matches as $key => $match) {
68 7
            if (is_int($key) || $match === null) {
69 7
                unset($matches[$key]);
70
            }
71
        }
72
73
        /** @var array<string, string> $matches */
74
75 9
        return $result === 1;
76
    }
77
}
78