symfony: Routes containing a period/dot don't work

Q A
Bug report? yes/no
Feature request? yes/no
BC Break report? yes/no
RFC? yes/no
Symfony version 4.0.0

I have created my routing using the following annotation:

/**
* @Route("/project/{id}/{file}.{extension}", methods={"GET"}, name="get_project_image")
*/

When I run php bin/console debug:router, it shows my route: get_project_image GET ANY ANY /api/project/{id}/{file}.{extension}

However, when I navigate towards the URL, it gives me the following error (the “/api” in front of the URL is because I have another route on my controller": No route found for "GET /api/project/1/test.xml"

This is very confusing to me, this should work according to the Symfony docs.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 23 (12 by maintainers)

Most upvoted comments

@TomasVotruba

router.php:

<?php
/**
 * This router is required if you are running the built in PHP web server
 * as it attempts to route static files through the natural router(index).
 */
if (php_sapi_name() == 'cli-server') {
    $info = parse_url($_SERVER['REQUEST_URI']);

    if ($info !== false && file_exists(sprintf("./%s", $info['path']))) {
        return false;
    } else {
        include_once "index.php";
        return true;
    }
}

Dump that into your public directory and when you start the php server append it with router.php as in php -S localhost:8000 router.php

This is a bug with php’ built in server so the issue is correctly closed. The problem is that the server is detecting the route as a static file. I had the issue with /sitemap.xml which was dynamically generated and you have the same issue with groups.json

I have come across this issue and believe its the period in the actual route. With a basic controller(provided below) router:match works on both /test/example-value and /test/example.value however a http request to example.value will return a 404.

<?php
declare(strict_types=1);

namespace App\Controller\Web\Site;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class TestController extends AbstractController
{
    /**
     * @Route("/test/{value}", name="test")
     */
    public function test(string $value): Response
    {
        return new Response();
    }
}

 [OK] Route "test" matches


+--------------+-----------------------------------------------------------+
| Property     | Value                                                     |
+--------------+-----------------------------------------------------------+
| Route Name   | test                                                      |
| Path         | /test/{value}                                             |
| Path Regex   | #^/test/(?P<value>[^/]++)$#sD                             |
| Host         | ANY                                                       |
| Host Regex   |                                                           |
| Scheme       | ANY                                                       |
| Method       | ANY                                                       |
| Requirements | NO CUSTOM                                                 |
| Class        | Symfony\Component\Routing\Route                           |
| Defaults     | _controller: App\Controller\Web\Site\TestController::test |
| Options      | compiler_class: Symfony\Component\Routing\RouteCompiler   |
+--------------+-----------------------------------------------------------+
------------------------------------------------------------

curl -I http://localhost:8000/test/example-value                                                                     
HTTP/1.1 200 OK
Host: localhost:8000
Date: Thu, 06 Jun 2019 07:57:14 +0000
Connection: close
X-Powered-By: PHP/7.2.17
Cache-Control: no-cache, private
Date: Thu, 06 Jun 2019 07:57:14 GMT
Content-Type: text/html; charset=UTF-8

bin/console router:match /test/example.value                                                                         


 [OK] Route "test" matches


+--------------+-----------------------------------------------------------+
| Property     | Value                                                     |
+--------------+-----------------------------------------------------------+
| Route Name   | test                                                      |
| Path         | /test/{value}                                             |
| Path Regex   | #^/test/(?P<value>[^/]++)$#sD                             |
| Host         | ANY                                                       |
| Host Regex   |                                                           |
| Scheme       | ANY                                                       |
| Method       | ANY                                                       |
| Requirements | NO CUSTOM                                                 |
| Class        | Symfony\Component\Routing\Route                           |
| Defaults     | _controller: App\Controller\Web\Site\TestController::test |
| Options      | compiler_class: Symfony\Component\Routing\RouteCompiler   |
+--------------+-----------------------------------------------------------+

curl -I http://localhost:8000/test/example.value                                                                     
HTTP/1.1 404 Not Found
Host: localhost:8000
Date: Thu, 06 Jun 2019 07:58:11 +0000
Connection: close
Content-Type: text/html; charset=UTF-8
Content-Length: 551

If i come across anything further I will add some notes.

Additional: I tested this using PHP’s built in server and it does not match, using nginx docker it works fine. This leads me to believe this issue is with php’ server. I am leaving it there as I have a work around; just adding notes for anyone else that comes along with this issue.