Search code examples
php.htaccessslimphp-builtin-server

Is there a way to allow dots in request urls in php?


when a request url has a dot in it I am getting a 404 error Not found page that says "The requested resource /error.example was not found on this server." What causes this error and is there a way of fixing it? I am using the Slim framework and run my code with the php built-in server. I will put bellow a sample code that recreates the above error.

index.php:

<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;

require __DIR__ . '/../vendor/autoload.php';

$app = AppFactory::create();

$app->get('/{name}/oth', function (Request $request, Response $response, array $args) {
    $name = $args['name'];
    $response->getBody()->write($name);
    return $response;
});

$app->run();

.htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]

Both index.php and .htaccess are located inside the public folder, and i run my code with php -S localhost:8080 -t public/ When I go to my browser and go type the address http://localhost:8080/name/oth it shows name correctly but when i type http://localhost:8080/name.ex/oth it shows the error i mentioned
Not Found
The requested resource /name.ex/oth was not found on this server.

Edit:
Adding the requested information:
-Log for php -S localhost:8080 -t public/:
PHP 8.1.2 Development Server (http://localhost:8080) started

-Log for the request url http://localhost:8080/name/oth:
[::1]:63906 [200]: GET /name/oth

-Log for the request url http://localhost:8080/name.ex/oth:
[::1]:63917 [404]: GET /name.ex/oth - No such file or directory

If i replace index.php with echo 'here'; die; it displays "here" correctly in the browser.


Solution

  • PHP is responsible there, not slim

    [::1]:63917 [404]: GET /name.ex/oth - No such file or directory

    This log message originates from the php built-in web server, not slim - it's implicit from "No such file or directory" that the request has been considered a file path.

    Not Found, The requested resource /blah.ex/blah was not found on this server

    If the response looks like this (php purple :)), i.e. different from anything your own script might generate, that's also strong evidence it's coming from the built-in web server.

    This is very likely related to the known behavior of the php dev server considering any url with a . in it as a filepath and not forwarding the request to any php script - see for example this old issue.

    Specify a router script

    The fix here is simple, specify a "router script" when starting the php development server:

    If a PHP file is given on the command line when the web server is started it is treated as a "router" script.

    This is also how slim's own documentation say to use the webserver, adapted to the question use:

    $ php -S localhost:8080 -t public/ public/index.php
    

    With the server running with an explicit router script, that should resolve the immediate problem of requests not reaching index.php:

    $ curl -i http://localhost:8080/blah.ex/blah
    HTTP/1.1 200 OK
    Host: localhost:8080
    Date: Sun, 20 Mar 2022 20:33:58 GMT
    Connection: close
    X-Powered-By: PHP/8.0.11
    Content-type: text/html; charset=UTF-8
    
    ...whatever public/index.php returns...