for testing and deploying your application
for finding and fixing issues
for empowering human code reviews
<?php
declare(strict_types=1);
namespace Gacela\Router\Validators;
use Gacela\Router\Entities\RouteParams;
final class PathValidator
{
public static function isValid(string $path): bool
if ($path === '/') {
return true;
}
if (!self::hasValidFormat($path)) {
return false;
return self::hasValidParameterOrder($path);
private static function hasValidFormat(string $path): bool
if ($path === '') {
if (str_starts_with($path, '/')) {
if (str_ends_with($path, '/')) {
return !self::hasEmptyParts($path);
private static function hasEmptyParts(string $path): bool
$parts = explode('/', $path);
foreach ($parts as $part) {
if (!$part) {
private static function hasValidParameterOrder(string $path): bool
$optionalParamFound = false;
if (!$part) { // Empty part found
if (preg_match(RouteParams::OPTIONAL_PARAM_PATTERN, $part)) { // Optional argument found
$optionalParamFound = true;
} elseif ($optionalParamFound) { // Mandatory argument or static part found after an optional argument