【发布时间】:2014-09-25 13:17:55
【问题描述】:
TL;DR
PHP 5.4 内置的网络服务器是否有关于相对路径的错误或限制?还是需要正确(以及额外)配置?
当我过去积极编程时,我有一个系统在 URI 路由下使用 .htaccess 文件中的这些行:
RewriteEngine On
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php [L]
FrontController 收到请求,从 SQLITE 数据库中的给定 URI 中找到正确的路由,然后 Dispatcher 调用 Action Controller。
它与 Apache 配合得非常好。几个月后的今天,我决定使用 PHP 5.4 内置网络服务器运行我的测试应用程序。
我注意到的第一件事,显然 .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' )
);
成为next文件夹内所有模块的core文件夹,其中包含我拥有的所有应用程序共有的所有内容。并且不需要为此做任何进一步的解释。
我所见过的AutoLoader技术都不能自己autoload,所以唯一需要手动的类就是我的Autoloader。但是在运行测试应用程序后,我收到一个错误,因为找不到我的 AutoLoader。 o.O
我一直对 realpath() 非常怀疑,所以我决定用这个 next 目录的完整和绝对路径来更改它,并且它起作用了。不需要像我那样做,但它确实有效。
我的自动加载器已被 spl_autoload_register() 加载并成功注册。作为参考,这是 autoloading 函数(当然只有闭包):
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/'
);
它再次起作用了……几乎! >.
我可以使用这个系统创建的大多数应用程序都可以很好地与基于 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。
如果我再次手动设置绝对路径,一切(真的)工作正常,请求流成功到达动作控制器。
发生了什么事?
【问题讨论】:
-
Yop.. 同样的问题...(使用 php 5.3x)...问题出在 PHP HTTP 服务器上...如果您仅使用 HTML 应用程序尝试此操作,您会得到同样的问题...
-
我注意到,如果我从这个相对路径定义所在的目录中运行负责启动内置网络服务器的批处理脚本,它有时会起作用。有时因为取决于应用程序(phpMyAdmin 不起作用)。但这是一个可怕的限制,因为我不能同时运行两个不同的应用程序 - 或者 - 两个网络服务器运行都应该监听两个不同的端口。更差!我会有几个批处理脚本,每个应用程序一个,如果没有这个错误,只有一个指向“。”就够了。
-
我不知道有任何配置指令可以更改此行为。我仍然认为 PHP 的内部网络服务器错过了内部重定向。我的错误报告立即被标记为不是错误:bugs.php.net/bug.php?id=66191
标签: webserver relative-path php-5.4