使用 PHP 内置 Web 服务器进行无脂路由

2024-04-08

我正在学习 fatfree 的路线,发现它的表现出乎意料。

这是我在index.php中的代码:

$f3 = require_once(dirname(dirname(__FILE__)). '/lib/base.php');
$f3 = \Base::instance();

echo 'received uri: '.$_SERVER['REQUEST_URI'].'<br>';

$f3->route('GET /brew/@count',
    function($f3,$params) {
        echo $params['count'].' bottles of beer on the wall.';
    }
);

$f3->run();

这是我访问的 URL:http://xx.xx.xx.xx:8090/brew/12 http://xx.xx.xx.xx:8090/brew/12

我收到 404 错误:

received uri: /brew/12
Not Found

HTTP 404 (GET /12)

奇怪的是,F3 中的 URI 现在是“/12”而不是“/brew/12”,我想这就是问题所在。

当我检查base.php(3.6.5)时,$this->hive['BASE'] =“/brew”和$this->hive['PATH'] =“/12”。 但如果F3只使用$this->hive['PATH']来匹配预定义的路由,则无法匹配它们。

如果我将路线更改为:

$f3->route('GET /brew',

并使用网址:http://xx.xx.xx.xx:8090/brew http://xx.xx.xx.xx:8090/brew,那么路线匹配就没有问题。 在本例中,$this->hive['BASE'] = "" 和 $this->hive['PATH'] = "/brew"。如果 F3 将 $this->hive['PATH'] 与预定义路由进行比较,则它们相互匹配。

顺便说一句,我正在使用 PHP 的内置 Web 服务器,并且由于 $_SERVER['REQUEST_URI'] (由 base.php 使用)返回正确的 URI,我认为我的 URL 重写没有任何问题。 .htrouter.php。

任何想法?我在这里错过了什么?

在这里添加.htrouter.php的内容

<?php

#get the relative URL
$uri = urldecode(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));

#if request to a real file (such as a html, image, js, css) then leave it as it is
if ($uri !== '/' && file_exists(__DIR__  . $uri)) {
    return false;
}

#if request virtual URL then pass it to the bootstrap file - index.php
$_GET['_url'] = $_SERVER['REQUEST_URI'];
require_once __DIR__ . './public/index.php';

您的问题与您使用 PHP 内置 Web 服务器的方式直接相关。

如中所述PHP docs http://php.net/manual/en/features.commandline.webserver.php,服务器处理请求的方式如下:

URI 请求将从启动 PHP 的当前工作目录提供服务,除非使用 -t 选项指定显式文档根目录。如果 URI 请求未指定文件,则返回给定目录中的 index.php 或 index.html。如果两个文件都不存在,则将在父目录中继续查找index.php和index.html,依此类推,直到找到一个文件或到达文档根目录。如果找到index.php或index.html,则将其返回,并将$_SERVER['PATH_INFO']设置为URI的尾随部分。否则返回 404 响应代码。

如果 Web 服务器启动时在命令行上给出 PHP 文件,则它将被视为“路由器”脚本。该脚本在每个 HTTP 请求开始时运行。如果此脚本返回 FALSE,则按原样返回所请求的资源。否则脚本的输出将返回到浏览器。

这意味着,默认情况下(没有路由器脚本),Web 服务器在将不存在的 URI 路由到文档根目录方面做得非常好index.php file.

换句话说,假设您的文件结构如下:

lib/
    base.php
    template.php
    etc.
public/
    index.php

以下命令足以启动服务器并将请求正确分派到框架:

php -S 0.0.0.0:8090 -t public/

或者,如果您直接从 public/ 文件夹运行命令:

cd public
php -S 0.0.0.0:8090

请注意,应用程序的工作目录取决于您调用命令的文件夹。为了利用这个价值,我强烈建议您添加chdir(__DIR__);在你的顶部public/index.php文件。这样,后续的所有require通话将与您相关public/文件夹。例如:$f3 = require('../lib/base.php');

路由文件样式 URI

内置服务器,默认情况下, 不会通过不存在的file指向您的 URIindex.php,如:

如果 URI 请求未指定文件,则返回给定目录中的 index.php 或 index.html

因此,如果您打算用点来定义一些路线,例如:

$f3->route('GET /brew.json','Brew->json');
$f3->route('GET /brew.html','Brew->html');

那么它就不会工作,因为 PHP 不会将请求传递给index.php.

