F3 路由引擎在 Linux 上使用 XAMPP 和 PhpStorm 工作,但为 CSS 文件提供 404

F3 routing engine works using XAMPP and PhpStorm on Linux, but gives 404 for CSS files

我正在尝试使用 PhpStorm 和 XAMPP 在 Linux 上编写 F3(“Fat Free Framework”)应用程序。

为了使用 RewriteEngine 所必需的 F3 提供的 .htaccess 文件(请参阅注释了解为什么这是错误的),我使用以下代码启动我的代码特殊 运行 配置:

我启动 运行 配置,这会启动 Web 服务器。我打开浏览器并转到 http://localhost:8000/ 。我可以看到内容和 link 的工作,我可以根据定义的路线从一个页面导航到另一个页面。

但是 CSS 的 none 在那里。如果我点击“view-source”并点击 CSS link,我会收到来自 F3 的 404 Not Found 消息。因此,似乎出于某种原因,F3 正在阻止 CSS 个文件。

网页开头如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>A title</title>
    <link href="{{@BASE}}/f3style.css" rel="stylesheet" type="text/css" />
</head>

尽管在我的例子中@BASE 变量是空的。 “f3style.css”文件当前确实位于我的 Web 目录的根目录中。

我使用F3推荐的默认.htaccess文件:

RewriteEngine On

# Uncommenting the following line has no effect
# RewriteBase /

RewriteRule ^(app|tmp)\/|\.ini$ - [R=404]

RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L,QSA]
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

(同样,请参阅关于为什么 .htaccess 文件与此处无关的评论)

这是我的路线。他们在“index.php”:

<?php

$f3 = require('lib/base.php');

// Routes
require 'controller.php';
$f3->route('GET /index.php', 'Controller->showMain');
$f3->route('GET /', 'Controller->showMain' );
$f3->route('GET /items/@item', 'Controller->showItem');

$f3->run();

知道我应该寻找什么吗?

根据您使用的屏幕截图PHP's built-in web server。问题是:它不支持 .htaccess。因此,所有 HTTP 请求都会转到您的路由器脚本(framework/index.php——我猜是 F3 应用程序的一部分)。

我不熟悉 F3 路由的工作原理,但我认为它与其他路由一样:它遍历所有已注册的 routes/endpoints,如果未找到匹配项,它将报告“404 Not Found " 响应。

由于 .htaccess 没有规则来过滤掉对此类 static/existing 文件(css/jpg/png/js 等)的请求,请求会通过您的 index.php,通过整个路由 table 并且 F3 将 404 错误报告回浏览器(当没有找到匹配的路由时)。

这里有几个可能的解决方案:

  1. 为此类静态资源创建一个单独的路由,并通过您的 F3 代码为它们提供服务(您的代码需要找到一个文件并使用正确的 headers 等发送响应.)

    不值得以这种方式实现它TBH(因为它只是为了处理这种特定情况/在PHP的网络服务器下)。

  2. 执行 pre-filter 并忽略对此类静态文件的任何请求。使用 PHP 的网络服务器时,只需在路由器脚本中返回 false(它告诉 PHP 使用 built-in 网络服务器代码来满足此类请求)。查看以下 link 中的示例并将类似的示例添加到您的代码中:https://www.php.net/manual/en/features.commandline.webserver.php#example-426

    if (preg_match('/\.(?:png|jpg|jpeg|gif|css)$/', $_SERVER["REQUEST_URI"])) return false;
    

    注意:您可以像以前一样将它添加到现有的 index.php 中(在顶部,在所有 use 行之后但在实际代码行之前)但这意味着您正在硬编码这样specific-to-PHP's-web-server-only 逻辑到脚本中,可以 运行 在适当的网络服务器下。
    Instead 我建议创建一个单独的路由器脚本(例如 php-router.php 并使用它而不是屏幕截图中的 index.php),你将在其中执行此操作,如果执行将通过该脚本条件,然后才从您的真实 index.php(即 require './index.php'; 或类似)

    中调用代码

为什么不首先使用 XAMPP 中的 Apache Web 服务器来为整个站点提供服务?

  • 一旦 Apache 运行ning 它处理所有虚拟主机(您可以通过 OS' hosts 文件中的假域名或通过在自定义专用端口)——无需单独启动每个站点。
  • Apache 显然完全支持 .htaccess 并且总是 better/more features/more 比 for-dev-only PHP 的 built-in web 更接近生产环境服务器(mod_rewrite 和其他模块)。