apache - Slim(PHP)RESTful API的Apache重写规则

标签 apache .htaccess rest mod-rewrite slim

我在配置RESTful API(使用Slim PHP和Eloquent ORM)以正确重写URL时遇到一些麻烦。

我的项目目录结构如下:

wwwroot/
    myproject/
        api/ (maintained in its own Git repo)
            app/
                data/
                lib/
                models/
                routes/
                app.php (where Slim is instantiated and used)
                config.php (holds database settings, etc.)
            public/
                .htaccess (#1)
                index.php (includes ../app/app.php)
            vendor/
            .htaccess (#2, this be empty yo)
        ngapp/ (future Angular.js app)
        webapp/ (future standard web app)


.htaccess(#1)包含标准规则:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]


这样可以通过http://localhost/myproject/api/public/<insertAnySlimRouteHere>访问该API。但是,我想通过如下URL到达API:http://localhost/myproject/api/<insertAnySlimRouteHere>。我该怎么做呢?

(也可以对我的总体项目结构发表评论。自从我受聘为.NET / JS开发人员以来,我正在尝试使用如今很少使用的语言来开发RESTful API,我使用了两个框架从来没有涉猎过它,并使它(API)适用于Web和移动设备上的多个客户端。有时间,学习很有趣。)

更新资料

我遵循smcjones的建议,并将以下内容添加到我的httpd-vhosts.conf中:

<VirtualHost *:80>
    Alias "/lampjavel/api" "C:/Users/Viktor/Dev/htdocs/lampjavel-api/public"
    <Directory "C:/Users/Viktor/Dev/htdocs/lampjavel-api">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride all
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>


我还删除了.htaccess#2和.htaccess#1(在public/中)如下所示:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]


但是,Slim路线的第一部分被扔掉了。当我在浏览器中访问.../api时,会得到/路由,这是正确的。但是当我请求.../api/images时,我仍然得到/路线。如果我深入研究.../api/images/images,我会得到所需的路线/images

在我的app.php中:

$app->get('/', function () use ($app) {
    echo '/';
});

$app->get('/images', function () use ($app) {
    echo '/images';
});


知道为什么路线的第一部分会被忽略吗?

最佳答案

您希望以陈述的形式完成的操作将是笨拙且不安全的。

笨拙,因为您试图从父级调用子级文件夹。这可能会导致一些无法预料的问题。例如:


您需要禁止使用mod_rewrite调用项目结构中的文件夹。否则,您的服务器将尝试为您提供Slim路由,而不是app。虽然您可以添加RewriteCond %{REQUEST_FILENAME} !-d,但这会遗漏要点,因为这样,您的app路线就无法在Slim上使用。
因此,您也永远无法拥有名为app的Slim路由。尽管您很可能无意使用名为app的Slim路由,但最好为您的应用程序提供灵活性。
类似地,如果您确定需要另一个文件夹(例如,用于单元测试的docstest),则可能需要将其埋在另一个文件夹中,例如apppublic(至少在我看来,它们似乎不合适),否则您将需要更改mod_rewrite。您还需要再次寻找命名冲突。从这个意义上讲,除非您100%确定不会修改结构,否则您将给自己增加更多不必要的痛苦。


不安全,因为您的Web路径当前设置为显示目录结构的很大一部分。尽管在我看来这就像是开发服务器,但这可能无关紧要,但我认为,最好先在开发服务器上按顺序获取路径。

当前,如果导航到http://localhost/myproject/api/app/data,它会抛出404吗?有人能够猜出您的结构吗?是否有您不希望某人在您的根目录之外找到的页面?虽然PHP将不会显示任何这些文件,但有人可以通过调用文件轻松地使系统过载。另外,如果文件在单独调用时抛出错误,则可能是您放弃了有关路径的更多信息。

再一次,我意识到您可能只是在进行测试,但是如果它正在某个时候进入实际环境,那么您将需要解决这些问题。在我开始尝试使开发服务器尽可能模拟我的实时服务器后,我的痛苦减轻了很多。

我的建议解决方案

.htaccess确实不是进行此类操作的理想场所。相反,您应该查看Apache的配置文件。正如@guillermoandrae所说,听起来您真正想要做的是使用不同的DocumentRoot

如果可以访问Apache的配置,则可以创建直接指向VirtualHost目录的public

例:

<VirtualHost *:80>
    Alias "/api" /wwwroot/myproject/api/public
    <Directory "/api">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride all
        Order allow,deny
        Allow from all
        <IfModule mod_rewrite.c>
            RewriteEngine on
            #Rewrite Rules from .htaccess here
        </IfModule>
    </Directory>
</VirtualHost>


您可以在此处添加更多Directory标记,并使用别名为需要访问的文件夹创建一个安全的应用程序。

关于项目结构的(长篇)注释

我已经提到过,您的项目结构可能必须在某个时候进行更改。总的来说,我会说您的项目结构看起来不错。 PHP是一种过于宽容的语言,可能会很糟糕,但是具有您的背景知识意味着您会做的很好。但是,我建议您将api文件夹拆分为自己的项目。我之所以建议这样做,是因为它目前与您的一种应用紧密结合。您提到要使其与多个应用程序一起使用。好吧,API的魅力在于只要您可以访问URI,它就可以正常工作。只要您创建RESTful API(甚至是基于JSon的API),任何语言都可以解析您的API,无论它在哪里。

当前,如果您创建一个新项目,例如mysecondproject,则将有两个相同的URL:

http://localhost/myproject/api/public/foohttp://localhost/mysecondproject/api/public/foo都将放在同一位置。除非您没有在一处更新项目,否则将发现不一致之处。

最终,我会怀疑除非您希望拥有镜像,否则您可能希望您的API存在于Internet上的一个位置。这样,您就可以更好地控制所有内容。

编辑

根据下面的问题,由于您的mod_rewrite代码,目录已被重新路由。在不知道您现在正在使用什么进行重写的情况下,我建议您添加这一行并查看其工作方式(在...%{REQUEST_FILENAME} !-f之后)

RewriteCond %{REQUEST_FILENAME} !-d


编辑#2

您的htaccess代码当前正在将主目录以外的目录或文件以外的所有内容推送到Slim。因此,错误的机会很大,这是因为您的Slim路由而不是您的Apache访问权限。您是否有一条看起来像这样的路线?

$app->get('/images/:route', function ($route) {

    //execute code
};


如果不这样做,则尝试找出正在实施的路由。如果难以找到,则可以使用Slim的某些内置日志记录功能。

关于apache - Slim(PHP)RESTful API的Apache重写规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28084322/

相关文章:

api - 基于身份验证的 REST API 响应,最佳实践?

python - 如何使用 Django 活塞以文本/纯文本形式返回响应?

php - Apache2 在 Linux Mint 17 KDE 中失败

apache - 浏览器以 UTF-8 而不是 windows-1251 显示页面

.htaccess - 使用 "index.php"时,将 "YII"隐藏在 "https"中的 url 不起作用

php - 301重定向错误动态和静态index.php?

wordpress - Wordpress 4.0 options.php中的403错误

java - 使用 spring boot 和 mongodb 检索具有完整和不完整配置文件的用户数量的最佳方法是什么?

apache - RewriteRules 的执行顺序问题

apache - 为什么apache虚拟服务器没有运行