在这种情况下,您需要调用自定义路由器,例如.htrouter.php你试图使用。唯一的事情是你的.htrouter.php显然是为不同的框架设计的(F3 不关心$_GET['url']但关心$_SERVER['SCRIPT_NAME'].

这是一个例子.htrouter.php应该与 F3 一起使用:

// public directory definition
$public_dir=__DIR__.'/public';

// serve existing files as-is
if (file_exists($public_dir.$_SERVER['REQUEST_URI']))
    return FALSE;

// patch SCRIPT_NAME and pass the request to index.php
$_SERVER['SCRIPT_NAME']='index.php';
require($public_dir.'/index.php');

NB: the $public_dir变量应根据位置设置.htrouter.php file.

例如,如果您致电:

php -S 0.0.0.0:8090 -t public/ .htrouter.php

它应该是$public_dir=__DIR__.'/public'.

但如果你打电话:

cd public
php -S 0.0.0.0:8090 .htrouter.php

它应该是$public_dir=__DIR__.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 PHP 内置 Web 服务器进行无脂路由 的相关文章

  • 检查@@rowcount函数来确定行是否存在可以吗?

    我正在浏览我们的代码库并看到很多这样的测试 declare row id int declare row attribute string select row attribute ROW ATTRIBUTE from SOME TABLE
  • isset() 和empty() - 使用什么

    你能帮助我改进我的编码风格吗 在某些任务中我需要检查 变量是否为空或包含某些内容 为了解决这个任务 我通常会执行以下操作 检查 该变量是否已设置 如果它已设置 我检查 它是否为空 我有一个问题 我应该在empty 之前使用isset 有必要
  • 错误:org.apache.hadoop.hbase.MasterNotRunningException:null+hbase+hadoop

    我最近用两台机器 在ubuntu上 配置了hadoop集群 到目前为止效果很好 但是当我尝试在上面的 hadoop 集群上配置 hbase 时 它 显示错误 这就是我所做的 我有两台机器 192 168 1 110 Hadoop主站 192
  • 无法翻译 LINQ 表达式

    我有一张桌子叫Orders和一个名为Customers Orders有财产CustomerId 现在我想获取我的客户的所有订单Customers list 这是我尝试过的 IEnumerable
  • 如何右对齐 JLabel 中的图标?

    对于带有图标的 JLabel 如果您setHorizontalTextPosition SwingConstants LEADING 无论标签有多宽 图标都会绘制在文本之后 这对于列表来说尤其糟糕 因为图标会到处都是 具体取决于每个项目的文
  • FireMonkey TListview 搜索重新加载问题

    当您进行搜索时 TListview 无法正确重新加载 请清除搜索 然后重新加载列表视图 使用XE5 步骤是 项目运行后 在搜索中输入文本 单击 清除 按钮或删除搜索文本或单击搜索 X 按钮清除搜索 按 重新加载 按钮 什么也没有出现 您可以
  • Webview 不加载 URL,但浏览器会加载

    因此 从我的第一个屏幕开始 我将 URL 传递给要在 Web 视图中启动的活动 但是当 webview 启动时 它显示 web page not available The web page at URL might be temporar
  • 需要 Microsoft Visual C++ 14.0,在 Windows Docker 上安装 pip 包

    我希望能够安装 C 编译器 因为某些软件包没有我需要的轮子 Windows 上大量的 Visual Studio 构建工具中所需的确切工具需要大量挖掘 并且安装需要很长时间 我见过一些导致此问题的错误 请随意将其他错误添加到此列表中 库 m
  • 嵌套形式和一对一关系

    我的用户和目标之间存在一对一的关系 我想构建一个显示用户目标的表单 问题是我的代码仅在用户已经定义了目标时才有效 当不存在目标时 不会呈现文本字段 Rails 是否提供了一种简单的方法来做到这一点 我就是这样做的 class User lt
  • 在 beforeAction 中渲染视图时,在 Yii 中出现“标题已发送”错误

    我读过 Yii2 的处理程序 但我不知道如何在这种情况下正确使用它们 基本上在我的SiteController 我有 class SiteController extends app components Controller public
  • 我们可以从 WPF 窗口将文件拖放到 Windows 资源管理器中吗?

    我有一个显示当前文件系统的树视图 我想添加功能以允许将文件拖放到 Windows 资源管理器中 如果我拖动树视图的任何节点并将其放在 Windows 资源管理器的任何窗口上 则文件将被复制到该位置 我怎样才能做到这一点 初读this htt
  • Typescript 中的 Getter/Setter

    我正在学习有关 Typescript 类的教程 教学人员创建了一个类和一些 setter getter 方法 但是当我读到时打字稿文档 https www typescriptlang org docs handbook classes h
  • 是否可以使用Dropbox、Google Drive、Skydrive等作为服务器空间?

    我正在创建一个在线连接到服务器以收集信息的应用程序 为了节省从大公司租用服务器空间的费用 我想知道这些免费服务 Dropbox Google Drive Microsoft Skydrive Amazon Cloud 等 是否可以用作服务器

随机推荐