slimphp / Slim

Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs.
http://slimframework.com
MIT License
11.97k stars 1.95k forks source link

Routing is incompatible with embedded PHP server and default nginx settings #1829

Closed grikdotnet closed 7 years ago

grikdotnet commented 8 years ago

The default Nginx value of SCRIPT_NAME parameter sent to PHP-FPM is: fastcgi_param SCRIPT_NAME $fastcgi_script_name; https://github.com/nginx/nginx/blob/master/conf/fastcgi_params#L7

The default value of $fastcgi_script_name is a request URI. http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#variables

In the same time Slim sets the BasePath setting to $_SERVER['SCRIPT_NAME'] here: https://github.com/slimphp/Slim/blob/3.x/Slim/Http/Uri.php#L209

A router substracts the basepath from the URL https://github.com/slimphp/Slim/blob/3.x/Slim/Http/Uri.php#L216 The router receives "/" as the URI for any request, and so it misses all routes except of "/".

mathmarques commented 8 years ago

You need to change the nginx settings. See on Slim docs here: http://www.slimframework.com/docs/start/web-servers.html

grikdotnet commented 8 years ago

I see. Well, as to me, a framework should be compatible as much as possible. The idea of microframeworks is to enforce less constraints. To be embeddable. To assist, not to limit. If Slim requires a dedicated server configuration, the goal is not achieved.

grikdotnet commented 8 years ago

A brief test shows that native PHP embedded server behaves the same way. It is not possible to customize a SCRIPT_NAME value. It's a common development and debugging environment.

gri$ php -t wwwroot/ -S localhost:8080 bootstrap.php
PHP 7.0.2 Development Server started at Mon Mar 28 15:50:21 2016
Listening on http://localhost:8080
Document root is /opt/www/krossovki/wwwroot
Press Ctrl-C to quit.

var_dump($_SERVER);

/opt/www/krossovki/bootstrap.php:25: array (size=22) 'DOCUMENT_ROOT' => string '/opt/www/krossovki/wwwroot' (length=26) 'REMOTE_ADDR' => string '127.0.0.1' (length=9) 'REMOTE_PORT' => string '65480' (length=5) 'SERVER_SOFTWARE' => string 'PHP 7.0.2 Development Server' (length=28) 'SERVER_PROTOCOL' => string 'HTTP/1.1' (length=8) 'SERVER_NAME' => string 'localhost' (length=9) 'SERVER_PORT' => string '8080' (length=4) 'REQUEST_URI' => string '/products/qweqwe.123' (length=20) 'REQUEST_METHOD' => string 'GET' (length=3) 'SCRIPT_NAME' => string '/products/qweqwe.123' (length=20) 'SCRIPT_FILENAME' => string '/opt/www/krossovki/wwwroot/bootstrap.php' (length=40) 'PHP_SELF' => string '/products/qweqwe.123' (length=20) 'HTTP_HOST' => string 'krossovki.dev:8080' (length=18) 'HTTP_CACHE_CONTROL' => string 'max-age=0' (length=9) 'HTTP_CONNECTION' => string 'keep-alive' (length=10) 'HTTPACCEPT' => string 'text/html,application/xhtml+xml,application/xml;q=0.9,/_;q=0.8' (length=63) 'HTTP_USER_AGENT' => string 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17' (length=116) 'HTTP_ACCEPT_LANGUAGE' => string 'ru' (length=2) 'HTTP_ACCEPT_ENCODING' => string 'gzip, deflate' (length=13) 'HTTP_DNT' => string '1' (length=1) 'REQUEST_TIME_FLOAT' => float 1459169615.382 'REQUEST_TIME' => int 1459169615

tuupola commented 8 years ago

Built in PHP server assumes uris containing a dot are static files. This is considered not to be a bug but a feature.

grikdotnet commented 8 years ago

It is not related. The $_SERVER['SCRIPT_NAME'] is set to the URL value, and the routes are not processed with ANY URI.

tuupola commented 8 years ago

I have no problems using PHP internal webserver with Slim 3. However if you add a route containing a dot that will fail. Looking at your request uri it seems to contain a dot /products/qweqwe.123.

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

