超薄框架 - 无法解释带点的路线

时间:2014-06-20 22:45:07

标签: php apache .htaccess frameworks slim

问题陈述

我目前正在开发一个内部RESTful API,我正在使用我们的主域名作为环境标识符。但是,我注意到Slim根本不喜欢它的路径。

示例案例

我有一个使用PHP内置网络服务器运行的本地Web服务器,我调用php -S 0.0.0.0:5000来运行它。

一旦Web服务器启动,我在索引页面上有一个简单的“hello world”。一切都很好,花花公子。

然后我按照以下方式设置路线:

$app->get('/:domain/:id', function($domain, $id) 
{
    echo $domain . ' ' . $id;
} 

有了这个,我设置了希望解决0.0.0.0:5000/apple.com/juicers的路线。我尝试使用0.0.0.0:5000/apple/juicers,页面打印出苹果榨汁机。但是使用0.0.0.0:5000/apple.com/juicers,我收到 404 Not Found 错误。

到目前为止我尝试了什么

URL重写

我查看了Google上的可用资源,以及Slim框架的Github问题。似乎有人遇到了类似的问题:https://github.com/codeguy/Slim/issues/359

该票证中提议的解决方案是: URL重写修复。我尝试了但无济于事。我在项目目录的根目录下设置了.htaccess,并在Mac的httpd.conf文件中打开了AllowOverRide All

php -S 0.0.0.0:5000 index.php

我没有自己运行php -S 0.0.0.0:5000,而是在index.php上运行命令。此时,瘦框架不是抛出Not Found错误,而是解析为我的基本路由,我设置如下:

$app->get('/', function() { echo "hello world"; });

谢谢

我的智慧结束了,任何帮助都将受到高度赞赏。非常感谢您的阅读!

4 个答案:

答案 0 :(得分:14)

Slim依赖于$_SERVER['SCRIPT_NAME'],它应该是路由文件(Apache的DirectoryIndex,以及Rewrite指向的文件。假设index.php为下面的例子。)< / p>

在PHP嵌入式服务器中,如果URI在文件部分中包含一个点,则PHP无法正确定位SCRIPT_NAME值。

您可以使用以下调整来模仿RewriteRule行为:

创建一个router.php文件,并通过PHP嵌入式服务器发送所有请求:

$_SERVER['SCRIPT_NAME'] = 'index.php';
include 'index.php';

然后,使用以下命令启动PHP嵌入式服务器:

php -S 0.0.0.0:<port> -t <your-Http-document-root> router.php

router.php文件不会在您的生产环境中使用。只有PHP嵌入式服务器使用它,它应该解决你的“带点的路由”问题。

答案 1 :(得分:4)

根问题 - PHP开发服务器

在玩了不同的Slim条件和实验之后,我开始仔细研究服务器级别并确保URL正确传递到Slim路由。

原来这是PHP开发服务器的一个问题,可以通过php -S命令获得。

快速谷歌搜索显示其他几个人遇到了同样的问题,这是一个服务器问题,而不是Slim中的一个错误。

解决方案

为了测试我的解决方案,我运行了MAMP,并将我的所有文件都转移了。然后我写了.htaccess将所有请求重定向到index.php。

真相:

我输入了localhost:8888/campaigns/demo.com/12,当我在浏览器中看到一行美丽,华丽的demo.com/12时,一股欢乐的浪潮席卷了我的血脉! (我对该特定路线有一个echo声明)一周以上的故障排除和修修补补终于结出果实了!

庆祝Hoorah!

\(^ O ^)/ Hoorah for Apache!

感谢您的帮助@adosaiguas!

答案 2 :(得分:0)

我会尝试苗条的Route Conditions。您应该可以指定类似的内容以允许参数中的点:

$app->get('/:domain/:id', function($domain, $id) {
    echo $domain . ' ' . $id;
})->conditions(array('domain' => '[a-zA-Z\.]+'));

如果这不起作用,您应该考虑使用其他字符而不是点来将域名与TLD分开,然后在函数中替换它:

$app->get('/:domain/:id', function($domain, $id) {
    $domain = str_replace('_', '.', $domain);
    echo $domain . ' ' . $id;
})->conditions(array('domain' => '[a-zA-Z_]+'));

它不是那么优雅,但它有效。

答案 3 :(得分:0)

我刚刚将其添加到路由器脚本的顶部(在本例中为index.php):

if (PHP_SAPI === 'cli-server') {
  $_SERVER['SCRIPT_NAME'] = pathinfo(__FILE__, PATHINFO_BASENAME);
}

用法示例:

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