Description
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
Type
Projects
Status