$app = new \Slim\App;

$app->get("/foo", function ($request, $response, $args) {
    return $response->write("bar");
});

$app->get("/foo.bar", function ($request, $response, $args) {
    return $response->write("bar");
});

$app->run();
$ php -S 0.0.0.0:8080 index.php

$ curl --include http://localhost:8080/foo
HTTP/1.1 200 OK
Host: localhost:8080
Connection: close
X-Powered-By: PHP/5.6.17
Content-Type: text/html; charset=UTF-8
Content-Length: 3

bar

$ curl --include http://localhost:8080/foo.bar
HTTP/1.1 404 Not Found
Host: localhost:8080
Connection: close
X-Powered-By: PHP/5.6.17
Content-type: text/html;charset=UTF-8
Content-Length: 887
...
akrabat commented 8 years ago

I'm sorry, but I don't understand the problem. Can you explain a different way?

This works with the PHP built in server:

$ composer create-project slim/slim-skeleton slimtest
$ php -S 0.0.0.0:8888 -t public public/index.php

I can then add this to routes.php:

$app->get('/products/{code}', function ($request, $response, $args) {
    return $response->write("Product {$args['code']}\n");
});

and test it via curl:

$ curl http://localhost:8888/products/123
Product 123
akrabat commented 8 years ago

Look at the instructions for Silex (http://silex.sensiolabs.org/doc/web_servers.html#nginx), Zend Framework (https://www.nginx.com/resources/wiki/start/topics/recipes/zend/#time-for-nginx) & CakePHP (http://book.cakephp.org/2.0/en/installation/url-rewriting.html#pretty-urls-on-nginx), I don't see what's significantly different about configuring Slim for nginx?

grikdotnet commented 8 years ago

Difference is in the ticket - they work with default settings. ZF and Cake are dead, so the comparison is a bit funny.

Guys, if you wrote Slim for your own needs - I'm totally OK with that. If you want it to be popular - this report is for you. Don't take it personally please.

I will retest the issue with a builtin php server a bit later. Thanks.

akrabat commented 8 years ago

I think both ZF and CakePHP would disagree with you.

I genuinely don't understand the first comment. Can you provide concrete sample strings and show what's going wrong please?

grikdotnet commented 8 years ago

I am here not to argue, sorry. Which words in particular I can help you with?

akrabat commented 8 years ago

If we can make Slim easier to use with Nginx without creating a BC break, then I'd like to do so, but I have no clue what needs to be changed as my testing shows that it already works

Test methodology:

  1. Create a brand new Ubuntu box and then run apt-get install vim nginx php5 php5-fpm.
  2. Follow https://help.ubuntu.com/community/Nginx#Nginx_with_PHP and modify etc/nginx/sites-available/default as instructed so that my Nginx PHP configuration is as default as it can be:

    a. Use public directory, by changing root /usr/share/nginx/html; to root /usr/share/nginx/html/public;

    b. Uncomment PHP section, so that it looks like this:

    location ~ \.php$ {
                       fastcgi_split_path_info ^(.+\.php)(/.+)$;
               #        # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
               #
               #        # With php5-cgi alone:
               #       fastcgi_pass 127.0.0.1:9000;
                       # With php5-fpm:
                       fastcgi_pass unix:/var/run/php5-fpm.sock;
                       fastcgi_index index.php;
                       include fastcgi_params;
               }
  3. Write simple Slim application: https://gist.github.com/akrabat/44371596bf9ea291c673
    • composer.json goes in /usr/share/nginx/html
    • index.php goes in /usr/share/nginx/html/public
  4. Test
    • http://192.168.99.211/ works
    • http://192.168.99.211/products/123 is a 404 page. It seems that index.php file isn't being called by Nginx.
  5. Configure URL rewriting in Nginx by updating: etc/nginx/sites-available/default. In the location / section, change:

    try_files $uri $uri/ =404; to try_files $uri $uri/ /index.php$is_args$args;

  6. Test
    • http://192.168.99.211/ works
    • http://192.168.99.211/products/123 works

Did I miss something? Out of the box, Nginx doesn't support PHP or URL rewriting without changing configuration, and when you configure it, Slim works as expected.

Please provide an actionable item that we can do help solve the reported problem.

grikdotnet commented 8 years ago

@akrabat unfortunately, yes, there is one important thing. In most projects Nginx settings are defined by devops team, and developers can't change that. Microframework is intended to be a part of a large application and be integrated or embedded. There are default commonly used setting for Nginx and PHP. A SCRIPT_NAME parameter is one of them. All other frameworks work with it. Slim does not. I spent half of a day finding the reason and provided links to the exact lines of code showing why it happens.

I don't ask you to follow that. I have a feeling you don't like what I write, I guess I'll better leave. Thanks, and sorry for inconvenience. Grigori

OptimusCrime commented 8 years ago

I thought nginx needed configurations to be able to handle "friendly urls"? Apache needs it, and it will not work without htaccess or edits to the Apache config file(s). Because nginx lacks something similar to htaccess-files, there is no other way to do this?

I might be wrong.

Ups, @akrabat already stated that in his answer.

My question @grikdotnet, is how you want to fix this? As far as I can tell, there is no way to get Slim to work with URL patterns that Slim operates with? In addition, I'd like to remark that people that are familiar with nginx knows this for sure. As a Apache user I know that you either need to supply rewrite with htaccess or change the config files. Neither web server provides this by default, and that's been the case forever.

One option could be for Slim to handle ugly urls too, where the actual path is hidden in a GET param, for example index.php?q=my/path/goes/here would be rewritten to my/path/goes/here after rewrite. I know MODX does it this way and you can toggle what way the system should generate/read URLs.

akrabat commented 8 years ago

@grikdotnet: I have no idea what we can do to solve the problem you are seeing as I don't understand what you think it is getting wrong.

Please provide the URL you are using, the SCRIPT_NAME value you see in PHP, the basepath that Slim calculates and the basepath you think that it should have calculated.

Lewiscowles1986 commented 8 years ago

What exactly is the problem with the "."?

I'm assuming it's because fastroute uses regex, so you could (if this is the problem) simply escape the dot?

OptimusCrime commented 8 years ago

@Lewiscowles1986 Looking at what is posted above, they were talking about the build in PHP server, where "." by design indicates a static file, so it is neither Slim nor Fastroute's fault. It is PHP. I don't think Fastroute has a problem with "." in URLs as far as I know?

Lewiscowles1986 commented 8 years ago

Thx, I don't use the built-in server (not sure why anyone would), so IDK, maybe don't use built-in-server could be good advice?

grikdotnet commented 8 years ago

:D Guys, it's unrelated to dots in a URL. When I remove a line fastcgi_param SCRIPT_NAME $fastcgi_script_name; from Nginx config, it works fine with dots in URLs.

The issue is in processing of a SCRIPT_NAME parameter passed to PHP from a web server. I will write you the values of a URL and a baseUrl.

tuupola commented 8 years ago

Dot in the url bug is related to internal PHP server not Nginx.

Lewiscowles1986 commented 8 years ago

@tuupola if you read the initial comment, @grikdotnet is using nginx. While the bug you are talking about is not part of Nginx, the behaviour @grikdotnet is experiencing is both for internal server and nginx...

akrabat commented 8 years ago

I still have no idea how to reproduce this error.

Lewiscowles1986 commented 8 years ago

@grikdotnet can you let me know

OS + release, PHP version, nginx version if it's a VPS or internal PC. If possibly a host-specific issue let me know the host (I'm assuming it's shared, after the comment about dedicated)

Also some sample code to reproduce the bug. If it exists I can either squish it or write a doc on how to avoid / work-around

tuupola commented 8 years ago

@Lewiscowles1986 The title of this bug report is: "Routing is incompatible with embedded PHP server and default nginx settings".

My comment points out that @grikdotnet is using dot in the uri which can be seen from the provided var_dump:

'SCRIPT_NAME' => string '/products/qweqwe.123' (length=20)

Dot in uri is why Slim with embedded PHP server seems to be broken. Slim 3 routing itself is not broken with embedded PHP server.

At no point I have been referring to Nginx behaviour in any way.

The $_SERVER['SCRIPT_NAME'] is set to the URL value, and the routes are not processed with ANY URI.

Does not seem to be case with PHP 5.6 atleast.

<?php
print_r($_SERVER);
$ php -S 0.0.0.0:8080 index.php 
$ curl http://localhost:8080/foo
Array
(
    [DOCUMENT_ROOT] => /tmp
    [REMOTE_ADDR] => 127.0.0.1
    [REMOTE_PORT] => 55723
    [SERVER_SOFTWARE] => PHP 5.6.17 Development Server
    [SERVER_PROTOCOL] => HTTP/1.1
    [SERVER_NAME] => 0.0.0.0
    [SERVER_PORT] => 8080
    [REQUEST_URI] => /foo
    [REQUEST_METHOD] => GET
    [SCRIPT_NAME] => /index.php
    [SCRIPT_FILENAME] => /tmp/index.php
    [PATH_INFO] => /foo
    [PHP_SELF] => /index.php/foo
    [HTTP_HOST] => localhost:8080
    [HTTP_USER_AGENT] => curl/7.43.0
    [HTTP_ACCEPT] => */*
    [REQUEST_TIME_FLOAT] => 1459350222.3006
    [REQUEST_TIME] => 1459350222
)
tuupola commented 8 years ago

In any case if I understand this bug report there the problem @grikdotnet describes is that he wishes Slim 3 routing to work without adding the following to nginx.config

location /  {
   try_files $uri $uri/ /index.php$is_args$args;
}

Am I correct?

mathmarques commented 8 years ago

I think the "problem" @grikdotnet is reporting is with this nginx.config setting:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Slim need this in order to work properly.

And @grikdotnet said:

Well, as to me, a framework should be compatible as much as possible. The idea of microframeworks is to enforce less constraints. To be embeddable. To assist, not to limit. If Slim requires a dedicated server configuration, the goal is not achieved.

He thinks it's not a good idea. He claims that others frameworks work without this change:

There are default commonly used setting for Nginx and PHP. A SCRIPT_NAME parameter is one of them. All other frameworks work with it.

So @grikdotnet can you please tell which others frameworks?

ckressibucher commented 8 years ago

I think nginx and php built-in server are two different problems. I have the same problem with the php built-in server, but only when using dots in the url path. To reproduce @akrabat

// define 3 routes:
        $app->get('/', function ($request, $response, $args) {
            die('home');
        });
        $app->get('/no-dot', function ($request, $response, $args) {
            die('no dot');
        });
        $app->get('/with.dot', function ($request, $response, $args) {
            die('with dot');
        });

Start server: php -t public -S 127.0.0.1:8080 public/index.php

Call the 3 routes:

> curl -# 127.0.0.1:8080
home
> curl -# 127.0.0.1:8080/no-dot
no dot
> curl -# 127.0.0.1:8080/with.dot
home

The last one should show 'with dot' instead of home. The reason is that slim does not work correctly when SCRIPT_NAME is set to the same value as REQUEST_URI, which is the case with the php server when the url contains a dot.

In Symfony, they use an additional router script which wraps the application's entry point. This script sets SCRIPT_NAME as well as PHP_SELF to this entry point:

https://github.com/symfony/framework-bundle/blob/master/Resources/config/router_dev.php#L37

For the php built in server I would suggest to provide a similar wrapper script. Because I think it's very uncommon behavior to set SCRIPT_NAME to the URL path if the url contains a dot...

As I said, nginx is probably another topic, I haven't tested yet.

bertrandmalet commented 8 years ago

I think i have the same problem with the build-in PHP server. My setup is with a catch all route define at the end of all routes :

$app->get('/{route:.*}', 'Help:run');

on the run method i'm using

$request->getUri()

The getUri return 2 differents results with Apache and php build-in server.

For exemple, with http://127.0.0.1/idontexist on Apache $request->getUri() will return /idontexist with build-in php it will return / That's because SCRIPT_NAME is set to /index.php with Apache, with build-in php it's set to /idontexist so Slim define different basePath https://github.com/slimphp/Slim/blob/f762309527e5180689be7d543c8f6b6d27290ef8/Slim/Http/Uri.php#L209

Hope it's help

UPDATE : my bad, i didn't set the -t option when running php build-in server :

php -S 127.0.0.1:8080 public/index.php

instead of

php -S 127.0.0.1:8080 -t public public/index.php
JoeBengalen commented 8 years ago

I now have this same problem running on ubuntu with PHP7 builtin webserver $ php -S localhost:8080 api.php Calling http://localhost:8080/api/v1/hello

object(Slim\Http\Environment)[109]
  protected 'data' => 
    array (size=21)
      'DOCUMENT_ROOT' => string '/home/martijn/Development/private-tables/public' (length=47)
      'REMOTE_ADDR' => string '127.0.0.1' (length=9)
      'REMOTE_PORT' => string '39830' (length=5)
      'SERVER_SOFTWARE' => string 'PHP 7.0.4-7ubuntu2 Development Server' (length=37)
      'SERVER_PROTOCOL' => string 'HTTP/1.1' (length=8)
      'SERVER_NAME' => string 'localhost' (length=9)
      'SERVER_PORT' => string '8080' (length=4)
      'REQUEST_URI' => string '/api/v1/hello' (length=13)
      'REQUEST_METHOD' => string 'GET' (length=3)
      'SCRIPT_NAME' => string '/api/v1/hello' (length=13)
      'SCRIPT_FILENAME' => string '/home/martijn/Development/private-tables/public/api.php' (length=55)
      'PHP_SELF' => string '/api/v1/hello' (length=13)
      'HTTP_HOST' => string 'localhost:8080' (length=14)
      'HTTP_USER_AGENT' => string 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0' (length=76)
      'HTTP_ACCEPT' => string 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' (length=63)
      'HTTP_ACCEPT_LANGUAGE' => string 'en-US,en;q=0.5' (length=14)
      'HTTP_ACCEPT_ENCODING' => string 'gzip, deflate' (length=13)
      'HTTP_CONNECTION' => string 'keep-alive' (length=10)
      'HTTP_CACHE_CONTROL' => string 'max-age=0' (length=9)
      'REQUEST_TIME_FLOAT' => float 1461626595.2633
      'REQUEST_TIME' => int 1461626595

object(Slim\Http\Uri)[110]
  protected 'scheme' => string 'http' (length=4)
  protected 'user' => string '' (length=0)
  protected 'password' => string '' (length=0)
  protected 'host' => string 'localhost' (length=9)
  protected 'port' => int 8080
  protected 'basePath' => string '/api/v1/hello' (length=13)
  protected 'path' => string '/' (length=1)
  protected 'query' => string '' (length=0)
  protected 'fragment' => string '' (length=0)

For some reason SCRIPT_NAME contains the path instead of the filename, which results in an incorrect Uri instance. Changing it to SCRIPT_FILENAME on https://github.com/slimphp/Slim/blob/3.x/Slim/Http/Uri.php#L200 solves it in this specific case.

geggleto commented 8 years ago

@JoeBengalen that might be a bug in PHP 7....

JoeBengalen commented 8 years ago

I don't know, it could be.

akrabat commented 8 years ago

I now have this same problem running on ubuntu with PHP7 builtin web server

    $ php -S localhost:8080 api.php

Calling http://localhost:8080/api/v1/hello

Which folder is api.php in?

akrabat commented 8 years ago

@JoeBengalen I can't reproduce with PHP 7.0.6.

This is my public/index.php:

<?php
require __DIR__ . '/../vendor/autoload.php';
$app = new \Slim\App();

$app->get('/api/v1/hello', function ($request, $response, $args) {
    var_dump($this->get('environment'));
    var_dump($request->getUri());
});

$app->run();

Running:

$ cd public
$ php -S localhost:8888 index.php 
PHP 7.0.6 Development Server started at Tue May  3 17:31:10 2016
Listening on http://localhost:8888
Document root is /Users/rob/tmp/slimtest/public
Press Ctrl-C to quit.

Open http://localhost:8888/api/v1/hello in browser:

/Users/rob/tmp/slimtest/public/index.php:6:
object(Slim\Http\Environment)[16]
  protected 'data' => 
    array (size=23)
      'DOCUMENT_ROOT' => string '/Users/rob/tmp/slimtest/public' (length=30)
      'REMOTE_ADDR' => string '::1' (length=3)
      'REMOTE_PORT' => string '64001' (length=5)
      'SERVER_SOFTWARE' => string 'PHP 7.0.6 Development Server' (length=28)
      'SERVER_PROTOCOL' => string 'HTTP/1.1' (length=8)
      'SERVER_NAME' => string 'localhost' (length=9)
      'SERVER_PORT' => string '8888' (length=4)
      'REQUEST_URI' => string '/api/v1/hello' (length=13)
      'REQUEST_METHOD' => string 'GET' (length=3)
      'SCRIPT_NAME' => string '/index.php' (length=10)
      'SCRIPT_FILENAME' => string '/Users/rob/tmp/slimtest/public/index.php' (length=40)
      'PATH_INFO' => string '/api/v1/hello' (length=13)
      'PHP_SELF' => string '/index.php/api/v1/hello' (length=23)
      'HTTP_HOST' => string 'localhost:8888' (length=14)
      'HTTP_ACCEPT' => string 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' (length=63)
      'HTTP_CONNECTION' => string 'keep-alive' (length=10)
      'HTTP_COOKIE' => string '__utma=111872281.18152458.1446108447.1457900608.1457935841.23; __utmz=111872281.1446108447.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); PHPSESSID=bb2de85ej4k73o060lvmhf5vb3' (length=178)
      'HTTP_USER_AGENT' => string 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17' (length=116)
      'HTTP_ACCEPT_LANGUAGE' => string 'en-us' (length=5)
      'HTTP_CACHE_CONTROL' => string 'max-age=0' (length=9)
      'HTTP_ACCEPT_ENCODING' => string 'gzip, deflate' (length=13)
      'REQUEST_TIME_FLOAT' => float 1462293277.2315
      'REQUEST_TIME' => int 1462293277
/Users/rob/tmp/slimtest/public/index.php:7:
object(Slim\Http\Uri)[22]
  protected 'scheme' => string 'http' (length=4)
  protected 'user' => string '' (length=0)
  protected 'password' => string '' (length=0)
  protected 'host' => string 'localhost' (length=9)
  protected 'port' => int 8888
  protected 'basePath' => string '' (length=0)
  protected 'path' => string '/api/v1/hello' (length=13)
  protected 'query' => string '' (length=0)
  protected 'fragment' => string '' (length=0)
JoeBengalen commented 8 years ago

@akrabat In a public/ folder

https://github.com/JoeBengalen/private-tables

vit1251 commented 8 years ago

Yep. I am already have issue with embeded PHP developer server. But I make simple hack in index.php: set up value $_SERVER['SERVER_NAME'] from different variable. It workaround but it works.

schnittstabil commented 8 years ago

This bug is quite annoying, especially because zend-expressive with fastroute is not affected by this.

@akrabat Sure, your last example works as expected.

But to reproduce the error you have to change index.php to e.g. api.php, and execute php -S localhost:8888 api.php.

As a result the built-in web server changes 'SCRIPT_NAME' => '/index.php' to 'SCRIPT_NAME' => '/api/v1/hello', which in turn breaks the $basePath determination.

ckressibucher commented 8 years ago

For the php built-in server, I suggest to provide a special "router" script which wraps index.php, and which does the "hacks" that @vit1251 probably means. Please have a look at my gist for this purpose: https://gist.github.com/ckressibucher/e37520cf2f1d08ec56d250c54d96ed72 (it's not specific to slim, but shows the idea). The approach is explained in more depth in an article I wrote about that "problem".

I think it's really the cli server which has some weird behavior, so I wouldn't want to change core logic to support this kind of behavior.

If you agree with this approach, I would offer to write that script and provide a PR.

schnittstabil commented 8 years ago

@ckressibucher Personally, I just set $_SERVER['SCRIPT_NAME'] = '/app.php'; in my app.php – I don't see a real benefit of creating an additional entry point for each production entry point, in particular because my development environment should match as accurately as possible my production environment.

ckressibucher commented 8 years ago

@schnittstabil That's what I did before. The question is if we want to support the uncommon behavior of the php server in the same file that we ship to production, or in a separate -- dev only -- file. In my opinion, the latter solution is cleaner, as it separates the "normal" entry point (which works in most of the common production environments) from the "hacks" that are required to support the PHP dev server.

in particular because my development environment should match as accurately as possible my production environment.

That is a valid point. However, I think in this case you should not use the PHP dev server at all. Because its behavior is fundamental different than that of your production server.

grikdotnet commented 8 years ago

Everything included in default PHP setup is common. Php embedded server installation and user base exceeds Slim in something like 1000 times. A fly near an elephant. But supporting a feature or not is on a personal author will. I use a link to this discussion as an argument for avoiding Slim in favor of another framework.

silentworks commented 8 years ago

@grikdotnet to this very day no one understands what your issue is and you haven't explained it clear enough for anyone to attempt to fix it if its a bug. Not sure why you still feel the need to be negative about others work while they are trying to help you as much as possible.

grikdotnet commented 8 years ago

The issue is that it does not work, and the links with explanation are provided. Maybe you can ask some question on what I can clarify? The discussion flow is not that the report is unclear, but that it should not be fixed because the team don't need it to work. If you want to, if you have a question, I will be glad to assist and explain.

silentworks commented 8 years ago

@grikdotnet yet again I have not seen anything in this discussion where any official member of the team has said they wont fix this. I have seen @akrabat ask over and over for you to clarify what the issue you are having is and how to reproduce it. I am yet to see you provide any of what he has asked but continuously say you have explained it already.

We cannot fix what we can't reproduce or have steps to reproduce, we also cannot fix anything that is not related to Slim itself. Please provide clear steps on how to reproduce your issue and we will definitely investigate it more. Also can you state which framework you have used which doesn't have the issue you are talking about so we can check how they are handling the issue.

akrabat commented 8 years ago

Maybe you can ask some question on what I can clarify?

@grikdotnet Please provide the nginx configuration that does not work that you think should so that we can reproduce it.

schnittstabil commented 8 years ago

@grikdotnet to this very day no one understands what your issue is and you haven't explained it clear enough for anyone to attempt to fix it if its a bug. … I am yet to see you provide any of what he has asked but continuously say you have explained it already.

Are you sure? :angry:

@silentworks, @akrabat: To sum up the discussion above, I've created a repository: https://github.com/schnittstabil/slim-issue-1829

tuupola commented 8 years ago

@schnittstabil Now that is a good example of understandable bug description.

So in one sentence: routing fails with builtin PHP webserver if script filename is something else than index.php.

silentworks commented 8 years ago

@schnittstabil your issue is very clear, not sure if this is the same issue @grikdotnet is having. If its the same this just means that there is no rewrite available/setup on these servers, you would have to route using the old method of including the file in the url. So from your example, you could get it working following your workarounds or by visiting http://0.0.0.0:8888/api.php/hello. This would work the same for nginx without the try_files $uri $uri/ /index.php$is_args$args; config change.

schnittstabil commented 8 years ago

not sure if this is the same issue @grikdotnet is having

@grikdotnet titled this issue …embedded PHP server and default nginx… and mentioned in his very first comment:

The default Nginx value of SCRIPT_NAME parameter sent to PHP-FPM is: fastcgi_param SCRIPT_NAME $fastcgi_script_name; … The default value of $fastcgi_script_name is a request URI.

That's very similar to PHPs built-in server.

this just means that there is no rewrite available on these servers

At least zend-expressive with fastroute is not affected by this, which is also based on the PSR-7 middleware idea, and also uses fastroute – greping a default setup tells me that expressive doesn't use SCRIPT_NAME at all… Thus, there must be a better way to determine the $basePath.

silentworks commented 8 years ago

@schnittstabil thank you so much for this, we will look into this now and try to come up with a solution.

geggleto commented 8 years ago

Since the problem ultimately lies in the PHP Webserver not setting it's own proper headers, you can get around this by doing it for the web server...

if (!isset($_SERVER['SCRIPT_NAME']) {
    $_SERVER['SCRIPT_NAME'] = '/api.php'; //or whatever entry point you are using.
}