PHP内置Web服务器和相对路径

时间:2014-08-02 13:15:55

标签: webserver relative-path php-5.4

TL; DR

PHP 5.4内置网络服务器是否有任何关于相对路径的错误或限制?或者是否需要正确(和另外)配置?


当我以前主动编程时,我在 .htaccess 文件中使用这些行在URI路由下工作:

RewriteEngine On

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

FrontController接收到Request,在SQLITE数据库中找到来自给定URI的正确路由,Dispatcher调用Action Controller。

它与Apache非常合作。今天,几个月后,我决定使用PHP 5.4内置的webserver运行我的测试应用程序。

我注意到的第一件事,显然, .htaccess 不起作用所以我使用了代码文件:

<?php

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

include __DIR__ . '/index.php';

并启动了这样的网络服务器:

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

到目前为止,这么好。我的应用程序需要引导的所有内容都可以通过修改 include_path 来完成:

set_include_path(

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

下一个文件夹中所有模块的核心文件夹,包含我拥有的所有应用程序的所有内容。并且它不需要为此目的做任何进一步的解释。

我见过的 AutoLoader 技术都没有能够自动加载,因此手动需要的唯一类是我的Autoloader。但运行测试应用程序后,我收到错误,因为找不到我的AutoLoader。 o.O

我一直对realpath()非常怀疑,所以我决定用这个 next 目录的完整和绝对路径来改变它,并且它有效。不应该像我一样做,但它确实有效。

我的自动加载器已加载并由spl_autoload_register()成功注册。作为参考,这是自动加载功能(当然只有Closure):

function( $classname ) {

    $classname = stream_resolve_include_path(

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

    if( $classname !== FALSE ) {

        include $classname;
    }
};

但是,无法找到位于 index.php 路径中的资源,如MVC类。所以我做了一些我也不应该做的事情,并将工作目录添加到 include_path 。再次,手动,而不依赖于realpath():

set_include_path(

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

它再次起作用......几乎! &GT;。&LT;

我可以使用此系统创建的大多数应用程序与基于SQLITE数据库的标准路由器配合得很好。为了使事情更容易,这个路由器在工作目录中查找预定义的SQLITE文件。

当然,我还提供了一种更改此默认条目的方法以防万一,因此我检查此文件是否存在,如果不存在则触发错误。

这是我看到的具体错误。检查程序是这样的:

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

    throw RouterException::connectionFailure(

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

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

dbPath 条目(如果未更改)使用相对于工作目录的常量值 Data / Routes.sqlite

如果再次,我再次手动设置绝对路径,一切(真的)工作,请求流成功到达动作控制器。

发生了什么事?

1 个答案:

答案 0 :(得分:1)

这是PHP内置Web服务器中的一个错误,自PHP版本5.6.30起,仍然没有修复。

简而言之,如果请求www.foo.com/bar/并且恰好是目录,则Web服务器不会重定向到www.foo./bar。作为服务器www.foo.com/bar的客户端假设它是一个文件(因为末尾缺少斜杠),因此所有后续相对链接将相对于www.foo.com/而不是www.foo.com/bar/获取。< / p>

A bug ticket was opened早在2013年就被错误地设置为“不是错误”。

我在2017年遇到类似的问题,所以我对错误罚单留下了评论。

编辑:注意到@ jens-a-koch打开了我链接的机票。我并不是对原始问题的评论。