Skip to content

[BUG]: Router fails to match routes starting with "/number:number/" due to internal parse_url() behavior #16741

Closed
@maximecaze

Description

@maximecaze

Describe the bug

After migrating from Phalcon 3.4.5 (PHP 7.3) to Phalcon 5.9 (PHP 8.4), certain route patterns no longer match correctly if URLs start with /number:number/ segments (e.g., /1:1/... or /150:200/...). This is caused by the internal use of PHP's native parse_url() function in Phalcon's Router component, which returns false for these specific URL patterns.

Such URLs were previously correctly routed in Phalcon 3.x (which did not rely on parse_url() internally).

To Reproduce

Steps to reproduce clearly and quickly:

<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Router;

$di = new FactoryDefault();
$router = new Router(false);
$router->setDI($di);

// Simple catch-all route
$router->add('/{param:.+}', [
    'controller' => 'index',
    'action'     => 'test',
]);

// Explicitly set request method (for CLI testing)
$_SERVER["REQUEST_METHOD"] = "GET";

// Problematic URLs
$testUrls = [
    '/1:1/test',
    '/a:1/test',
    '/1:a/test',
    '/a:a/test',
];

foreach ($testUrls as $uri) {
    $router->handle($uri);
    echo "Testing URI: $uri\n";
    echo $router->getMatchedRoute()
        ? "✅ MATCHED\n"
        : "❌ NOT MATCHED\n";
}

Result in Phalcon 5.9:

Testing URI: /1:1/test
❌ NOT MATCHED
Testing URI: /a:1/test
❌ NOT MATCHED
Testing URI: /1:a/test
✅ MATCHED
Testing URI: /a:a/test
✅ MATCHED

Expected behavior

All provided URIs should match correctly. In Phalcon 3.x, these routes matched properly, regardless of whether the segments contained numeric patterns before and after the ":" character.

Root cause clearly identified

Phalcon 5.x internally calls PHP's native parse_url() here:

https://github.com/phalcon/cphalcon/blob/v5.9.0/phalcon/Mvc/Router.zep#L360

let uri = parse_url(uri, PHP_URL_PATH);

PHP's native parse_url() returns false on URLs starting with "/number:number/", because it interprets such strings as URLs that specify a scheme and port number invalidly:

Minimal reproducer outside Phalcon (pure PHP):

php -r "var_dump(parse_url('/1:1/test'));"  # bool(false)
php -r "var_dump(parse_url('/a:1/test'));"  # bool(false)
php -r "var_dump(parse_url('/1:a/test'));"  # array(...)
php -r "var_dump(parse_url('/a:a/test'));"  # array(...)

Thus, Phalcon silently discards the route matching attempt because URI becomes boolean false internally, leading to router failure.

Temporary workaround

While waiting for the official fix, users can extend the Router class temporarily in PHP:

use Phalcon\Mvc\Router;

class FixedRouter extends Router
{
    public function handle(string $uri): void
    {
        $parsedUri = parse_url($uri, PHP_URL_PATH);
        if ($parsedUri === false) {
            $handledUri = $uri;
        } else {
            $handledUri = $parsedUri;
        }

        // Reimplement the internal logic (copied from original handle)
        // replacing only the initial parse_url handling.
        // [Copy original Zephir handle()-method logic translated here.]
    }
}

Details

  • Phalcon version: 5.9
  • PHP version: 8.4
  • Operating System: Debian GNU/Linux 12 (Docker)

🙏 Thank you very much for your time, and your excellent work maintaining Phalcon!

Metadata

Metadata

Assignees

Labels

5.0The issues we want to solve in the 5.0 releasebugA bug reportstatus: mediumMedium

Type

Projects

Status

Implemented

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions