-1

我知道在创建 php 网站时,我可以使用类似:index.php?id=2 并且 index.php 可以使用:$_GET['id'] 获取 id。我想为我的一个 websies 创建一个 api,我看到了不同的例子。

推特:

https://api.twitter.com/1.1/statuses/mentions_timeline.json?count=2&since_id=14927799

所以,我在我的 FTP 服务器上创建了一个文件夹“1.1”和一个文件夹“statuses”,其中包含可以理解 $_GET['count'] 等的文件提及时间线.json?

其他 API 如下所示:

https://quote.fm/api/recommendation/delete

我可以删除推荐:

https://quote.fm/api/recommendation/delete/?id=1 or
https://quote.fm/api/recommendation/delete/1

通常对于网站,我可以创建这样的 url 结构以使其使用 mod_rewrite 工作。据我了解,我为不同的部分创建了不同的网址:

https://xyz.com/api/user/get/1
https://xyz.com/api/user/delete/1

所以我创建了一个文件夹用户,子文件夹删除并进入 FTP 服务器,每个都有一个 index.php 文件?我的脚本如何知道 /1 是 id=1?

有人理解我吗?我很难理解我的脚本如何将 url 结构转换为来自应用程序的必要数据。

谢谢!

4

1 回答 1

3

我将在这里从我的路由器实现的自述文件中复制这一章:

什么是 URL 以及如何设置路由

URL 只是一个由几个部分组成的字符串:

http://example.com/foo?bar=baz
  |         |       |    |
  |         |       |    +- query
  |         |       +- path
  |         +- host
  +- scheme

URL 可能还具有身份验证信息、端口和片段,但我们将在此尽量保持简单。Kunststube\Router 专门处理路径。方案和查询通常对路由没有影响,主机通常由 Web 服务器处理。

假设使用 Apache Web 服务器进行典型设置,Apache 通常会为您执行“路由”。它接收到如下所示的 HTTP 请求:

GET /foo/bar/baz?some=parameters HTTP/1.1

Web 服务器现在可以自由地以它选择的任何方式响应此请求。大多数 Web 服务器所做的默认操作是将 URL 的路径映射到硬盘上的文件。Web 服务器将首先确定合适的DocumentRoot是什么,即磁盘上已配置为“公共 Web 文件夹”的文件夹。假设 DocumentRoot 是/var/www. 然后它将连接到该根的请求路径,从而产生/var/www/foo/bar/baz. 然后它将尝试确定该文件是否存在于磁盘上并将其作为响应提供。如果请求的文件以.php或 Apache 以其他方式配置为将该文件视为 PHP 文件,它将首先通过 PHP 解释器运行该文件,然后返回其输出。

要使用 PHP 路由器使用我们自己的自定义路由,我们需要拦截 Apache 查找文件以在磁盘上提供服务的过程。这可以在 Apache 配置文件中完成;但是如果您可以访问这些文件,我假设您知道自己在做什么,并且不会详细介绍那里的最佳设置。相反,我将介绍您不能或不想编辑核心 Apache 配置文件而是求助于.htaccess文件的典型情况。当 Apache 遍历磁盘上的目录结构以找到要服务的正确文件时,它会检查每个目录中是否.htaccess放置了一个调用的文件。如果找到,它将执行和/或将其中定义的规则合并到文件查找过程中,

您想要实现的是让 Apache “查找”并为任何和所有请求执行一个特定的 PHP 文件,并使原始 URL 可用于该 PHP 文件,以便它可以进行自己的路由。最简单,最肮脏的方法是简单的RewriteRule

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^(.*)$ index.php?url=/$1 [QSA,L] 
</IfModule>

假设您将其放入文件/var/www/.htaccess中。当 Apache 开始在该目录中查找文件时,它将解析这些重写规则。此时 Apache 正在寻找的路径的“内部状态”是foo/bar/baz. 的正则表达式^(.*)$RewriteRule匹配该路径(表达式基本上说“匹配任何东西”),并且该规则将路径重写为 index.php?url=/foo/bar/baz. 然后将原始some=parameters文件再次附加到该路径/URL(由于QSA标志)。然后 Apache 将继续寻找现在重写的路径index.php。因此,只需将您的代码放入/var/www/index.php其中,Apache 就会为其启动 PHP 解释器。PHP 将传递 URL 查询部分 ?url=/foo/bar/baz&some=parameters,在 PHP 中可以访问为 $_GET['url']$_GET['some']. 所以完整的设置如下所示:

基本设置

文件/文件夹结构
/var
    /www
        .htaccess
        index.php
        /Kunststube
            /Router
                Router.php
                ...
.htaccess
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^(.*)$ index.php?url=/$1 [QSA,L] 
</IfModule>
索引.php
<?php

require_once 'Kunststube/Router/Router.php';

$r = new Kunststube\Router\Router;
$r->add('/foo');
...
$r->route($_GET['url']);

这就是它的全部。一个基本的重写规则,将每个请求重定向到同一个 PHP 文件,并将原始 URL 作为查询参数附加,然后用于调用路由过程。

警告和调整

对上述设置的一个重要警告是,您的 URL 不能包含名为 的查询参数url,因为原始查询参数被添加回重写的 URL。URL /foo/bar?url=baz将被重写为:

index.php?url=/foo/bar&url=baz

第二个url参数将替换第一个参数。如果您需要url在应用程序中使用查询参数,请为您的重写规则选择不同的参数名称。

其次,请注意 Kunststube\Router 期望传递给的 URL route()/. 您可以在重写过程中添加斜线,如上所示,或者在 PHP 中;只要确保它在那里。

第三,您通常也有不想通过 PHP 路由的文件,例如 CSS 和图像文件。您将希望这些由 Apache 直接提供服务。一个很好的设置是这样的:

/var
    /Kunststube
        /Router
            ...
    /MyApp
        MyScript.php
        ...
    /www
        .htaccess
        index.php
        /css
            style.css
            ...
        /img
            kitten.jpg
            ...

将所有实际的 PHP 文件从公共 Web 根目录中取出,只留下公共资产文件和一个最小index.php文件。调整你的 RewriteRule 看起来像这样:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?url=/$1 [QSA,L] 
</IfModule>

RewriteCond确保RewriteRule仅当请求的文件实际上不存在时才适用 ( ) !-f。这意味着对 URL 的请求css/style.css将按原样通过,因为该文件确实存在并且 Apache 可以直接提供它。对物理上不存在的“虚构”文件的任何请求都将进入 index.php并可以路由到那里。在里面index.php,确保使用正确的路由器路径:

require_once '../Kunststube/Router/Router.php';

事实上,更好的做法是在其他地方完全定义您的路线并使用自动加载器来加载所需的文件,但这超出了本文档的范围。

于 2013-03-27T09:29:01.300 回答