PHP built-in web server and relative paths

TL; DR

Does PHP 5.4 built-in web server have any bugs or restrictions regarding relative paths? Or should it be configured properly (and optional)?


When I was actively programming, I had a system working under URI routing using these lines in the .htaccess file :

RewriteEngine On

RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php [L]

      

FrontController received a request, find the correct route from the given URI in the SQLITE database and the dispatcher will call the action controller.

It worked great with Apache. Today, a few months later, I decided to run a test application with PHP 5.4 built-in web server.

The first thing I noticed is obviously .htaccess doesn't work, so I used the code file instead:

<?php

if( preg_match( '/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"] ) ) {
    return false;
}

include __DIR__ . '/index.php';

      

And started the web server like this:

php.exe -c "php.ini" -S "localhost:8080" "path\to\testfolder\routing.php"

      

So far so good. All I need to download can be accomplished by modifying the include_path like this:

set_include_path(

    '.' . PATH_SEPARATOR . realpath( '../common/next' )
);

      

Being next is the main folder of all modules inside a folder with everything that is common to all applications that I have. And no further explanation is required for this.

None of the AutoLoader methods I've ever seen have been able to self-load, so the only class that is manually required is my autoloader. But after running the test application, I got an error because my autoloader was not found. oo

I've always been very suspicious of realpath (), so I decided to change it with the full and absolute path in this next directory and it worked. It doesn't have to be done the way I do, but it worked.

My autoloader has been loaded and registered successfully with spl_autoload_register (). For reference, this is the autoload function (only closing of course):

function( $classname ) {

    $classname = stream_resolve_include_path(

        str_replace( '\\', DIRECTORY_SEPARATOR, $classname ) . '.php'
    );

    if( $classname !== FALSE ) {

        include $classname;
    }
};

      

However, resources located in the index.php path, like the MVC classes, cannot be found. So I did something else that I shouldn't do either, and added the working directory to the include_path. Again, manually, without relying on realpath ():

set_include_path(

    '.' . PATH_SEPARATOR . 'path/to/common/next'
        . PATH_SEPARATOR . 'path/to/htdocs/testfolder/'
);

      

And it worked again ... Almost !. > & L;

Most of the applications I can build with this system work fine with my standard SQLITE database router. And to simplify this route, this router looks for a predefined SQLITE file in the working directory.

Of course, I also provide a way to change this default entry just in case, and because of this, I check if this file exists and throws an error if it doesn't.

And this is the specific error that I see. The verification procedure looks like this:

if( ! file_exists( $this -> options -> dbPath ) ) {

    throw RouterException::connectionFailure(

       'Routes Database File %s doesn\'t exist in Data Directory',

       array( $this -> options -> dbPath )
    );
}

      

The dbPath entry , if unchanged , uses the constant Data / Routes.sqlite value , relative to the working directory.

If you manually set the absolute path again again, everything (really) works, the request flow has successfully reached the Action Controllers.

What's happening?

+3


source to share


1 answer


This bug is on PHP built-in web server which is still not fixed as of PHP 5.6.30.

In short, the webserver does not redirect to www.foo.com/bar/

if the request www.foo./bar

was requested and is a directory. The client being the server www.foo.com/bar

assumes it is a file (due to the lack of a trailing slash), so all subsequent relative references will be selected relative www.foo.com/

instead of www.foo.com/bar/

.

In 2013, a ticket was opened with an error , but the status was set to "Not error" by mistake.



I'm experiencing a similar issue in 2017, so I left a comment on the bit.

Edit: Just noticed that @ jens-a-koch opened the ticket I contacted. I was not familiar with his comment on the original question.

+1


source







All Articles