[SOLVED] URL-encoded slash ("/") character does not work

Hi there,

I have a route like so: /api/search/{term} but if I call it like so: /api/search/03%2F2020 it will create a 404.

Why? Because Slim is using PATH_INFO instead of REQUEST_URI

I:\dev\myproject\app\back\api\front-controller.php:38:
array (size=42)
  'REQUEST_URI' => string '/api/search/03%2F2020' (length=xxx)
  'PATH_INFO' => string '/api/search/03/2020' (length=xxx)

I think I will copy REQUEST_URI inside PATH_INFO so that it works.

I am using the PHP embedded server to test my app. But it should not matter.

Any input welcome! :slight_smile: (like: any reason why Slim is not using REQUEST_URI?)

Stay safe,

Hello! I think you can try something like this:

$app->get('/api/search/{term}', function (Request $request, Response $response, array $args) {
    $term = $args['term'];
    $response->getBody()->write("Search: $term");

    return $response;
});

So, you can access to {term} using the $args array (instead of PATH_INFO or REQUEST_URI).

Request Example:

GET /api/search/03%2F2020

Response Example:

Search: 03/2020

Hi,

Thank you for the answer.

Problem is, that is exactly what I am doing right now, and I got a 404 because Slim seems to decode the “/” and then route it.

$group->get('/search/{term}', [\API\Controller\DashboardController::class, 'markersByTerm']);

Actually I found out that Slim is not even using PATH_INFO or PHP_SELF because I modified them, but it still throws a 404:

// FIX for Slim using PATH_INFO (or rather PHP_SELF instead of REQUEST_URI
$_SERVER['PHP_SELF'] = str_replace($_SERVER['PATH_INFO'], $_SERVER['REQUEST_URI'], $_SERVER['PHP_SELF']);
$_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'];

And then:

var_dump($_SERVER);

Which gives:

I:\dev\myproject\app\back\api\front-controller.php:40:
array (size=42)
  'REQUEST_URI' => string '/search/03%2F2020' (length=39)
  'PATH_INFO' => string '/search/03%2F2020' (length=39)
  'PHP_SELF' => string '/index.php/search/03%2F2020' (length=49)

But it still fails:

404 Not Found
The application could not run because of the following error:

Details
Type: Slim\Exception\HttpNotFoundException
Code: 404
Message: Not found.
File: I:\dev\myproject\vendor\slim\slim\Slim\Middleware\RoutingMiddleware.php
Line: 93

Slim uses FastRoute as Router and FastRoute expects a decoded URL.
As shown in the README, this can be achieved using a call to rawurldecode(). See issue 154.

Chars like %2F are invalid in URL paths as defined in RFC 3986 Section 3.3.

Why don’t you send your search values as query parameters? For example:

GET /api/search?term=03%2F2020
$app->get('/api/search', function (ServerRequestInterface $request, ResponseInterface $response) {
    $term = $request->getQueryParams()['term'];
    $response->getBody()->write("Search: $term");

    return $response;
});

Output:

Search: 03/2020

Thank you @odan!

Yeah I knew it was based on nickic fastroute, should have checked that too, my bad!

I used JS encodeURIComponent for this.

Ok I will maybe move this parameter to GET instead of URI, then… :frowning:

At least it will work flawlessly I guess :slight_smile:

Thanks!

I had the same “problem” when upgrading von slim 3 to slim 4. The API was in use by several clients so I was not “allowed” to change the API-Call itself. Therefore I did a trick like this:

$group->get('/search/{part1}/{part2}', [\API\Controller\DashboardController::class, 'markersByTerm'])

In my function I check for both ways and combine the two parameters if needed, and everythink work like before :wink: